2 * ion/ioncore/group-ws.c
4 * Copyright (c) Tuomo Valkonen 1999-2008.
6 * See the included file LICENSE for details.
11 #include <libtu/minmax.h>
12 #include <libtu/objp.h>
24 #include "grouppholder.h"
25 #include "framedpholder.h"
26 #include "float-placement.h"
34 void ioncore_groupws_set(ExtlTab tab)
39 if(extl_table_gets_s(tab, "float_placement_method", &method)){
40 if(strcmp(method, "udlr")==0)
41 ioncore_placement_method=PLACEMENT_UDLR;
42 else if(strcmp(method, "lrud")==0)
43 ioncore_placement_method=PLACEMENT_LRUD;
44 else if(strcmp(method, "random")==0)
45 ioncore_placement_method=PLACEMENT_RANDOM;
47 warn(TR("Unknown placement method \"%s\"."), method);
53 void ioncore_groupws_get(ExtlTab t)
55 extl_table_sets_s(t, "float_placement_method",
56 (ioncore_placement_method==PLACEMENT_UDLR
58 : (ioncore_placement_method==PLACEMENT_LRUD
70 static bool groupws_attach_framed(WGroupWS *ws,
71 WGroupAttachParams *ap,
75 WRegionAttachData data;
77 data.type=REGION_ATTACH_REPARENT;
80 return (region_attach_framed((WRegion*)ws, fp,
81 (WRegionAttachFn*)group_do_attach,
86 bool groupws_handle_drop(WGroupWS *ws, int x, int y,
89 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
90 WFramedParam fp=FRAMEDPARAM_INIT;
95 fp.inner_geom_gravity_set=TRUE;
98 fp.inner_geom.w=REGION_GEOM(dropped).w;
99 fp.inner_geom.h=REGION_GEOM(dropped).h;
100 fp.gravity=NorthWestGravity;
102 return groupws_attach_framed(ws, &ap, &fp, dropped);
107 * Attach region \var{reg} on \var{ws}.
108 * At least the following fields in \var{t} are supported:
110 * \begin{tabularx}{\linewidth}{lX}
111 * \tabhead{Field & Description}
112 * \var{switchto} & Should the region be switched to (boolean)? Optional. \\
113 * \var{geom} & Geometry; \var{x} and \var{y}, if set, indicates top-left of
114 * the frame to be created while \var{width} and \var{height}, if set, indicate
115 * the size of the client window within that frame. Optional.
118 EXTL_EXPORT_AS(WGroupWS, attach_framed)
119 bool groupws_attach_framed_extl(WGroupWS *ws, WRegion *reg, ExtlTab t)
121 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
122 WFramedParam frp=FRAMEDPARAM_INIT;
127 group_get_attach_params(&ws->grp, t, &ap);
129 /* Sensible size is given in framedparams */
135 frp.inner_geom_gravity_set=1;
136 frp.inner_geom=ap.geom;
137 frp.gravity=NorthWestGravity;
138 extl_table_gets_i(t, "gravity", &frp.gravity);
141 return groupws_attach_framed(ws, &ap, &frp, reg);
148 /*{{{ groupws_prepare_manage */
151 static WPHolder *groupws_do_prepare_manage(WGroupWS *ws,
152 const WClientWin *cwin,
153 const WManageParams *param,
156 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
157 WFramedParam fp=FRAMEDPARAM_INIT;
161 fp.inner_geom_gravity_set=TRUE;
162 fp.inner_geom=param->geom;
163 fp.gravity=param->gravity;
166 ap.geom_weak=geom_weak;
168 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
171 ph=pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
175 WGroupAttachParams gp=GROUPATTACHPARAMS_INIT;
181 gph=create_grouppholder(NULL, NULL, &gp);
184 gph->recreate_pholder=ph;
185 return (WPHolder*)gph;
193 WPHolder *groupws_prepare_manage(WGroupWS *ws, const WClientWin *cwin,
194 const WManageParams *param,
197 int cpriority=MANAGE_PRIORITY_SUB(priority, MANAGE_PRIORITY_GROUP);
198 int bpriority=MANAGE_PRIORITY_SUBX(priority, MANAGE_PRIORITY_GROUP);
199 WRegion *b=(ws->grp.bottom!=NULL ? ws->grp.bottom->reg : NULL);
201 bool act_b=(ws->grp.bottom==ws->grp.current_managed);
205 if(param->maprq && ioncore_g.opmode!=IONCORE_OPMODE_INIT
207 /* When the window is mapped by application request, position
208 * request is only honoured if the position was given by the user
209 * and in case of a transient (the app may know better where to
210 * place them) or if we're initialising.
212 weak=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
215 if(b!=NULL && !HAS_DYN(b, region_prepare_manage))
219 ? !extl_table_is_bool_set(cwin->proptab, "float")
222 if(b!=NULL && use_bottom)
223 ph=region_prepare_manage(b, cwin, param, bpriority);
227 WRegion *r=(ws->grp.current_managed!=NULL
228 ? ws->grp.current_managed->reg
232 ph=region_prepare_manage(r, cwin, param, cpriority);
235 if(ph==NULL && MANAGE_PRIORITY_OK(priority, MANAGE_PRIORITY_GROUP))
236 ph=groupws_do_prepare_manage(ws, cwin, param, weak);
238 if(ph==NULL && b!=NULL && !use_bottom)
239 ph=region_prepare_manage(b, cwin, param, cpriority);
245 WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin,
246 const WManageParams *param,
249 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
250 WFramedParam fp=FRAMEDPARAM_INIT;
253 ap.stack_above=OBJ_CAST(REGION_PARENT(param->tfor), WRegion);
254 if(ap.stack_above==NULL)
257 fp.inner_geom_gravity_set=TRUE;
258 fp.inner_geom=param->geom;
259 fp.gravity=param->gravity;
260 fp.mode=FRAME_MODE_TRANSIENT;
265 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
267 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
271 static bool group_empty_for_bottom_stdisp(WGroup *ws)
276 FOR_ALL_NODES_IN_GROUP(ws, st, tmp){
277 if(st!=ws->bottom && st!=ws->managed_stdisp)
285 static WRegion *groupws_managed_disposeroot(WGroupWS *ws, WRegion *reg)
287 if(group_bottom(&ws->grp)==reg){
288 if(group_empty_for_bottom_stdisp(&ws->grp)){
289 WRegion *tmpr=region_disposeroot((WRegion*)ws);
290 return (tmpr!=NULL ? tmpr : reg);
301 /*{{{ WGroupWS class */
304 bool groupws_init(WGroupWS *ws, WWindow *parent, const WFitParams *fp)
306 if(!group_init(&(ws->grp), parent, fp))
309 ((WRegion*)ws)->flags|=REGION_GRAB_ON_PARENT;
311 region_add_bindmap((WRegion*)ws, ioncore_groupws_bindmap);
317 WGroupWS *create_groupws(WWindow *parent, const WFitParams *fp)
319 CREATEOBJ_IMPL(WGroupWS, groupws, (p, parent, fp));
323 void groupws_deinit(WGroupWS *ws)
325 group_deinit(&(ws->grp));
329 WRegion *groupws_load(WWindow *par, const WFitParams *fp,
334 ws=create_groupws(par, fp);
339 group_do_load(&ws->grp, tab);
345 static DynFunTab groupws_dynfuntab[]={
346 {(DynFun*)region_prepare_manage,
347 (DynFun*)groupws_prepare_manage},
349 {(DynFun*)region_prepare_manage_transient,
350 (DynFun*)groupws_prepare_manage_transient},
352 {(DynFun*)region_managed_disposeroot,
353 (DynFun*)groupws_managed_disposeroot},
355 {(DynFun*)region_handle_drop,
356 (DynFun*)groupws_handle_drop},
358 {region_manage_stdisp,
359 group_manage_stdisp},
366 IMPLCLASS(WGroupWS, WGroup, groupws_deinit, groupws_dynfuntab);