4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
16 #include "clientwin.h"
27 static WRegion
*doit_new(WRegion
*mgr
,
28 WWindow
*par
, const WFitParams
*fp
,
29 WRegionDoAttachFn
*cont
, void *cont_param
,
30 WRegionCreateFn
*fn
, void *fn_param
)
32 WRegion
*reg
=fn(par
, fp
, fn_param
);
37 if(!cont(mgr
, reg
, cont_param
)){
38 destroy_obj((Obj
*)reg
);
46 static WRegion
*doit_reparent(WRegion
*mgr
,
47 WWindow
*par
, const WFitParams
*fp
,
48 WRegionDoAttachFn
*cont
, void *cont_param
,
54 if(!region_ancestor_check(mgr
, reg
)){
55 warn(TR("Attempt to make region %s manage its ancestor %s."),
56 region_name(mgr
), region_name(reg
));
60 disposeroot
=region_disposeroot(reg
);
62 if(disposeroot
==NULL
){
63 /* Region may not be reparented */
67 if(fp
->mode
®ION_FIT_WHATEVER
){
68 /* fp->g is not final; substitute size with current to avoid
74 fp2
.g
.w
=REGION_GEOM(reg
).w
;
75 fp2
.g
.h
=REGION_GEOM(reg
).h
;
79 if(!region_fitrep(reg
, par
, fp
)){
80 warn(TR("Unable to reparent."));
84 region_detach_manager(reg
);
86 if(!cont(mgr
, reg
, cont_param
)){
87 WScreen
*scr
=region_screen_of(reg
);
89 warn(TR("Unexpected attach error: "
90 "trying to recover by attaching to screen."));
93 /* Try to attach to screen, to have `reg` attached at least
94 * somewhere. For better recovery, we could try to get
95 * a placeholder for `reg` before we detach it, but this
96 * would add unnecessary overhead in the usual succesfull
97 * case. (This failure is supposed to be _very_ rare!)
98 * We intentionally also do not region_postdetach_dispose
101 int flags
=(region_may_control_focus(reg
)
102 ? MPLEX_ATTACH_SWITCHTO
104 if(mplex_attach_simple(&scr
->mplex
, reg
, flags
)!=NULL
)
108 warn(TR("Failed recovery."));
113 region_postdetach_dispose(reg
, disposeroot
);
124 static WRegion
*wrap_load(WWindow
*par
, const WFitParams
*fp
, WLP
*p
)
126 return create_region_load(par
, fp
, p
->tab
, p
->sm_ph_p
);
130 WRegion
*ioncore_newly_created
=NULL
;
133 static WRegion
*doit_load(WRegion
*mgr
,
134 WWindow
*par
, const WFitParams
*fp
,
135 WRegionDoAttachFn
*cont
, void *cont_param
,
136 ExtlTab tab
, WPHolder
**sm_ph
)
140 if(extl_table_gets_o(tab
, "reg", (Obj
**)®
)){
141 if(!OBJ_IS(reg
, WRegion
))
143 }/*else if(extl_table_is_bool_set(tab, "reg_use_new")){
144 reg=ioncore_newly_created;
150 return doit_reparent(mgr
, par
, fp
, cont
, cont_param
, reg
);
156 return doit_new(mgr
, par
, fp
, cont
, cont_param
,
157 (WRegionCreateFn
*)wrap_load
, &p
);
162 WRegion
*region_attach_load_helper(WRegion
*mgr
,
163 WWindow
*par
, const WFitParams
*fp
,
164 WRegionDoAttachFn
*fn
, void *fn_param
,
165 ExtlTab tab
, WPHolder
**sm_ph
)
167 return doit_load(mgr
, par
, fp
, fn
, fn_param
, tab
, sm_ph
);
171 WRegion
*region_attach_helper(WRegion
*mgr
,
172 WWindow
*par
, const WFitParams
*fp
,
173 WRegionDoAttachFn
*fn
, void *fn_param
,
174 const WRegionAttachData
*data
)
176 if(data
->type
==REGION_ATTACH_NEW
){
177 return doit_new(mgr
, par
, fp
, fn
, fn_param
,
178 data
->u
.n
.fn
, data
->u
.n
.param
);
179 }else if(data
->type
==REGION_ATTACH_LOAD
){
180 return doit_load(mgr
, par
, fp
, fn
, fn_param
, data
->u
.tab
, NULL
);
181 }else if(data
->type
==REGION_ATTACH_REPARENT
){
182 return doit_reparent(mgr
, par
, fp
, fn
, fn_param
, data
->u
.reg
);
192 /*{{{ Reparent check etc. */
195 bool region_ancestor_check(WRegion
*dst
, WRegion
*reg
)
199 /* Check that reg is not a parent or manager of mgr */
200 for(reg2
=dst
; reg2
!=NULL
; reg2
=REGION_MANAGER(reg2
)){
205 for(reg2
=REGION_PARENT_REG(dst
); reg2
!=NULL
; reg2
=REGION_PARENT_REG(reg2
)){
214 void region_postdetach_dispose(WRegion
*reg
, WRegion
*disposeroot
)
216 /* disposeroot should be destroyed (as empty and useless) unless it
217 * still, in fact, is an ancestor of reg.
219 if(disposeroot
!=reg
&& region_ancestor_check(reg
, disposeroot
))
220 region_dispose(disposeroot
);