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);
75 }else if(ph->prev!=NULL){
76 WGroupPHolder *next=ph->next;
82 assert(next->prev==ph);
86 /* ph should not be on a list, if prev pointer is NULL (whereas
87 * next alone can be NULL in our semi-doubly-linked lists).
89 assert(ph->next==NULL);
103 static WGroupAttachParams dummy_param=GROUPATTACHPARAMS_INIT;
106 bool grouppholder_init(WGroupPHolder *ph, WGroup *ws,
108 const WGroupAttachParams *param)
110 WRegion *stack_above=NULL;
112 pholder_init(&(ph->ph));
114 watch_init(&(ph->stack_above_watch));
118 ph->recreate_pholder=NULL;
119 ph->param=(param==NULL ? dummy_param : *param);
122 /* TODO? Just link to the stacking structure to remember
126 ph->param.szplcy_set=TRUE;
127 ph->param.szplcy=st->szplcy;
128 ph->param.level_set=TRUE;
129 ph->param.level=st->level;
132 ph->param.geom_set=TRUE;
133 ph->param.geom=REGION_GEOM(st->reg);
136 if(st->above!=NULL && st->above->reg!=NULL)
137 ph->param.stack_above=st->above->reg;
139 ph->param.bottom=(st==ws->bottom);
142 ph->param.switchto_set=FALSE;
144 stack_above=ph->param.stack_above;
145 ph->param.stack_above=NULL;
147 grouppholder_do_link(ph, ws, stack_above);
153 WGroupPHolder *create_grouppholder(WGroup *ws,
155 const WGroupAttachParams *param)
157 CREATEOBJ_IMPL(WGroupPHolder, grouppholder, (p, ws, st, param));
161 void grouppholder_deinit(WGroupPHolder *ph)
163 grouppholder_do_unlink(ph);
165 pholder_deinit(&(ph->ph));
175 static WPHolder *get_recreate_ph(WGroupPHolder *ph)
177 return get_head(ph)->recreate_pholder;
182 WGroupPHolder *ph, *ph_head;
183 WRegionAttachData *data;
188 static WRegion *recreate_handler(WWindow *par,
189 const WFitParams *fp,
192 WGroupPHolder *phtmp;
196 grp=(WGroup*)create_groupcw(par, fp);
201 rp->reg_ret=group_do_attach(grp, &rp->ph->param, rp->data);
203 if(rp->reg_ret==NULL){
204 destroy_obj((Obj*)grp);
207 grp->phs=rp->ph_head;
209 for(phtmp=grp->phs; phtmp!=NULL; phtmp=phtmp->next)
213 return (WRegion*)grp;
218 static WRegion *grouppholder_attach_recreate(WGroupPHolder *ph, int flags,
219 WRegionAttachData *data)
221 WRegionAttachData data2;
222 WPHolder *root, *rph;
226 rp.ph_head=get_head(ph);
228 assert(rp.ph_head!=NULL);
230 rph=rp.ph_head->recreate_pholder;
239 data2.type=REGION_ATTACH_NEW;
240 data2.u.n.fn=recreate_handler;
243 grp=(WGroup*)pholder_do_attach(rph, flags, &data2);
246 assert(OBJ_IS(grp, WGroup));
247 rp.ph_head->recreate_pholder=NULL;
248 /* It might be in use in attach chain! So defer. */
249 mainloop_defer_destroy((Obj*)rph);
256 WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags,
257 WRegionAttachData *data)
259 WGroup *ws=ph->group;
263 return grouppholder_attach_recreate(ph, flags, data);
265 ph->param.switchto_set=1;
266 ph->param.switchto=(flags&PHOLDER_ATTACH_SWITCHTO ? 1 : 0);
268 /* Get stack_above from Watch. */
269 ph->param.stack_above=(WRegion*)ph->stack_above_watch.obj;
271 reg=group_do_attach(ws, &ph->param, data);
273 ph->param.stack_above=NULL;
279 bool grouppholder_do_goto(WGroupPHolder *ph)
281 return (ph->group!=NULL
282 ? region_goto((WRegion*)ph->group)
283 : (ph->recreate_pholder!=NULL
284 ? pholder_do_goto(ph->recreate_pholder)
289 WRegion *grouppholder_do_target(WGroupPHolder *ph)
291 return (ph->group!=NULL
292 ? (WRegion*)ph->group
293 : (ph->recreate_pholder!=NULL
294 ? pholder_do_target(ph->recreate_pholder)
302 /*{{{ WGroup stuff */
305 WGroupPHolder *group_managed_get_pholder(WGroup *ws, WRegion *mgd)
307 WStacking *st=group_find_stacking(ws, mgd);
312 return create_grouppholder(ws, st, NULL);
319 /*{{{ Class information */
322 static DynFunTab grouppholder_dynfuntab[]={
323 {(DynFun*)pholder_do_attach,
324 (DynFun*)grouppholder_do_attach},
326 {(DynFun*)pholder_do_goto,
327 (DynFun*)grouppholder_do_goto},
329 {(DynFun*)pholder_do_target,
330 (DynFun*)grouppholder_do_target},
335 IMPLCLASS(WGroupPHolder, WPHolder, grouppholder_deinit,
336 grouppholder_dynfuntab);