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.
19 #include "clientwin.h"
30 static WRegion *doit_new(WRegion *mgr,
31 WWindow *par, const WFitParams *fp,
32 WRegionDoAttachFn *cont, void *cont_param,
33 WRegionCreateFn *fn, void *fn_param)
35 WRegion *reg=fn(par, fp, fn_param);
40 if(!cont(mgr, reg, cont_param)){
41 destroy_obj((Obj*)reg);
49 static WRegion *doit_reparent(WRegion *mgr,
50 WWindow *par, const WFitParams *fp,
51 WRegionDoAttachFn *cont, void *cont_param,
57 if(!region_ancestor_check(mgr, reg)){
58 warn(TR("Attempt to make region %s manage its ancestor %s."),
59 region_name(mgr), region_name(reg));
63 disposeroot=region_disposeroot(reg);
65 if(disposeroot==NULL){
66 /* Region may not be reparented */
70 if(fp->mode®ION_FIT_WHATEVER){
71 /* fp->g is not final; substitute size with current to avoid
77 fp2.g.w=REGION_GEOM(reg).w;
78 fp2.g.h=REGION_GEOM(reg).h;
82 if(!region_fitrep(reg, par, fp)){
83 warn(TR("Unable to reparent."));
87 region_detach_manager(reg);
89 if(!cont(mgr, reg, cont_param)){
90 WScreen *scr=region_screen_of(reg);
92 warn(TR("Unexpected attach error: "
93 "trying to recover by attaching to screen."));
96 /* Try to attach to screen, to have `reg` attached at least
97 * somewhere. For better recovery, we could try to get
98 * a placeholder for `reg` before we detach it, but this
99 * would add unnecessary overhead in the usual succesfull
100 * case. (This failure is supposed to be _very_ rare!)
101 * We intentionally also do not region_postdetach_dispose
104 int flags=(region_may_control_focus(reg)
105 ? MPLEX_ATTACH_SWITCHTO
107 if(mplex_attach_simple(&scr->mplex, reg, flags)!=NULL)
111 warn(TR("Failed recovery."));
116 region_postdetach_dispose(reg, disposeroot);
122 static WRegion *wrap_load(WWindow *par, const WFitParams *fp,
125 return create_region_load(par, fp, *tab);
129 WRegion *ioncore_newly_created=NULL;
132 static WRegion *doit_load(WRegion *mgr,
133 WWindow *par, const WFitParams *fp,
134 WRegionDoAttachFn *cont, void *cont_param,
139 if(extl_table_gets_o(tab, "reg", (Obj**)®)){
140 if(!OBJ_IS(reg, WRegion))
142 }/*else if(extl_table_is_bool_set(tab, "reg_use_new")){
143 reg=ioncore_newly_created;
149 return doit_reparent(mgr, par, fp, cont, cont_param, reg);
151 return doit_new(mgr, par, fp, cont, cont_param,
152 (WRegionCreateFn*)wrap_load, &tab);
156 WRegion *region_attach_helper(WRegion *mgr,
157 WWindow *par, const WFitParams *fp,
158 WRegionDoAttachFn *fn, void *fn_param,
159 const WRegionAttachData *data)
161 if(data->type==REGION_ATTACH_NEW){
162 return doit_new(mgr, par, fp, fn, fn_param,
163 data->u.n.fn, data->u.n.param);
164 }else if(data->type==REGION_ATTACH_LOAD){
165 return doit_load(mgr, par, fp, fn, fn_param, data->u.tab);
166 }else if(data->type==REGION_ATTACH_REPARENT){
167 return doit_reparent(mgr, par, fp, fn, fn_param, data->u.reg);
177 /*{{{ Reparent check etc. */
180 bool region_ancestor_check(WRegion *dst, WRegion *reg)
184 /* Check that reg is not a parent or manager of mgr */
185 for(reg2=dst; reg2!=NULL; reg2=REGION_MANAGER(reg2)){
190 for(reg2=REGION_PARENT_REG(dst); reg2!=NULL; reg2=REGION_PARENT_REG(reg2)){
199 void region_postdetach_dispose(WRegion *reg, WRegion *disposeroot)
201 /* disposeroot should be destroyed (as empty and useless) unless it
202 * still, in fact, is an ancestor of reg.
204 if(disposeroot!=reg && region_ancestor_check(reg, disposeroot))
205 region_dispose(disposeroot);