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 fp=FRAMEDPARAM_INIT;
129 fp.gravity=ForgetGravity;
131 if(extl_table_is_bool_set(t, "switchto")){
132 ap.switchto_set=TRUE;
136 if(extl_table_gets_t(t, "geom", >)){
142 if(extl_table_gets_i(gt, "x", &(ap.geom.x)))
144 if(extl_table_gets_i(gt, "y", &(ap.geom.y)))
147 if(extl_table_gets_i(gt, "w", &(ap.geom.w)))
149 if(extl_table_gets_i(gt, "h", &(ap.geom.h)))
152 fp.inner_geom.w=maxof(fp.inner_geom.w, 1);
153 fp.inner_geom.h=maxof(fp.inner_geom.h, 1);
155 fp.inner_geom_gravity_set=(size==2 && pos==2);
157 extl_unref_table(gt);
160 return groupws_attach_framed(ws, &ap, &fp, reg);
167 /*{{{ groupws_prepare_manage */
170 static WPHolder *groupws_do_prepare_manage(WGroupWS *ws,
171 const WClientWin *cwin,
172 const WManageParams *param,
175 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
176 WFramedParam fp=FRAMEDPARAM_INIT;
180 fp.inner_geom_gravity_set=TRUE;
181 fp.inner_geom=param->geom;
182 fp.gravity=param->gravity;
185 ap.geom_weak=geom_weak;
187 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
190 ph=pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
193 ph=pholder_either((WPHolder*)create_groupedpholder((WPHolder*)ph), ph);
199 WPHolder *groupws_prepare_manage(WGroupWS *ws, const WClientWin *cwin,
200 const WManageParams *param,
203 int cpriority=MANAGE_PRIORITY_SUB(priority, MANAGE_PRIORITY_GROUP);
204 int bpriority=MANAGE_PRIORITY_SUBX(priority, MANAGE_PRIORITY_GROUP);
205 WRegion *b=(ws->grp.bottom!=NULL ? ws->grp.bottom->reg : NULL);
207 bool act_b=(ws->grp.bottom==ws->grp.current_managed);
211 if(param->maprq && ioncore_g.opmode!=IONCORE_OPMODE_INIT
213 /* When the window is mapped by application request, position
214 * request is only honoured if the position was given by the user
215 * and in case of a transient (the app may know better where to
216 * place them) or if we're initialising.
218 weak=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
221 if(b!=NULL && !HAS_DYN(b, region_prepare_manage))
225 ? !extl_table_is_bool_set(cwin->proptab, "float")
228 if(b!=NULL && use_bottom)
229 ph=region_prepare_manage(b, cwin, param, bpriority);
233 WRegion *r=(ws->grp.current_managed!=NULL
234 ? ws->grp.current_managed->reg
238 ph=region_prepare_manage(r, cwin, param, cpriority);
241 if(ph==NULL && MANAGE_PRIORITY_OK(priority, MANAGE_PRIORITY_GROUP))
242 ph=groupws_do_prepare_manage(ws, cwin, param, weak);
244 if(ph==NULL && b!=NULL && !use_bottom)
245 ph=region_prepare_manage(b, cwin, param, cpriority);
251 WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin,
252 const WManageParams *param,
255 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
256 WFramedParam fp=FRAMEDPARAM_INIT;
259 ap.stack_above=OBJ_CAST(REGION_PARENT(param->tfor), WRegion);
260 if(ap.stack_above==NULL)
263 fp.inner_geom_gravity_set=TRUE;
264 fp.inner_geom=param->geom;
265 fp.gravity=param->gravity;
266 fp.mode=FRAME_MODE_TRANSIENT;
271 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
273 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
277 WPHolder *groupws_get_rescue_pholder_for(WGroupWS *ws,
280 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
281 WFramedParam fp=FRAMEDPARAM_INIT;
285 ap.geom=REGION_GEOM(forwhat);
288 ap.geom_weak=(REGION_PARENT(forwhat)!=REGION_PARENT(ws)
289 ? REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y
292 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
294 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
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_handle_drop,
353 (DynFun*)groupws_handle_drop},
355 {(DynFun*)region_get_rescue_pholder_for,
356 (DynFun*)groupws_get_rescue_pholder_for},
358 {region_manage_stdisp,
359 group_manage_stdisp},
366 IMPLCLASS(WGroupWS, WGroup, groupws_deinit, groupws_dynfuntab);