2 * ion/ioncore/group-cw.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * See the included file LICENSE for details.
11 #include <libtu/objp.h>
12 #include <libmainloop/defer.h>
16 #include "clientwin.h"
23 #include "framedpholder.h"
24 #include "grouppholder.h"
27 #define DFLT_SZPLCY SIZEPOLICY_FREE_GLUE__SOUTH
30 /*{{{ Add/remove managed */
33 static WPHolder *groupcw_transient_pholder(WGroupCW *cwg,
34 const WClientWin *cwin,
35 const WManageParams *mp)
37 WGroupAttachParams param=GROUPATTACHPARAMS_INIT;
38 WFramedParam fp=FRAMEDPARAM_INIT;
42 param.level=STACKING_LEVEL_MODAL1;
45 param.szplcy=cwg->transient_szplcy;
50 param.geom_weak_set=1;
51 param.geom_weak=REGION_RQGEOM_WEAK_ALL;
53 if(!ioncore_g.framed_transients){
57 return (WPHolder*)create_grouppholder(&cwg->grp, NULL, ¶m);
59 fp.inner_geom_gravity_set=1;
60 fp.inner_geom=mp->geom;
61 fp.gravity=ForgetGravity;
62 fp.mode=FRAME_MODE_TRANSIENT;
64 ph=(WPHolder*)create_grouppholder(&cwg->grp, NULL, ¶m);
66 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
71 WPHolder *groupcw_prepare_manage(WGroupCW *cwg, const WClientWin *cwin,
72 const WManageParams *param, int priority)
74 if(!MANAGE_PRIORITY_OK(priority, MANAGE_PRIORITY_GROUP))
77 /* Only catch windows with transient mode set to current here. */
78 if(clientwin_get_transient_mode(cwin)!=TRANSIENT_MODE_CURRENT)
81 return groupcw_transient_pholder(cwg, cwin, param);
85 static bool groupcw_should_manage_transient(WGroupCW *cwg,
90 if(group_find_stacking(&cwg->grp, (WRegion*)tfor))
93 mgr=REGION_MANAGER(tfor);
95 if(mgr!=NULL && ioncore_g.framed_transients && OBJ_IS(mgr, WFrame))
96 return (group_find_stacking(&cwg->grp, mgr)!=NULL);
102 WPHolder *groupcw_prepare_manage_transient(WGroupCW *cwg,
103 const WClientWin *transient,
104 const WManageParams *param,
107 WPHolder *ph=region_prepare_manage_transient_default((WRegion*)cwg,
112 if(ph==NULL && groupcw_should_manage_transient(cwg, param->tfor))
113 ph=groupcw_transient_pholder(cwg, transient, param);
119 static WRegion *groupcw_managed_disposeroot(WGroupCW *ws, WRegion *reg)
125 FOR_ALL_NODES_IN_GROUP(&ws->grp, st, tmp){
126 if(st!=ws->grp.managed_stdisp && st->reg!=reg){
131 tmpr=region_disposeroot((WRegion*)ws);
132 return (tmpr!=NULL ? tmpr : reg);
143 * Toggle transients managed by \var{cwin} between top/bottom
147 void groupcw_toggle_transients_pos(WGroupCW *cwg)
152 if((cwg->transient_szplcy&SIZEPOLICY_VERT_MASK)==SIZEPOLICY_VERT_TOP){
153 cwg->transient_szplcy&=~SIZEPOLICY_VERT_MASK;
154 cwg->transient_szplcy|=SIZEPOLICY_VERT_BOTTOM;
156 cwg->transient_szplcy&=~SIZEPOLICY_VERT_MASK;
157 cwg->transient_szplcy|=SIZEPOLICY_VERT_TOP;
160 FOR_ALL_NODES_IN_GROUP(&cwg->grp, st, tmp){
161 st->szplcy&=~SIZEPOLICY_VERT_MASK;
162 st->szplcy|=(cwg->transient_szplcy&SIZEPOLICY_VERT_MASK);
167 fp.g=REGION_GEOM(cwg);
169 sizepolicy(&st->szplcy, st->reg, NULL,
170 REGION_RQGEOM_WEAK_ALL, &fp);
171 region_fitrep(st->reg, NULL, &fp);
177 const char *groupcw_displayname(WGroupCW *cwg)
179 const char *name=NULL;
181 if(cwg->grp.bottom!=NULL && cwg->grp.bottom->reg!=NULL)
182 name=region_name(cwg->grp.bottom->reg);
185 name=region_name((WRegion*)cwg);
191 void groupcw_managed_notify(WGroupCW *cwg, WRegion *reg, WRegionNotify how)
193 if(group_bottom(&cwg->grp)==reg && how==ioncore_g.notifies.name){
194 /* Title has changed */
195 region_notify_change((WRegion*)cwg, how);
198 group_managed_notify(&cwg->grp, reg, how);
202 void groupcw_bottom_set(WGroupCW *cwg)
204 region_notify_change((WRegion*)cwg, ioncore_g.notifies.name);
211 /*{{{ WGroupCW class */
214 bool groupcw_init(WGroupCW *cwg, WWindow *parent, const WFitParams *fp)
216 cwg->transient_szplcy=DFLT_SZPLCY;
218 if(!group_init(&(cwg->grp), parent, fp))
221 region_add_bindmap((WRegion*)cwg, ioncore_groupcw_bindmap);
227 WGroupCW *create_groupcw(WWindow *parent, const WFitParams *fp)
229 CREATEOBJ_IMPL(WGroupCW, groupcw, (p, parent, fp));
233 void groupcw_deinit(WGroupCW *cwg)
235 group_deinit(&(cwg->grp));
239 WRegion *groupcw_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
242 ExtlTab substab, subtab;
245 ws=create_groupcw(par, fp);
250 if(!extl_table_gets_t(tab, "managed", &substab))
253 n=extl_table_get_n(substab);
255 if(extl_table_geti_t(substab, i, &subtab)){
256 group_attach_new(&ws->grp, subtab);
257 extl_unref_table(subtab);
261 extl_unref_table(substab);
263 if(ws->grp.managed_list==NULL){
264 destroy_obj((Obj*)ws);
272 static DynFunTab groupcw_dynfuntab[]={
273 {(DynFun*)region_prepare_manage,
274 (DynFun*)groupcw_prepare_manage},
276 {(DynFun*)region_prepare_manage_transient,
277 (DynFun*)groupcw_prepare_manage_transient},
280 {(DynFun*)region_handle_drop,
281 (DynFun*)groupcw_handle_drop},
283 {(DynFun*)group_do_add_managed,
284 (DynFun*)groupcw_do_add_managed},
288 {(DynFun*)region_get_rescue_pholder_for,
289 (DynFun*)groupcw_get_rescue_pholder_for},
292 {(DynFun*)region_prepare_manage,
293 (DynFun*)groupcw_prepare_manage},
295 {(DynFun*)region_prepare_manage_transient,
296 (DynFun*)groupcw_prepare_manage_transient},
298 {(DynFun*)region_managed_disposeroot,
299 (DynFun*)groupcw_managed_disposeroot},
301 {(DynFun*)region_displayname,
302 (DynFun*)groupcw_displayname},
304 {region_managed_notify,
305 groupcw_managed_notify},
315 IMPLCLASS(WGroupCW, WGroup, groupcw_deinit, groupcw_dynfuntab);