2 * ion/ioncore/group-ws.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
14 #include <libtu/minmax.h>
15 #include <libtu/objp.h>
27 #include "grouppholder.h"
28 #include "groupedpholder.h"
29 #include "framedpholder.h"
30 #include "float-placement.h"
38 void ioncore_groupws_set(ExtlTab tab)
43 if(extl_table_gets_s(tab, "float_placement_method", &method)){
44 if(strcmp(method, "udlr")==0)
45 ioncore_placement_method=PLACEMENT_UDLR;
46 else if(strcmp(method, "lrud")==0)
47 ioncore_placement_method=PLACEMENT_LRUD;
48 else if(strcmp(method, "random")==0)
49 ioncore_placement_method=PLACEMENT_RANDOM;
51 warn(TR("Unknown placement method \"%s\"."), method);
57 void ioncore_groupws_get(ExtlTab t)
59 extl_table_sets_s(t, "float_placement_method",
60 (ioncore_placement_method==PLACEMENT_UDLR
62 : (ioncore_placement_method==PLACEMENT_LRUD
74 static bool groupws_attach_framed(WGroupWS *ws,
75 WGroupAttachParams *ap,
79 WRegionAttachData data;
81 data.type=REGION_ATTACH_REPARENT;
84 return (region_attach_framed((WRegion*)ws, fp,
85 (WRegionAttachFn*)group_do_attach,
90 bool groupws_handle_drop(WGroupWS *ws, int x, int y,
93 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
94 WFramedParam fp=FRAMEDPARAM_INIT;
99 fp.inner_geom_gravity_set=TRUE;
102 fp.inner_geom.w=REGION_GEOM(dropped).w;
103 fp.inner_geom.h=REGION_GEOM(dropped).h;
104 fp.gravity=NorthWestGravity;
106 return groupws_attach_framed(ws, &ap, &fp, dropped);
111 * Attach region \var{reg} on \var{ws}.
112 * At least the following fields in \var{t} are supported:
114 * \begin{tabularx}{\linewidth}{lX}
115 * \tabhead{Field & Description}
116 * \var{switchto} & Should the region be switched to (boolean)? Optional. \\
117 * \var{geom} & Geometry; \var{x} and \var{y}, if set, indicates top-left of
118 * the frame to be created while \var{width} and \var{height}, if set, indicate
119 * the size of the client window within that frame. Optional.
122 EXTL_EXPORT_AS(WGroupWS, attach_framed)
123 bool groupws_attach_framed_extl(WGroupWS *ws, WRegion *reg, ExtlTab t)
125 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
126 WFramedParam fp=FRAMEDPARAM_INIT;
132 fp.gravity=ForgetGravity;
134 if(extl_table_is_bool_set(t, "switchto")){
135 ap.switchto_set=TRUE;
139 if(extl_table_gets_t(t, "geom", >)){
145 if(extl_table_gets_i(gt, "x", &(ap.geom.x)))
147 if(extl_table_gets_i(gt, "y", &(ap.geom.y)))
150 if(extl_table_gets_i(gt, "w", &(ap.geom.w)))
152 if(extl_table_gets_i(gt, "h", &(ap.geom.h)))
155 fp.inner_geom.w=maxof(fp.inner_geom.w, 1);
156 fp.inner_geom.h=maxof(fp.inner_geom.h, 1);
158 fp.inner_geom_gravity_set=(size==2 && pos==2);
160 extl_unref_table(gt);
163 return groupws_attach_framed(ws, &ap, &fp, reg);
170 /*{{{ groupws_prepare_manage */
173 static WPHolder *groupws_do_prepare_manage(WGroupWS *ws,
174 const WClientWin *cwin,
175 const WManageParams *param,
176 int redir, int geom_weak)
178 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
179 WFramedParam fp=FRAMEDPARAM_INIT;
182 if(redir==MANAGE_REDIR_PREFER_YES){
183 WRegion *r=(ws->grp.current_managed!=NULL
184 ? ws->grp.current_managed->reg
190 ph=region_prepare_manage(r, cwin, param, MANAGE_REDIR_PREFER_YES);
193 FOR_ALL_MANAGED_BY_GROUP(&ws->grp, r, tmp){
194 ph=region_prepare_manage(r, cwin, param,
195 MANAGE_REDIR_PREFER_YES);
202 if(redir==MANAGE_REDIR_STRICT_YES)
205 fp.inner_geom_gravity_set=TRUE;
206 fp.inner_geom=param->geom;
207 fp.gravity=param->gravity;
210 ap.geom_weak=geom_weak;
212 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
215 ph=pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
218 ph=pholder_either((WPHolder*)create_groupedpholder((WPHolder*)ph), ph);
224 WPHolder *groupws_prepare_manage(WGroupWS *ws, const WClientWin *cwin,
225 const WManageParams *param,
228 WRegion *b=(ws->grp.bottom!=NULL ? ws->grp.bottom->reg : NULL);
230 bool act_b=(ws->grp.bottom==ws->grp.current_managed);
234 if(param->maprq && ioncore_g.opmode!=IONCORE_OPMODE_INIT
236 /* When the window is mapped by application request, position
237 * request is only honoured if the position was given by the user
238 * and in case of a transient (the app may know better where to
239 * place them) or if we're initialising.
241 weak=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
244 if(b!=NULL && !HAS_DYN(b, region_prepare_manage))
248 ? !extl_table_is_bool_set(cwin->proptab, "float")
251 if(b!=NULL && use_bottom)
252 ph=region_prepare_manage(b, cwin, param, redir);
255 ph=groupws_do_prepare_manage(ws, cwin, param, redir, weak);
257 if(ph==NULL && b!=NULL && !use_bottom)
258 ph=region_prepare_manage(b, cwin, param, redir);
264 WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin,
265 const WManageParams *param,
268 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
269 WFramedParam fp=FRAMEDPARAM_INIT;
272 ap.stack_above=OBJ_CAST(REGION_PARENT(param->tfor), WRegion);
273 if(ap.stack_above==NULL)
276 fp.inner_geom_gravity_set=TRUE;
277 fp.inner_geom=param->geom;
278 fp.gravity=param->gravity;
279 fp.mode=FRAME_MODE_TRANSIENT;
284 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
286 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
290 WPHolder *groupws_get_rescue_pholder_for(WGroupWS *ws,
293 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
294 WFramedParam fp=FRAMEDPARAM_INIT;
298 ap.geom=REGION_GEOM(forwhat);
301 ap.geom_weak=(REGION_PARENT(forwhat)!=REGION_PARENT(ws)
302 ? REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y
305 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
307 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
314 /*{{{ WGroupWS class */
317 bool groupws_init(WGroupWS *ws, WWindow *parent, const WFitParams *fp)
319 if(!group_init(&(ws->grp), parent, fp))
322 ((WRegion*)ws)->flags|=REGION_GRAB_ON_PARENT;
324 region_add_bindmap((WRegion*)ws, ioncore_groupws_bindmap);
330 WGroupWS *create_groupws(WWindow *parent, const WFitParams *fp)
332 CREATEOBJ_IMPL(WGroupWS, groupws, (p, parent, fp));
336 void groupws_deinit(WGroupWS *ws)
338 group_deinit(&(ws->grp));
342 WRegion *groupws_load(WWindow *par, const WFitParams *fp,
347 ws=create_groupws(par, fp);
352 group_do_load(&ws->grp, tab);
358 static DynFunTab groupws_dynfuntab[]={
359 {(DynFun*)region_prepare_manage,
360 (DynFun*)groupws_prepare_manage},
362 {(DynFun*)region_prepare_manage_transient,
363 (DynFun*)groupws_prepare_manage_transient},
365 {(DynFun*)region_handle_drop,
366 (DynFun*)groupws_handle_drop},
368 {(DynFun*)region_get_rescue_pholder_for,
369 (DynFun*)groupws_get_rescue_pholder_for},
371 {region_manage_stdisp,
372 group_manage_stdisp},
379 IMPLCLASS(WGroupWS, WGroup, groupws_deinit, groupws_dynfuntab);