2 * ion/ioncore/group-ws.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
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
);
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
60 : (ioncore_placement_method
==PLACEMENT_LRUD
63 extl_table_sets_i(t
, "float_placement_padding", ioncore_placement_padding
);
73 static bool groupws_attach_framed(WGroupWS
*ws
,
74 WGroupAttachParams
*ap
,
78 WRegionAttachData data
;
80 data
.type
=REGION_ATTACH_REPARENT
;
83 return (region_attach_framed((WRegion
*)ws
, fp
,
84 (WRegionAttachFn
*)group_do_attach
,
89 bool groupws_handle_drop(WGroupWS
*ws
, int x
, int y
,
92 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
93 WFramedParam fp
=FRAMEDPARAM_INIT
;
98 fp
.inner_geom_gravity_set
=TRUE
;
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
);
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.
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
;
130 groupattachparams_get(&ap
, t
, NULL
);
132 /* Sensible size is given in framedparams */
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
);
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
;
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");
170 !param
->maprq
|| ioncore_g
.opmode
==IONCORE_OPMODE_INIT
){
173 }else if(!ap
.geom_weak_set
){
175 ap
.geom_weak
=REGION_RQGEOM_WEAK_X
|REGION_RQGEOM_WEAK_Y
;
178 ph
=(WPHolder
*)create_grouppholder(&ws
->grp
, NULL
, &ap
);
181 ph
=pholder_either((WPHolder
*)create_framedpholder(ph
, &fp
), ph
);
185 WGroupAttachParams gp
=GROUPATTACHPARAMS_INIT
;
191 gph
=create_grouppholder(NULL
, NULL
, &gp
);
194 gph
->recreate_pholder
=ph
;
195 return (WPHolder
*)gph
;
203 WPHolder
*groupws_prepare_manage(WGroupWS
*ws
, const WClientWin
*cwin
,
204 const WManageParams
*param
,
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
);
211 bool act_b
=(ws
->grp
.bottom
==ws
->grp
.current_managed
);
214 if(b
!=NULL
&& !HAS_DYN(b
, region_prepare_manage
))
218 ? !extl_table_is_bool_set(cwin
->proptab
, "float")
221 if(b
!=NULL
&& use_bottom
)
222 ph
=region_prepare_manage(b
, cwin
, param
, bpriority
);
226 WRegion
*r
=(ws
->grp
.current_managed
!=NULL
227 ? ws
->grp
.current_managed
->reg
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
);
244 WPHolder
*groupws_prepare_manage_transient(WGroupWS
*ws
, const WClientWin
*cwin
,
245 const WManageParams
*param
,
248 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
249 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
;
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
){
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
)
281 FOR_ALL_NODES_IN_GROUP(ws
, st
, tmp
){
282 if(st
!=ws
->bottom
&& st
!=ws
->managed_stdisp
)
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
);
304 /*{{{ WGroupWS class */
307 bool groupws_init(WGroupWS
*ws
, WWindow
*parent
, const WFitParams
*fp
)
309 if(!group_init(&(ws
->grp
), parent
, fp
))
312 ((WRegion
*)ws
)->flags
|=REGION_GRAB_ON_PARENT
;
314 region_add_bindmap((WRegion
*)ws
, ioncore_groupws_bindmap
);
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
,
337 ws
=create_groupws(par
, fp
);
342 group_do_load(&ws
->grp
, tab
);
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
},
369 IMPLCLASS(WGroupWS
, WGroup
, groupws_deinit
, groupws_dynfuntab
);