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"
30 #include "screen-notify.h"
36 void ioncore_groupws_set(ExtlTab tab
)
41 if(extl_table_gets_s(tab
, "float_placement_method", &method
)){
42 if(strcmp(method
, "udlr")==0)
43 ioncore_placement_method
=PLACEMENT_UDLR
;
44 else if(strcmp(method
, "lrud")==0)
45 ioncore_placement_method
=PLACEMENT_LRUD
;
46 else if(strcmp(method
, "random")==0)
47 ioncore_placement_method
=PLACEMENT_RANDOM
;
49 warn(TR("Unknown placement method \"%s\"."), method
);
52 if(extl_table_gets_i(tab
, "float_placement_padding", &fpp
))
53 ioncore_placement_padding
=maxof(0, fpp
);
57 void ioncore_groupws_get(ExtlTab t
)
59 extl_table_sets_s(t
, "float_placement_method",
60 (ioncore_placement_method
==PLACEMENT_UDLR
62 : (ioncore_placement_method
==PLACEMENT_LRUD
65 extl_table_sets_i(t
, "float_placement_padding", ioncore_placement_padding
);
75 static bool groupws_attach_framed(WGroupWS
*ws
,
76 WGroupAttachParams
*ap
,
80 WRegionAttachData data
;
82 data
.type
=REGION_ATTACH_REPARENT
;
85 return (region_attach_framed((WRegion
*)ws
, fp
,
86 (WRegionAttachFn
*)group_do_attach
,
91 bool groupws_handle_drop(WGroupWS
*ws
, int x
, int y
,
94 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
95 WFramedParam fp
=FRAMEDPARAM_INIT
;
100 fp
.inner_geom_gravity_set
=TRUE
;
103 fp
.inner_geom
.w
=REGION_GEOM(dropped
).w
;
104 fp
.inner_geom
.h
=REGION_GEOM(dropped
).h
;
105 fp
.gravity
=NorthWestGravity
;
107 return groupws_attach_framed(ws
, &ap
, &fp
, dropped
);
112 * Attach region \var{reg} on \var{ws}.
113 * At least the following fields in \var{t} are supported:
115 * \begin{tabularx}{\linewidth}{lX}
116 * \tabhead{Field & Description}
117 * \var{switchto} & Should the region be switched to (boolean)? Optional. \\
118 * \var{geom} & Geometry; \var{x} and \var{y}, if set, indicates top-left of
119 * the frame to be created while \var{width} and \var{height}, if set, indicate
120 * the size of the client window within that frame. Optional.
123 EXTL_EXPORT_AS(WGroupWS
, attach_framed
)
124 bool groupws_attach_framed_extl(WGroupWS
*ws
, WRegion
*reg
, ExtlTab t
)
126 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
127 WFramedParam frp
=FRAMEDPARAM_INIT
;
132 groupattachparams_get(&ap
, t
, NULL
);
134 /* Sensible size is given in framedparams */
140 frp
.inner_geom_gravity_set
=1;
141 frp
.inner_geom
=ap
.geom
;
142 frp
.gravity
=NorthWestGravity
;
143 extl_table_gets_i(t
, "gravity", &frp
.gravity
);
146 return groupws_attach_framed(ws
, &ap
, &frp
, reg
);
153 /*{{{ groupws_prepare_manage */
156 static WPHolder
*groupws_do_prepare_manage(WGroupWS
*ws
,
157 const WClientWin
*cwin
,
158 const WManageParams
*param
)
160 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
161 WFramedParam fp
=FRAMEDPARAM_INIT
;
165 fp
.inner_geom_gravity_set
=TRUE
;
166 fp
.inner_geom
=param
->geom
;
167 fp
.gravity
=param
->gravity
;
169 groupattachparams_get(&ap
, cwin
->proptab
, "attach_params");
172 !param
->maprq
|| ioncore_g
.opmode
==IONCORE_OPMODE_INIT
){
175 }else if(!ap
.geom_weak_set
){
177 ap
.geom_weak
=REGION_RQGEOM_WEAK_X
|REGION_RQGEOM_WEAK_Y
;
180 ph
=(WPHolder
*)create_grouppholder(&ws
->grp
, NULL
, &ap
);
183 ph
=pholder_either((WPHolder
*)create_framedpholder(ph
, &fp
), ph
);
187 WGroupAttachParams gp
=GROUPATTACHPARAMS_INIT
;
193 gph
=create_grouppholder(NULL
, NULL
, &gp
);
196 gph
->recreate_pholder
=ph
;
197 return (WPHolder
*)gph
;
205 WPHolder
*groupws_prepare_manage(WGroupWS
*ws
, const WClientWin
*cwin
,
206 const WManageParams
*param
,
209 int cpriority
=MANAGE_PRIORITY_SUB(priority
, MANAGE_PRIORITY_GROUP
);
210 int bpriority
=MANAGE_PRIORITY_SUBX(priority
, MANAGE_PRIORITY_GROUP
);
211 WRegion
*b
=(ws
->grp
.bottom
!=NULL
? ws
->grp
.bottom
->reg
: NULL
);
213 bool act_b
=(ws
->grp
.bottom
==ws
->grp
.current_managed
);
216 if(b
!=NULL
&& !HAS_DYN(b
, region_prepare_manage
))
220 ? !extl_table_is_bool_set(cwin
->proptab
, "float")
223 if(b
!=NULL
&& use_bottom
)
224 ph
=region_prepare_manage(b
, cwin
, param
, bpriority
);
228 WRegion
*r
=(ws
->grp
.current_managed
!=NULL
229 ? ws
->grp
.current_managed
->reg
233 ph
=region_prepare_manage(r
, cwin
, param
, cpriority
);
236 if(ph
==NULL
&& MANAGE_PRIORITY_OK(priority
, MANAGE_PRIORITY_GROUP
))
237 ph
=groupws_do_prepare_manage(ws
, cwin
, param
);
239 if(ph
==NULL
&& b
!=NULL
&& !use_bottom
)
240 ph
=region_prepare_manage(b
, cwin
, param
, cpriority
);
246 WPHolder
*groupws_prepare_manage_transient(WGroupWS
*ws
, const WClientWin
*cwin
,
247 const WManageParams
*param
,
250 WGroupAttachParams ap
=GROUPATTACHPARAMS_INIT
;
251 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
);
333 screen_unnotify_if_workspace(ws
);
335 group_deinit(&(ws
->grp
));
339 WRegion
*groupws_load(WWindow
*par
, const WFitParams
*fp
,
345 ws
=create_groupws(par
, fp
);
350 group_do_load(&ws
->grp
, tab
);
352 if(extl_table_gets_t(tab
, "initial_outputs", &io
))
353 ws
->initial_outputs
=io
;
358 ExtlTab
groupws_get_configuration(WGroupWS
*ws
)
363 tab
=group_get_configuration(&ws
->grp
);
364 extl_table_sets_t(tab
, "initial_outputs", ws
->initial_outputs
);
370 ExtlTab
groupws_get_initial_outputs(WGroupWS
*ws
)
372 return extl_ref_table(ws
->initial_outputs
);
377 void groupws_set_initial_outputs(WGroupWS
*ws
, ExtlTab tab
)
379 extl_unref_table(ws
->initial_outputs
);
380 ws
->initial_outputs
=extl_ref_table(tab
);
384 static DynFunTab groupws_dynfuntab
[]={
385 {(DynFun
*)region_prepare_manage
,
386 (DynFun
*)groupws_prepare_manage
},
388 {(DynFun
*)region_prepare_manage_transient
,
389 (DynFun
*)groupws_prepare_manage_transient
},
391 {(DynFun
*)region_managed_disposeroot
,
392 (DynFun
*)groupws_managed_disposeroot
},
394 {(DynFun
*)region_handle_drop
,
395 (DynFun
*)groupws_handle_drop
},
397 {region_manage_stdisp
,
398 group_manage_stdisp
},
400 {(DynFun
*)region_get_configuration
,
401 (DynFun
*)groupws_get_configuration
},
408 IMPLCLASS(WGroupWS
, WGroup
, groupws_deinit
, groupws_dynfuntab
);