2 * ion/ioncore/group-cw.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
14 #include <libtu/objp.h>
15 #include <libmainloop/defer.h>
19 #include "clientwin.h"
26 #include "framedpholder.h"
27 #include "grouppholder.h"
30 #define DFLT_SZPLCY SIZEPOLICY_FREE_GLUE__SOUTH
33 /*{{{ Add/remove managed */
36 static WPHolder *groupcw_transient_pholder(WGroupCW *cwg,
37 const WClientWin *cwin,
38 const WManageParams *mp)
40 WGroupAttachParams param=GROUPATTACHPARAMS_INIT;
41 WFramedParam fp=FRAMEDPARAM_INIT;
45 param.level=STACKING_LEVEL_MODAL1;
48 param.szplcy=cwg->transient_szplcy;
53 param.geom_weak_set=1;
54 param.geom_weak=REGION_RQGEOM_WEAK_ALL;
56 if(!ioncore_g.framed_transients){
60 return (WPHolder*)create_grouppholder(&cwg->grp, NULL, ¶m);
62 fp.inner_geom_gravity_set=1;
63 fp.inner_geom=mp->geom;
64 fp.gravity=ForgetGravity;
65 fp.mode=FRAME_MODE_TRANSIENT;
67 ph=(WPHolder*)create_grouppholder(&cwg->grp, NULL, ¶m);
69 return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
74 WPHolder *groupcw_prepare_manage(WGroupCW *cwg, const WClientWin *cwin,
75 const WManageParams *param, int redir)
77 if(redir==MANAGE_REDIR_STRICT_YES)
80 /* Only catch windows with transient mode set to current here. */
81 if(clientwin_get_transient_mode(cwin)!=TRANSIENT_MODE_CURRENT)
84 return groupcw_transient_pholder(cwg, cwin, param);
88 static bool groupcw_should_manage_transient(WGroupCW *cwg,
93 if(group_find_stacking(&cwg->grp, (WRegion*)tfor))
96 mgr=REGION_MANAGER(tfor);
98 if(mgr!=NULL && ioncore_g.framed_transients && OBJ_IS(mgr, WFrame))
99 return (group_find_stacking(&cwg->grp, mgr)!=NULL);
105 WPHolder *groupcw_prepare_manage_transient(WGroupCW *cwg,
106 const WClientWin *transient,
107 const WManageParams *param,
110 WPHolder *ph=region_prepare_manage_transient_default((WRegion*)cwg,
115 if(ph==NULL && groupcw_should_manage_transient(cwg, param->tfor))
116 ph=groupcw_transient_pholder(cwg, transient, param);
129 * Toggle transients managed by \var{cwin} between top/bottom
133 void groupcw_toggle_transients_pos(WGroupCW *cwg)
138 if((cwg->transient_szplcy&SIZEPOLICY_VERT_MASK)==SIZEPOLICY_VERT_TOP){
139 cwg->transient_szplcy&=~SIZEPOLICY_VERT_MASK;
140 cwg->transient_szplcy|=SIZEPOLICY_VERT_BOTTOM;
142 cwg->transient_szplcy&=~SIZEPOLICY_VERT_MASK;
143 cwg->transient_szplcy|=SIZEPOLICY_VERT_TOP;
146 FOR_ALL_NODES_IN_GROUP(&cwg->grp, st, tmp){
147 st->szplcy&=~SIZEPOLICY_VERT_MASK;
148 st->szplcy|=(cwg->transient_szplcy&SIZEPOLICY_VERT_MASK);
153 fp.g=REGION_GEOM(cwg);
155 sizepolicy(&st->szplcy, st->reg, NULL,
156 REGION_RQGEOM_WEAK_ALL, &fp);
157 region_fitrep(st->reg, NULL, &fp);
163 const char *groupcw_displayname(WGroupCW *cwg)
165 const char *name=NULL;
167 if(cwg->grp.bottom!=NULL && cwg->grp.bottom->reg!=NULL)
168 name=region_name(cwg->grp.bottom->reg);
171 name=region_name((WRegion*)cwg);
177 void groupcw_managed_notify(WGroupCW *cwg, WRegion *reg, WRegionNotify how)
179 if(group_bottom(&cwg->grp)==reg && how==ioncore_g.notifies.name){
180 /* Title has changed */
181 region_notify_change((WRegion*)cwg, how);
184 group_managed_notify(&cwg->grp, reg, how);
191 /*{{{ WGroupCW class */
194 bool groupcw_init(WGroupCW *cwg, WWindow *parent, const WFitParams *fp)
196 cwg->transient_szplcy=DFLT_SZPLCY;
198 if(!group_init(&(cwg->grp), parent, fp))
201 region_add_bindmap((WRegion*)cwg, ioncore_groupcw_bindmap);
207 WGroupCW *create_groupcw(WWindow *parent, const WFitParams *fp)
209 CREATEOBJ_IMPL(WGroupCW, groupcw, (p, parent, fp));
213 void groupcw_deinit(WGroupCW *cwg)
215 group_deinit(&(cwg->grp));
219 WRegion *groupcw_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
222 ExtlTab substab, subtab;
225 ws=create_groupcw(par, fp);
230 if(!extl_table_gets_t(tab, "managed", &substab))
233 n=extl_table_get_n(substab);
235 if(extl_table_geti_t(substab, i, &subtab)){
236 group_attach_new(&ws->grp, subtab);
237 extl_unref_table(subtab);
241 extl_unref_table(substab);
243 if(ws->grp.managed_list==NULL){
244 destroy_obj((Obj*)ws);
252 static DynFunTab groupcw_dynfuntab[]={
253 {(DynFun*)region_prepare_manage,
254 (DynFun*)groupcw_prepare_manage},
256 {(DynFun*)region_prepare_manage_transient,
257 (DynFun*)groupcw_prepare_manage_transient},
260 {(DynFun*)region_handle_drop,
261 (DynFun*)groupcw_handle_drop},
263 {(DynFun*)group_do_add_managed,
264 (DynFun*)groupcw_do_add_managed},
268 {(DynFun*)region_get_rescue_pholder_for,
269 (DynFun*)groupcw_get_rescue_pholder_for},
272 {(DynFun*)region_prepare_manage,
273 (DynFun*)groupcw_prepare_manage},
275 {(DynFun*)region_prepare_manage_transient,
276 (DynFun*)groupcw_prepare_manage_transient},
278 {(DynFun*)region_displayname,
279 (DynFun*)groupcw_displayname},
281 {region_managed_notify,
282 groupcw_managed_notify},
289 IMPLCLASS(WGroupCW, WGroup, groupcw_deinit, groupcw_dynfuntab);