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"
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
);
51 if(extl_table_gets_i(tab
, "float_placement_padding", &fpp
))
52 ioncore_placement_padding
=maxof(0, fpp
);
56 void ioncore_groupws_get(ExtlTab t
)
58 extl_table_sets_s(t
, "float_placement_method",
59 (ioncore_placement_method
==PLACEMENT_UDLR
61 : (ioncore_placement_method
==PLACEMENT_LRUD
64 extl_table_sets_i(t
, "float_placement_padding", ioncore_placement_padding
);
74 static bool groupws_attach_framed(WGroupWS
*ws
,
75 WGroupAttachParams
*ap
,
79 WRegionAttachData data
;
81 data
.type
=REGION_ATTACH_REPARENT
;
84 return (region_attach_framed((WRegion
*)ws
, fp
,
85 (WRegionAttachFn
*)group_do_attach
,
90 bool groupws_handle_drop(WGroupWS
*ws
, int x
, int y
,
93 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
94 WFramedParam fp
=FRAMEDPARAM_INIT
;
99 fp
.inner_geom_gravity_set
=TRUE
;
102 fp
.inner_geom
.w
=REGION_GEOM(dropped
).w
;
103 fp
.inner_geom
.h
=REGION_GEOM(dropped
).h
;
104 fp
.gravity
=NorthWestGravity
;
106 return groupws_attach_framed(ws
, &ap
, &fp
, dropped
);
111 * Attach region \var{reg} on \var{ws}.
112 * At least the following fields in \var{t} are supported:
114 * \begin{tabularx}{\linewidth}{lX}
115 * \tabhead{Field & Description}
116 * \var{switchto} & Should the region be switched to (boolean)? Optional. \\
117 * \var{geom} & Geometry; \var{x} and \var{y}, if set, indicates top-left of
118 * the frame to be created while \var{width} and \var{height}, if set, indicate
119 * the size of the client window within that frame. Optional.
122 EXTL_EXPORT_AS(WGroupWS
, attach_framed
)
123 bool groupws_attach_framed_extl(WGroupWS
*ws
, WRegion
*reg
, ExtlTab t
)
125 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
126 WFramedParam frp
=FRAMEDPARAM_INIT
;
131 groupattachparams_get(&ap
, t
, NULL
);
133 /* Sensible size is given in framedparams */
139 frp
.inner_geom_gravity_set
=1;
140 frp
.inner_geom
=ap
.geom
;
141 frp
.gravity
=NorthWestGravity
;
142 extl_table_gets_i(t
, "gravity", &frp
.gravity
);
145 return groupws_attach_framed(ws
, &ap
, &frp
, reg
);
152 /*{{{ groupws_prepare_manage */
155 static WPHolder
*groupws_do_prepare_manage(WGroupWS
*ws
,
156 const WClientWin
*cwin
,
157 const WManageParams
*param
)
159 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
160 WFramedParam fp
=FRAMEDPARAM_INIT
;
164 fp
.inner_geom_gravity_set
=TRUE
;
165 fp
.inner_geom
=param
->geom
;
166 fp
.gravity
=param
->gravity
;
168 groupattachparams_get(&ap
, cwin
->proptab
, "attach_params");
171 !param
->maprq
|| ioncore_g
.opmode
==IONCORE_OPMODE_INIT
){
174 }else if(!ap
.geom_weak_set
){
176 ap
.geom_weak
=REGION_RQGEOM_WEAK_X
|REGION_RQGEOM_WEAK_Y
;
179 ph
=(WPHolder
*)create_grouppholder(&ws
->grp
, NULL
, &ap
);
182 ph
=pholder_either((WPHolder
*)create_framedpholder(ph
, &fp
), ph
);
186 WGroupAttachParams gp
=GROUPATTACHPARAMS_INIT
;
192 gph
=create_grouppholder(NULL
, NULL
, &gp
);
195 gph
->recreate_pholder
=ph
;
196 return (WPHolder
*)gph
;
204 WPHolder
*groupws_prepare_manage(WGroupWS
*ws
, const WClientWin
*cwin
,
205 const WManageParams
*param
,
208 int cpriority
=MANAGE_PRIORITY_SUB(priority
, MANAGE_PRIORITY_GROUP
);
209 int bpriority
=MANAGE_PRIORITY_SUBX(priority
, MANAGE_PRIORITY_GROUP
);
210 WRegion
*b
=(ws
->grp
.bottom
!=NULL
? ws
->grp
.bottom
->reg
: NULL
);
212 bool act_b
=(ws
->grp
.bottom
==ws
->grp
.current_managed
);
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
);
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
;
254 ap
.stack_above
=OBJ_CAST(REGION_PARENT(param
->tfor
), WRegion
);
255 if(ap
.stack_above
==NULL
)
258 fp
.inner_geom_gravity_set
=TRUE
;
259 fp
.inner_geom
=param
->geom
;
260 fp
.gravity
=param
->gravity
;
261 fp
.mode
=FRAME_MODE_TRANSIENT
;
263 groupattachparams_get(&ap
, cwin
->proptab
, "attach_params");
265 if(!ap
.geom_weak_set
|| param
->userpos
||
266 !param
->maprq
|| ioncore_g
.opmode
==IONCORE_OPMODE_INIT
){
271 ph
=(WPHolder
*)create_grouppholder(&ws
->grp
, NULL
, &ap
);
273 return pholder_either((WPHolder
*)create_framedpholder(ph
, &fp
), ph
);
277 static bool group_empty_for_bottom_stdisp(WGroup
*ws
)
282 FOR_ALL_NODES_IN_GROUP(ws
, st
, tmp
){
283 if(st
!=ws
->bottom
&& st
!=ws
->managed_stdisp
)
291 static WRegion
*groupws_managed_disposeroot(WGroupWS
*ws
, WRegion
*reg
)
293 if(group_bottom(&ws
->grp
)==reg
){
294 if(group_empty_for_bottom_stdisp(&ws
->grp
))
295 return region_disposeroot((WRegion
*)ws
);
305 /*{{{ WGroupWS class */
308 bool groupws_init(WGroupWS
*ws
, WWindow
*parent
, const WFitParams
*fp
)
310 if(!group_init(&(ws
->grp
), parent
, fp
, "Notion GroupWS"))
313 ws
->initial_outputs
=extl_create_table();
315 ((WRegion
*)ws
)->flags
|=REGION_GRAB_ON_PARENT
;
317 region_add_bindmap((WRegion
*)ws
, ioncore_groupws_bindmap
);
323 WGroupWS
*create_groupws(WWindow
*parent
, const WFitParams
*fp
)
325 CREATEOBJ_IMPL(WGroupWS
, groupws
, (p
, parent
, fp
));
329 void groupws_deinit(WGroupWS
*ws
)
331 extl_unref_table(ws
->initial_outputs
);
332 group_deinit(&(ws
->grp
));
336 WRegion
*groupws_load(WWindow
*par
, const WFitParams
*fp
,
342 ws
=create_groupws(par
, fp
);
347 group_do_load(&ws
->grp
, tab
);
349 if(extl_table_gets_t(tab
, "initial_outputs", &io
))
350 ws
->initial_outputs
=io
;
355 ExtlTab
groupws_get_configuration(WGroupWS
*ws
)
360 tab
=group_get_configuration(&ws
->grp
);
361 extl_table_sets_t(tab
, "initial_outputs", ws
->initial_outputs
);
367 ExtlTab
groupws_get_initial_outputs(WGroupWS
*ws
)
369 return extl_ref_table(ws
->initial_outputs
);
374 void groupws_set_initial_outputs(WGroupWS
*ws
, ExtlTab tab
)
376 extl_unref_table(ws
->initial_outputs
);
377 ws
->initial_outputs
=extl_ref_table(tab
);
381 static DynFunTab groupws_dynfuntab
[]={
382 {(DynFun
*)region_prepare_manage
,
383 (DynFun
*)groupws_prepare_manage
},
385 {(DynFun
*)region_prepare_manage_transient
,
386 (DynFun
*)groupws_prepare_manage_transient
},
388 {(DynFun
*)region_managed_disposeroot
,
389 (DynFun
*)groupws_managed_disposeroot
},
391 {(DynFun
*)region_handle_drop
,
392 (DynFun
*)groupws_handle_drop
},
394 {region_manage_stdisp
,
395 group_manage_stdisp
},
397 {(DynFun
*)region_get_configuration
,
398 (DynFun
*)groupws_get_configuration
},
405 IMPLCLASS(WGroupWS
, WGroup
, groupws_deinit
, groupws_dynfuntab
);