Only define LUA when lua is actually on the PATH
[notion/jeffpc.git] / ioncore / group-ws.c
blob0639ff6bf969eddef6f830ec2d32965e9776f69a
1 /*
2 * ion/ioncore/group-ws.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
11 #include <libtu/minmax.h>
12 #include <libtu/objp.h>
14 #include "common.h"
15 #include "global.h"
16 #include "region.h"
17 #include "focus.h"
18 #include "group.h"
19 #include "regbind.h"
20 #include "bindmaps.h"
21 #include "xwindow.h"
22 #include "group-ws.h"
23 #include "group-cw.h"
24 #include "grouppholder.h"
25 #include "framedpholder.h"
26 #include "float-placement.h"
27 #include "resize.h"
28 #include "conf.h"
31 /*{{{ Settings */
34 void ioncore_groupws_set(ExtlTab tab)
36 char *method=NULL;
37 int fpp;
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;
46 else
47 warn(TR("Unknown placement method \"%s\"."), method);
48 free(method);
50 if(extl_table_gets_i(tab, "float_placement_padding", &fpp))
51 ioncore_placement_padding=maxof(0, fpp);
55 void ioncore_groupws_get(ExtlTab t)
57 extl_table_sets_s(t, "float_placement_method",
58 (ioncore_placement_method==PLACEMENT_UDLR
59 ? "udlr"
60 : (ioncore_placement_method==PLACEMENT_LRUD
61 ? "lrud"
62 : "random")));
63 extl_table_sets_i(t, "float_placement_padding", ioncore_placement_padding);
67 /*}}}*/
70 /*{{{ Attach stuff */
73 static bool groupws_attach_framed(WGroupWS *ws,
74 WGroupAttachParams *ap,
75 WFramedParam *fp,
76 WRegion *reg)
78 WRegionAttachData data;
80 data.type=REGION_ATTACH_REPARENT;
81 data.u.reg=reg;
83 return (region_attach_framed((WRegion*)ws, fp,
84 (WRegionAttachFn*)group_do_attach,
85 ap, &data)!=NULL);
89 bool groupws_handle_drop(WGroupWS *ws, int x, int y,
90 WRegion *dropped)
92 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
93 WFramedParam fp=FRAMEDPARAM_INIT;
95 ap.switchto_set=TRUE;
96 ap.switchto=TRUE;
98 fp.inner_geom_gravity_set=TRUE;
99 fp.inner_geom.x=x;
100 fp.inner_geom.y=y;
101 fp.inner_geom.w=REGION_GEOM(dropped).w;
102 fp.inner_geom.h=REGION_GEOM(dropped).h;
103 fp.gravity=NorthWestGravity;
105 return groupws_attach_framed(ws, &ap, &fp, dropped);
109 /*EXTL_DOC
110 * Attach region \var{reg} on \var{ws}.
111 * At least the following fields in \var{t} are supported:
113 * \begin{tabularx}{\linewidth}{lX}
114 * \tabhead{Field & Description}
115 * \var{switchto} & Should the region be switched to (boolean)? Optional. \\
116 * \var{geom} & Geometry; \var{x} and \var{y}, if set, indicates top-left of
117 * the frame to be created while \var{width} and \var{height}, if set, indicate
118 * the size of the client window within that frame. Optional.
119 * \end{tabularx}
121 EXTL_EXPORT_AS(WGroupWS, attach_framed)
122 bool groupws_attach_framed_extl(WGroupWS *ws, WRegion *reg, ExtlTab t)
124 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
125 WFramedParam frp=FRAMEDPARAM_INIT;
127 if(reg==NULL)
128 return FALSE;
130 groupattachparams_get(&ap, t, NULL);
132 /* Sensible size is given in framedparams */
133 if(ap.geom_set){
134 ap.geom_set=0;
135 ap.geom_weak_set=1;
136 ap.geom_weak=0;
138 frp.inner_geom_gravity_set=1;
139 frp.inner_geom=ap.geom;
140 frp.gravity=NorthWestGravity;
141 extl_table_gets_i(t, "gravity", &frp.gravity);
144 return groupws_attach_framed(ws, &ap, &frp, reg);
148 /*}}}*/
151 /*{{{ groupws_prepare_manage */
154 static WPHolder *groupws_do_prepare_manage(WGroupWS *ws,
155 const WClientWin *cwin,
156 const WManageParams *param)
158 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
159 WFramedParam fp=FRAMEDPARAM_INIT;
160 WPHolder *ph;
163 fp.inner_geom_gravity_set=TRUE;
164 fp.inner_geom=param->geom;
165 fp.gravity=param->gravity;
167 groupattachparams_get(&ap, cwin->proptab, "attach_params");
169 if(param->userpos ||
170 !param->maprq || ioncore_g.opmode==IONCORE_OPMODE_INIT){
171 ap.geom_weak_set=1;
172 ap.geom_weak=0;
173 }else if(!ap.geom_weak_set){
174 ap.geom_weak_set=1;
175 ap.geom_weak=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
178 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
180 if(ph!=NULL)
181 ph=pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
183 if(ph!=NULL){
184 WGroupPHolder *gph;
185 WGroupAttachParams gp=GROUPATTACHPARAMS_INIT;
187 gp.switchto_set=1;
188 gp.switchto=1;
189 gp.bottom=1;
191 gph=create_grouppholder(NULL, NULL, &gp);
193 if(gph!=NULL){
194 gph->recreate_pholder=ph;
195 return (WPHolder*)gph;
199 return ph;
203 WPHolder *groupws_prepare_manage(WGroupWS *ws, const WClientWin *cwin,
204 const WManageParams *param,
205 int priority)
207 int cpriority=MANAGE_PRIORITY_SUB(priority, MANAGE_PRIORITY_GROUP);
208 int bpriority=MANAGE_PRIORITY_SUBX(priority, MANAGE_PRIORITY_GROUP);
209 WRegion *b=(ws->grp.bottom!=NULL ? ws->grp.bottom->reg : NULL);
210 WPHolder *ph=NULL;
211 bool act_b=(ws->grp.bottom==ws->grp.current_managed);
212 bool use_bottom;
214 if(b!=NULL && !HAS_DYN(b, region_prepare_manage))
215 b=NULL;
217 use_bottom=(act_b
218 ? !extl_table_is_bool_set(cwin->proptab, "float")
219 : act_b);
221 if(b!=NULL && use_bottom)
222 ph=region_prepare_manage(b, cwin, param, bpriority);
224 if(ph==NULL){
225 /* Check current */
226 WRegion *r=(ws->grp.current_managed!=NULL
227 ? ws->grp.current_managed->reg
228 : NULL);
230 if(r!=NULL && r!=b)
231 ph=region_prepare_manage(r, cwin, param, cpriority);
234 if(ph==NULL && MANAGE_PRIORITY_OK(priority, MANAGE_PRIORITY_GROUP))
235 ph=groupws_do_prepare_manage(ws, cwin, param);
237 if(ph==NULL && b!=NULL && !use_bottom)
238 ph=region_prepare_manage(b, cwin, param, cpriority);
240 return ph;
244 WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin,
245 const WManageParams *param,
246 int unused)
248 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
249 WFramedParam fp=FRAMEDPARAM_INIT;
250 WPHolder *ph;
251 bool tmp;
253 ap.stack_above=OBJ_CAST(REGION_PARENT(param->tfor), WRegion);
254 if(ap.stack_above==NULL)
255 return 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;
262 groupattachparams_get(&ap, cwin->proptab, "attach_params");
264 if(!ap.geom_weak_set || param->userpos ||
265 !param->maprq || ioncore_g.opmode==IONCORE_OPMODE_INIT){
266 ap.geom_weak_set=1;
267 ap.geom_weak=0;
270 ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
272 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
276 static bool group_empty_for_bottom_stdisp(WGroup *ws)
278 WGroupIterTmp tmp;
279 WStacking *st;
281 FOR_ALL_NODES_IN_GROUP(ws, st, tmp){
282 if(st!=ws->bottom && st!=ws->managed_stdisp)
283 return FALSE;
286 return TRUE;
290 static WRegion *groupws_managed_disposeroot(WGroupWS *ws, WRegion *reg)
292 if(group_bottom(&ws->grp)==reg){
293 if(group_empty_for_bottom_stdisp(&ws->grp))
294 return region_disposeroot((WRegion*)ws);
297 return reg;
301 /*}}}*/
304 /*{{{ WGroupWS class */
307 bool groupws_init(WGroupWS *ws, WWindow *parent, const WFitParams *fp)
309 if(!group_init(&(ws->grp), parent, fp))
310 return FALSE;
312 ((WRegion*)ws)->flags|=REGION_GRAB_ON_PARENT;
314 region_add_bindmap((WRegion*)ws, ioncore_groupws_bindmap);
316 return TRUE;
320 WGroupWS *create_groupws(WWindow *parent, const WFitParams *fp)
322 CREATEOBJ_IMPL(WGroupWS, groupws, (p, parent, fp));
326 void groupws_deinit(WGroupWS *ws)
328 group_deinit(&(ws->grp));
332 WRegion *groupws_load(WWindow *par, const WFitParams *fp,
333 ExtlTab tab)
335 WGroupWS *ws;
337 ws=create_groupws(par, fp);
339 if(ws==NULL)
340 return NULL;
342 group_do_load(&ws->grp, tab);
344 return (WRegion*)ws;
348 static DynFunTab groupws_dynfuntab[]={
349 {(DynFun*)region_prepare_manage,
350 (DynFun*)groupws_prepare_manage},
352 {(DynFun*)region_prepare_manage_transient,
353 (DynFun*)groupws_prepare_manage_transient},
355 {(DynFun*)region_managed_disposeroot,
356 (DynFun*)groupws_managed_disposeroot},
358 {(DynFun*)region_handle_drop,
359 (DynFun*)groupws_handle_drop},
361 {region_manage_stdisp,
362 group_manage_stdisp},
364 END_DYNFUNTAB
368 EXTL_EXPORT
369 IMPLCLASS(WGroupWS, WGroup, groupws_deinit, groupws_dynfuntab);
372 /*}}}*/