2 * ion/ioncore/group-ws.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * See the included file LICENSE for details.
11 #include <libtu/minmax.h>
12 #include <libtu/objp.h>
24 #include "grouppholder.h"
25 #include "groupedpholder.h"
26 #include "framedpholder.h"
27 #include "float-placement.h"
35 void ioncore_groupws_set(ExtlTab tab)
40 if(extl_table_gets_s(tab, "float_placement_method", &method)){
41 if(strcmp(method, "udlr")==0)
42 ioncore_placement_method=PLACEMENT_UDLR;
43 else if(strcmp(method, "lrud")==0)
44 ioncore_placement_method=PLACEMENT_LRUD;
45 else if(strcmp(method, "random")==0)
46 ioncore_placement_method=PLACEMENT_RANDOM;
48 warn(TR("Unknown placement method \"%s\"."), method);
54 void ioncore_groupws_get(ExtlTab t)
56 extl_table_sets_s(t, "float_placement_method",
57 (ioncore_placement_method==PLACEMENT_UDLR
59 : (ioncore_placement_method==PLACEMENT_LRUD
71 static bool groupws_attach_framed(WGroupWS *ws,
72 WGroupAttachParams *ap,
76 WRegionAttachData data;
78 data.type=REGION_ATTACH_REPARENT;
81 return (region_attach_framed((WRegion*)ws, fp,
82 (WRegionAttachFn*)group_do_attach,
87 bool groupws_handle_drop(WGroupWS *ws, int x, int y,
90 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
91 WFramedParam fp=FRAMEDPARAM_INIT;
96 fp.inner_geom_gravity_set=TRUE;
99 fp.inner_geom.w=REGION_GEOM(dropped).w;
100 fp.inner_geom.h=REGION_GEOM(dropped).h;
101 fp.gravity=NorthWestGravity;
103 return groupws_attach_framed(ws, &ap, &fp, dropped);
108 * Attach region \var{reg} on \var{ws}.
109 * At least the following fields in \var{t} are supported:
111 * \begin{tabularx}{\linewidth}{lX}
112 * \tabhead{Field & Description}
113 * \var{switchto} & Should the region be switched to (boolean)? Optional. \\
114 * \var{geom} & Geometry; \var{x} and \var{y}, if set, indicates top-left of
115 * the frame to be created while \var{width} and \var{height}, if set, indicate
116 * the size of the client window within that frame. Optional.
119 EXTL_EXPORT_AS(WGroupWS, attach_framed)
120 bool groupws_attach_framed_extl(WGroupWS *ws, WRegion *reg, ExtlTab t)
122 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
123 WFramedParam frp=FRAMEDPARAM_INIT;
128 group_get_attach_params(&ws->grp, t, &ap);
130 /* Sensible size is given in framedparams */
136 frp.inner_geom_gravity_set=1;
137 frp.inner_geom=ap.geom;
138 frp.gravity=NorthWestGravity;
139 extl_table_gets_i(t, "gravity", &frp.gravity);
142 return groupws_attach_framed(ws, &ap, &frp, reg);
149 /*{{{ groupws_prepare_manage */
152 static WPHolder *groupws_do_prepare_manage(WGroupWS *ws,
153 const WClientWin *cwin,
154 const WManageParams *param,
157 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
158 WFramedParam fp=FRAMEDPARAM_INIT;
162 fp.inner_geom_gravity_set=TRUE;
163 fp.inner_geom=param->geom;
164 fp.gravity=param->gravity;
167 ap.geom_weak=geom_weak;
169 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
172 ph=pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
175 ph=pholder_either((WPHolder*)create_groupedpholder((WPHolder*)ph), ph);
181 WPHolder *groupws_prepare_manage(WGroupWS *ws, const WClientWin *cwin,
182 const WManageParams *param,
185 int cpriority=MANAGE_PRIORITY_SUB(priority, MANAGE_PRIORITY_GROUP);
186 int bpriority=MANAGE_PRIORITY_SUBX(priority, MANAGE_PRIORITY_GROUP);
187 WRegion *b=(ws->grp.bottom!=NULL ? ws->grp.bottom->reg : NULL);
189 bool act_b=(ws->grp.bottom==ws->grp.current_managed);
193 if(param->maprq && ioncore_g.opmode!=IONCORE_OPMODE_INIT
195 /* When the window is mapped by application request, position
196 * request is only honoured if the position was given by the user
197 * and in case of a transient (the app may know better where to
198 * place them) or if we're initialising.
200 weak=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
203 if(b!=NULL && !HAS_DYN(b, region_prepare_manage))
207 ? !extl_table_is_bool_set(cwin->proptab, "float")
210 if(b!=NULL && use_bottom)
211 ph=region_prepare_manage(b, cwin, param, bpriority);
215 WRegion *r=(ws->grp.current_managed!=NULL
216 ? ws->grp.current_managed->reg
220 ph=region_prepare_manage(r, cwin, param, cpriority);
223 if(ph==NULL && MANAGE_PRIORITY_OK(priority, MANAGE_PRIORITY_GROUP))
224 ph=groupws_do_prepare_manage(ws, cwin, param, weak);
226 if(ph==NULL && b!=NULL && !use_bottom)
227 ph=region_prepare_manage(b, cwin, param, cpriority);
233 WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin,
234 const WManageParams *param,
237 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
238 WFramedParam fp=FRAMEDPARAM_INIT;
241 ap.stack_above=OBJ_CAST(REGION_PARENT(param->tfor), WRegion);
242 if(ap.stack_above==NULL)
245 fp.inner_geom_gravity_set=TRUE;
246 fp.inner_geom=param->geom;
247 fp.gravity=param->gravity;
248 fp.mode=FRAME_MODE_TRANSIENT;
253 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
255 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
259 WPHolder *groupws_get_rescue_pholder_for(WGroupWS *ws,
262 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
263 WFramedParam fp=FRAMEDPARAM_INIT;
267 ap.geom=REGION_GEOM(forwhat);
270 ap.geom_weak=(REGION_PARENT(forwhat)!=REGION_PARENT(ws)
271 ? REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y
274 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
276 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
280 static bool group_empty_for_bottom_stdisp(WGroup *ws)
285 FOR_ALL_NODES_IN_GROUP(ws, st, tmp){
286 if(st!=ws->bottom && st!=ws->managed_stdisp)
294 static WRegion *groupws_managed_disposeroot(WGroupWS *ws, WRegion *reg)
296 if(group_bottom(&ws->grp)==reg){
297 if(group_empty_for_bottom_stdisp(&ws->grp)){
298 WRegion *tmpr=region_disposeroot((WRegion*)ws);
299 return (tmpr!=NULL ? tmpr : reg);
310 /*{{{ WGroupWS class */
313 bool groupws_init(WGroupWS *ws, WWindow *parent, const WFitParams *fp)
315 if(!group_init(&(ws->grp), parent, fp))
318 ((WRegion*)ws)->flags|=REGION_GRAB_ON_PARENT;
320 region_add_bindmap((WRegion*)ws, ioncore_groupws_bindmap);
326 WGroupWS *create_groupws(WWindow *parent, const WFitParams *fp)
328 CREATEOBJ_IMPL(WGroupWS, groupws, (p, parent, fp));
332 void groupws_deinit(WGroupWS *ws)
334 group_deinit(&(ws->grp));
338 WRegion *groupws_load(WWindow *par, const WFitParams *fp,
343 ws=create_groupws(par, fp);
348 group_do_load(&ws->grp, tab);
354 static DynFunTab groupws_dynfuntab[]={
355 {(DynFun*)region_prepare_manage,
356 (DynFun*)groupws_prepare_manage},
358 {(DynFun*)region_prepare_manage_transient,
359 (DynFun*)groupws_prepare_manage_transient},
361 {(DynFun*)region_managed_disposeroot,
362 (DynFun*)groupws_managed_disposeroot},
364 {(DynFun*)region_handle_drop,
365 (DynFun*)groupws_handle_drop},
367 {(DynFun*)region_get_rescue_pholder_for,
368 (DynFun*)groupws_get_rescue_pholder_for},
370 {region_manage_stdisp,
371 group_manage_stdisp},
378 IMPLCLASS(WGroupWS, WGroup, groupws_deinit, groupws_dynfuntab);