2 * ion/ioncore/grouppholder.c
4 * Copyright (c) Tuomo Valkonen 2005-2008.
6 * See the included file LICENSE for details.
9 #include <libtu/objp.h>
10 #include <libtu/obj.h>
11 #include <libtu/pointer.h>
12 #include <libmainloop/defer.h>
14 #include <ioncore/common.h>
17 #include "grouppholder.h"
20 static void group_watch_handler(Watch *watch, Obj *ws);
26 void grouppholder_do_link(WGroupPHolder *ph, WGroup *group, WRegion *stack_above)
31 LINK_ITEM_FIRST(group->phs, ph, next, prev);
33 /* This seems very crucial for detached pholders... */
38 /* We must move stack_above pointer into a Watch. */
40 watch_setup(&(ph->stack_above_watch), (Obj*)stack_above, NULL);
44 static WGroupPHolder *get_head(WGroupPHolder *ph)
47 /* ph->prev==NULL should not happen.. */
48 if(ph->prev==NULL || ph->prev->next==NULL)
57 void grouppholder_do_unlink(WGroupPHolder *ph)
59 WGroup *group=ph->group;
61 watch_reset(&(ph->stack_above_watch));
63 if(ph->recreate_pholder!=NULL){
65 ph->next->recreate_pholder=ph->recreate_pholder;
67 /* It might be in use in attach chain! So defer. */
68 mainloop_defer_destroy((Obj*)ph->recreate_pholder);
70 ph->recreate_pholder=NULL;
74 UNLINK_ITEM(group->phs, ph, next, prev);
76 WGroupPHolder *next=ph->next;
83 assert(next->prev==ph);
99 static WGroupAttachParams dummy_param=GROUPATTACHPARAMS_INIT;
102 bool grouppholder_init(WGroupPHolder *ph, WGroup *ws,
104 const WGroupAttachParams *param)
106 WRegion *stack_above=NULL;
108 pholder_init(&(ph->ph));
110 watch_init(&(ph->stack_above_watch));
114 ph->recreate_pholder=NULL;
115 ph->param=(param==NULL ? dummy_param : *param);
118 /* TODO? Just link to the stacking structure to remember
122 ph->param.szplcy_set=TRUE;
123 ph->param.szplcy=st->szplcy;
124 ph->param.level_set=TRUE;
125 ph->param.level=st->level;
128 ph->param.geom_set=TRUE;
129 ph->param.geom=REGION_GEOM(st->reg);
132 if(st->above!=NULL && st->above->reg!=NULL)
133 ph->param.stack_above=st->above->reg;
135 ph->param.bottom=(st==ws->bottom);
138 ph->param.switchto_set=FALSE;
140 stack_above=ph->param.stack_above;
141 ph->param.stack_above=NULL;
143 grouppholder_do_link(ph, ws, stack_above);
149 WGroupPHolder *create_grouppholder(WGroup *ws,
151 const WGroupAttachParams *param)
153 CREATEOBJ_IMPL(WGroupPHolder, grouppholder, (p, ws, st, param));
157 void grouppholder_deinit(WGroupPHolder *ph)
159 grouppholder_do_unlink(ph);
161 pholder_deinit(&(ph->ph));
171 static WPHolder *get_recreate_ph(WGroupPHolder *ph)
173 return get_head(ph)->recreate_pholder;
178 WGroupPHolder *ph, *ph_head;
179 WRegionAttachData *data;
184 static WRegion *recreate_handler(WWindow *par,
185 const WFitParams *fp,
188 WGroupPHolder *phtmp;
192 grp=(WGroup*)create_groupcw(par, fp);
197 rp->reg_ret=group_do_attach(grp, &rp->ph->param, rp->data);
199 if(rp->reg_ret==NULL){
200 destroy_obj((Obj*)grp);
203 grp->phs=rp->ph_head;
205 for(phtmp=grp->phs; phtmp!=NULL; phtmp=phtmp->next)
209 return (WRegion*)grp;
214 static WRegion *grouppholder_attach_recreate(WGroupPHolder *ph, int flags,
215 WRegionAttachData *data)
217 WRegionAttachData data2;
218 WPHolder *root, *rph;
222 rp.ph_head=get_head(ph);
224 assert(rp.ph_head!=NULL);
226 rph=rp.ph_head->recreate_pholder;
235 data2.type=REGION_ATTACH_NEW;
236 data2.u.n.fn=recreate_handler;
239 grp=(WGroup*)pholder_do_attach(rph, flags, &data2);
242 assert(OBJ_IS(grp, WGroup));
243 rp.ph_head->recreate_pholder=NULL;
244 /* It might be in use in attach chain! So defer. */
245 mainloop_defer_destroy((Obj*)rph);
252 WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags,
253 WRegionAttachData *data)
255 WGroup *ws=ph->group;
259 return grouppholder_attach_recreate(ph, flags, data);
261 ph->param.switchto_set=1;
262 ph->param.switchto=(flags&PHOLDER_ATTACH_SWITCHTO ? 1 : 0);
264 /* Get stack_above from Watch. */
265 ph->param.stack_above=(WRegion*)ph->stack_above_watch.obj;
267 reg=group_do_attach(ws, &ph->param, data);
269 ph->param.stack_above=NULL;
275 bool grouppholder_do_goto(WGroupPHolder *ph)
277 return (ph->group!=NULL
278 ? region_goto((WRegion*)ph->group)
279 : (ph->recreate_pholder!=NULL
280 ? pholder_do_goto(ph->recreate_pholder)
285 WRegion *grouppholder_do_target(WGroupPHolder *ph)
287 return (ph->group!=NULL
288 ? (WRegion*)ph->group
289 : (ph->recreate_pholder!=NULL
290 ? pholder_do_target(ph->recreate_pholder)
298 /*{{{ WGroup stuff */
301 WGroupPHolder *group_managed_get_pholder(WGroup *ws, WRegion *mgd)
303 WStacking *st=group_find_stacking(ws, mgd);
308 return create_grouppholder(ws, st, NULL);
315 /*{{{ Class information */
318 static DynFunTab grouppholder_dynfuntab[]={
319 {(DynFun*)pholder_do_attach,
320 (DynFun*)grouppholder_do_attach},
322 {(DynFun*)pholder_do_goto,
323 (DynFun*)grouppholder_do_goto},
325 {(DynFun*)pholder_do_target,
326 (DynFun*)grouppholder_do_target},
331 IMPLCLASS(WGroupPHolder, WPHolder, grouppholder_deinit,
332 grouppholder_dynfuntab);