4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
16 #include "clientwin.h"
22 #include "screen-notify.h"
28 static WRegion
*doit_new(WRegion
*mgr
,
29 WWindow
*par
, const WFitParams
*fp
,
30 WRegionDoAttachFn
*cont
, void *cont_param
,
31 WRegionCreateFn
*fn
, void *fn_param
)
33 WRegion
*reg
=fn(par
, fp
, fn_param
);
38 if(!cont(mgr
, reg
, cont_param
)){
39 destroy_obj((Obj
*)reg
);
47 static WRegion
*doit_reparent(WRegion
*mgr
,
48 WWindow
*par
, const WFitParams
*fp
,
49 WRegionDoAttachFn
*cont
, void *cont_param
,
54 WScreen
*old_scr
=region_screen_of(reg
);
56 if(!region_ancestor_check(mgr
, reg
)){
57 warn(TR("Attempt to make region %s manage its ancestor %s."),
58 region_name(mgr
), region_name(reg
));
62 disposeroot
=region_disposeroot(reg
);
64 if(disposeroot
==NULL
){
65 /* Region may not be reparented */
69 if(fp
->mode
®ION_FIT_WHATEVER
){
70 /* fp->g is not final; substitute size with current to avoid
76 fp2
.g
.w
=REGION_GEOM(reg
).w
;
77 fp2
.g
.h
=REGION_GEOM(reg
).h
;
81 if(!region_fitrep(reg
, par
, fp
)){
82 warn(TR("Unable to reparent."));
86 region_detach_manager(reg
);
89 screen_update_notifywin(old_scr
);
91 ioncore_screen_activity_notify(reg
, ioncore_g
.notifies
.activity
);
93 if(!cont(mgr
, reg
, cont_param
)){
94 WScreen
*scr
=region_screen_of(reg
);
96 warn(TR("Unexpected attach error: "
97 "trying to recover by attaching to screen."));
100 /* Try to attach to screen, to have `reg` attached at least
101 * somewhere. For better recovery, we could try to get
102 * a placeholder for `reg` before we detach it, but this
103 * would add unnecessary overhead in the usual succesfull
104 * case. (This failure is supposed to be _very_ rare!)
105 * We intentionally also do not region_postdetach_dispose
108 int flags
=(region_may_control_focus(reg
)
109 ? MPLEX_ATTACH_SWITCHTO
111 if(mplex_attach_simple(&scr
->mplex
, reg
, flags
)!=NULL
)
115 warn(TR("Failed recovery."));
120 region_postdetach_dispose(reg
, disposeroot
);
131 static WRegion
*wrap_load(WWindow
*par
, const WFitParams
*fp
, WLP
*p
)
133 return create_region_load(par
, fp
, p
->tab
, p
->sm_ph_p
);
137 WRegion
*ioncore_newly_created
=NULL
;
140 static WRegion
*doit_load(WRegion
*mgr
,
141 WWindow
*par
, const WFitParams
*fp
,
142 WRegionDoAttachFn
*cont
, void *cont_param
,
143 ExtlTab tab
, WPHolder
**sm_ph
)
147 if(extl_table_gets_o(tab
, "reg", (Obj
**)®
)){
148 if(!OBJ_IS(reg
, WRegion
))
150 }/*else if(extl_table_is_bool_set(tab, "reg_use_new")){
151 reg=ioncore_newly_created;
157 return doit_reparent(mgr
, par
, fp
, cont
, cont_param
, reg
);
163 return doit_new(mgr
, par
, fp
, cont
, cont_param
,
164 (WRegionCreateFn
*)wrap_load
, &p
);
169 WRegion
*region_attach_load_helper(WRegion
*mgr
,
170 WWindow
*par
, const WFitParams
*fp
,
171 WRegionDoAttachFn
*fn
, void *fn_param
,
172 ExtlTab tab
, WPHolder
**sm_ph
)
174 return doit_load(mgr
, par
, fp
, fn
, fn_param
, tab
, sm_ph
);
178 WRegion
*region_attach_helper(WRegion
*mgr
,
179 WWindow
*par
, const WFitParams
*fp
,
180 WRegionDoAttachFn
*fn
, void *fn_param
,
181 const WRegionAttachData
*data
)
183 if(data
->type
==REGION_ATTACH_NEW
){
184 return doit_new(mgr
, par
, fp
, fn
, fn_param
,
185 data
->u
.n
.fn
, data
->u
.n
.param
);
186 }else if(data
->type
==REGION_ATTACH_LOAD
){
187 return doit_load(mgr
, par
, fp
, fn
, fn_param
, data
->u
.tab
, NULL
);
188 }else if(data
->type
==REGION_ATTACH_REPARENT
){
189 return doit_reparent(mgr
, par
, fp
, fn
, fn_param
, data
->u
.reg
);
199 /*{{{ Reparent check etc. */
202 bool region_ancestor_check(WRegion
*dst
, WRegion
*reg
)
206 /* Check that reg is not a parent or manager of mgr */
207 for(reg2
=dst
; reg2
!=NULL
; reg2
=REGION_MANAGER(reg2
)){
212 for(reg2
=REGION_PARENT_REG(dst
); reg2
!=NULL
; reg2
=REGION_PARENT_REG(reg2
)){
221 void region_postdetach_dispose(WRegion
*reg
, WRegion
*disposeroot
)
223 /* disposeroot should be destroyed (as empty and useless) unless it
224 * still, in fact, is an ancestor of reg.
226 if(disposeroot
!=reg
&& region_ancestor_check(reg
, disposeroot
))
227 region_dispose(disposeroot
);