X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=ioncore%2Fregion.c;h=47f8f5c3d93fd09feef16123a485929a8a7fd285;hp=68be25d32e8695ecaeb7ae0b62ac5388e4afea2d;hb=e3aec18706513a87eaa7839dfdaf7e0fcd0d8d2a;hpb=803afbc1cd633f6c025bcd9537e9b7e9aedadd0d diff --git a/ioncore/region.c b/ioncore/region.c index 68be25d..47f8f5c 100644 --- a/ioncore/region.c +++ b/ioncore/region.c @@ -1,12 +1,9 @@ /* * ion/ioncore/region.c * - * Copyright (c) Tuomo Valkonen 1999-2007. + * Copyright (c) Tuomo Valkonen 1999-2009. * - * Ion is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. + * See the included file LICENSE for details. */ #include @@ -27,6 +24,7 @@ #include "activity.h" #include "region-iter.h" #include "return.h" +#include "key.h" #define D2(X) @@ -112,7 +110,9 @@ void region_deinit(WRegion *reg) D(warn("Region to be focused next destroyed[1].")); ioncore_g.focus_next=NULL; } - + + assert(reg->submapstat==NULL); + /*region_free_submapstat(reg);*/ region_detach_manager(reg); region_unset_return(reg); region_unset_parent(reg); @@ -152,12 +152,14 @@ void region_updategr(WRegion *reg) void region_map(WRegion *reg) { CALL_DYN(region_map, reg, (reg)); + region_notify_change_(reg, ioncore_g.notifies.map); } void region_unmap(WRegion *reg) { CALL_DYN(region_unmap, reg, (reg)); + region_notify_change_(reg, ioncore_g.notifies.unmap); } @@ -233,7 +235,7 @@ void region_managed_remove(WRegion *mgr, WRegion *reg) /*EXTL_DOC - * Return the object, if any, that is considered ''currently active'' + * Return the object, if any, that is considered ``currently active'' * within the objects managed by \var{mplex}. */ EXTL_SAFE @@ -280,14 +282,13 @@ void region_updategr_default(WRegion *reg) bool region_prepare_focus(WRegion *reg, int flags, WPrepareFocusResult *res) { - WRegion *mgr=REGION_MANAGER(reg); - WRegion *par=REGION_PARENT_REG(reg); - if(REGION_IS_MAPPED(reg) && region_may_control_focus(reg)){ - res->reg=reg; - res->flags=0; - return TRUE; - }else{ + if(TRUE /* !REGION_IS_ACTIVE(reg) || + !REGION_IS_MAPPED(reg) || + ioncore_g.focus_next!=NULL*/){ + WRegion *mgr=REGION_MANAGER(reg); + WRegion *par=REGION_PARENT_REG(reg); + if(mgr!=NULL){ return region_managed_prepare_focus(mgr, reg, flags, res); }else if(par!=NULL){ @@ -296,11 +297,14 @@ bool region_prepare_focus(WRegion *reg, int flags, /* Just focus reg, if it has no manager, and parent can be * focused. */ + }else if(!REGION_IS_MAPPED(reg)){ + region_map(reg); } - res->reg=reg; - res->flags=flags; - return TRUE; } + + res->reg=reg; + res->flags=flags; + return TRUE; } @@ -366,32 +370,10 @@ bool region_reparent(WRegion *reg, WWindow *par, /*{{{ Close */ -static bool region_rqclose_default(WRegion *reg, bool relocate) +static void region_rqclose_default(WRegion *reg, bool relocate) { - WPHolder *ph; - bool refuse=TRUE, mcf; - - if((!relocate && !region_may_destroy(reg)) || - !region_manager_allows_destroying(reg)){ - return FALSE; - } - - ph=region_get_rescue_pholder(reg); - mcf=region_may_control_focus(reg); - - if(ph!=NULL){ - refuse=!region_rescue_clientwins(reg, ph); - destroy_obj((Obj*)ph); - } - - if(refuse){ - warn(TR("Failed to rescue some client windows - not closing.")); - return FALSE; - } - - region_dispose(reg, mcf); - - return TRUE; + if(relocate || region_may_dispose(reg)) + region_defer_rqdispose(reg); } @@ -400,19 +382,16 @@ static bool region_rqclose_default(WRegion *reg, bool relocate) * depends on whether the particular type of region in question has * implemented the feature and, in case of client windows, whether * the client supports the \code{WM_DELETE} protocol (see also - * \fnref{WClientWin.kill}). If the operation is likely to succeed, - * \code{true} is returned, otherwise \code{false}. In most cases the - * region will not have been actually destroyed when this function returns. - * If \var{relocate} is not set, and \var{reg} manages other regions, it - * will not be closed. Otherwise the managed regions will be attempted - * to be relocated. + * \fnref{WClientWin.kill}). The region will not be destroyed when + * this function returns. To find out if and when it is destroyed, + * use the \codestr{deinit} notification. If \var{relocate} is not set, + * and \var{reg} manages other regions, it will not be closed. Otherwise + * the managed regions will be attempted to be relocated. */ EXTL_EXPORT_MEMBER -bool region_rqclose(WRegion *reg, bool relocate) +void region_rqclose(WRegion *reg, bool relocate) { - bool ret=FALSE; - CALL_DYN_RET(ret, bool, region_rqclose, reg, (reg, relocate)); - return ret; + CALL_DYN(region_rqclose, reg, (reg, relocate)); } @@ -421,9 +400,13 @@ static WRegion *region_rqclose_propagate_default(WRegion *reg, { if(maybe_sub==NULL) maybe_sub=region_current(reg); - if(maybe_sub!=NULL) + + if(maybe_sub!=NULL){ return region_rqclose_propagate(maybe_sub, NULL); - return (region_rqclose(reg, FALSE) ? reg : NULL); + }else{ + region_rqclose(reg, FALSE); + return reg; + } } @@ -431,8 +414,8 @@ static WRegion *region_rqclose_propagate_default(WRegion *reg, * Recursively attempt to close a region or one of the regions managed by * it. If \var{sub} is set, it will be used as the managed region, otherwise * \fnref{WRegion.current}\code{(reg)}. The object to be closed is - * returned or NULL if nothing can be closed. Also see notes for - * \fnref{WRegion.rqclose}. + * returned, or NULL if nothing can be closed. For further details, see + * notes for \fnref{WRegion.rqclose}. */ EXTL_EXPORT_MEMBER WRegion *region_rqclose_propagate(WRegion *reg, WRegion *maybe_sub) @@ -444,48 +427,104 @@ WRegion *region_rqclose_propagate(WRegion *reg, WRegion *maybe_sub) } -bool region_may_destroy(WRegion *reg) +bool region_may_dispose_default(WRegion *reg) +{ + bool res=region_rescue_needed(reg); + + if(res){ + const char *name=region_name(reg); + warn(TR("Can not destroy %s: contains client windows."), + (name!=NULL ? name : TR("(unknown)"))); + } + + return !res; +} + + +bool region_may_dispose(WRegion *reg) { bool ret=TRUE; - CALL_DYN_RET(ret, bool, region_may_destroy, reg, (reg)); + CALL_DYN_RET(ret, bool, region_may_dispose, reg, (reg)); return ret; } -bool region_managed_may_destroy(WRegion *mgr, WRegion *reg) +static WRegion *region_managed_disposeroot_default(WRegion *mgr, WRegion *reg) { - bool ret=TRUE; - CALL_DYN_RET(ret, bool, region_managed_may_destroy, mgr, (mgr, reg)); + return reg; +} + + +WRegion *region_managed_disposeroot(WRegion *mgr, WRegion *reg) +{ + WRegion *ret=NULL; + CALL_DYN_RET(ret, WRegion*, region_managed_disposeroot, mgr, (mgr, reg)); return ret; } -bool region_manager_allows_destroying(WRegion *reg) +WRegion *region_disposeroot(WRegion *reg) { WRegion *mgr=REGION_MANAGER(reg); - if(mgr==NULL) - return TRUE; + return (mgr!=NULL + ? region_managed_disposeroot(mgr, reg) + : reg); +} + + +bool region_rqdispose(WRegion *reg) +{ + WRegion *root; - return region_managed_may_destroy(mgr, reg); + if(!region_may_dispose(reg)) + return FALSE; + + root=region_disposeroot(reg); + + if(root==NULL) + return FALSE; + + return region_dispose(root); } -void region_dispose(WRegion *reg, bool was_mcf) +bool region_dispose_(WRegion *reg, bool not_simple) { - if(was_mcf){ - WPHolder *ph=region_get_return(reg); - if(ph!=NULL) - pholder_goto(ph); + bool rescue=not_simple; + bool was_mcf=(not_simple && region_may_control_focus(reg)); + WPHolder *ph=NULL; + + if(rescue){ + if(!region_rescue(reg, NULL, 0)){ + warn(TR("Failed to rescue some client windows - not closing.")); + return FALSE; + } + } + + if(was_mcf) + ph=region_unset_get_return(reg); + + destroy_obj((Obj*)reg); + + if(ph!=NULL){ + pholder_goto(ph); + destroy_obj((Obj*)ph); } + + return TRUE; +} + - mainloop_defer_destroy((Obj*)reg); +bool region_dispose(WRegion *reg) +{ + return region_dispose_(reg, TRUE); } -void region_dispose_(WRegion *reg) +void region_defer_rqdispose(WRegion *reg) { - region_dispose(reg, region_may_control_focus(reg)); + mainloop_defer_action((Obj*)reg, (WDeferredAction*)region_rqdispose); } @@ -498,29 +537,11 @@ void region_dispose_(WRegion *reg) /* Routine to call to unmanage a region */ void region_detach_manager(WRegion *reg) { - WRegion *mgr; - - mgr=REGION_MANAGER(reg); + WRegion *mgr=REGION_MANAGER(reg); if(mgr==NULL) return; -#if 0 - /* Restore activity state to non-parent manager */ - if(region_may_control_focus(reg)){ - WRegion *par=REGION_PARENT_REG(reg); - if(par!=NULL && mgr!=par && REGION_PARENT_REG(mgr)==par){ - /* REGION_ACTIVE shouldn't be set for windowless regions - * but make the parent's active_sub point to it - * nevertheless so that region_may_control_focus can - * be made to work. - */ - par->active_sub=mgr; - region_maybewarp_now(mgr, FALSE); - } - } -#endif - region_set_activity(reg, SETPARAM_UNSET); region_managed_remove(mgr, reg); @@ -577,6 +598,9 @@ void region_unset_manager(WRegion *reg, WRegion *mgr) reg->manager=NULL; + /* Reset status, as it is set by manager */ + reg->flags&=~REGION_SKIP_FOCUS; + if(region_is_activity_r(reg)) region_clear_mgd_activity(mgr); @@ -723,7 +747,7 @@ bool region_rqorder(WRegion *reg, WRegionOrder order) /*EXTL_DOC * Request ordering. Currently supported values for \var{ord} - * are 'front' and 'back'. + * are \codestr{front} and \codestr{back}. */ EXTL_EXPORT_AS(WRegion, rqorder) bool region_rqorder_extl(WRegion *reg, const char *ord) @@ -929,6 +953,9 @@ static DynFunTab region_dynfuntab[]={ {(DynFun*)region_rescue_clientwins, (DynFun*)region_rescue_child_clientwins}, + + {(DynFun*)region_may_dispose, + (DynFun*)region_may_dispose_default}, {(DynFun*)region_prepare_manage, (DynFun*)region_prepare_manage_default}, @@ -938,6 +965,9 @@ static DynFunTab region_dynfuntab[]={ {(DynFun*)region_managed_prepare_focus, (DynFun*)region_managed_prepare_focus_default}, + + {(DynFun*)region_managed_disposeroot, + (DynFun*)region_managed_disposeroot_default}, {(DynFun*)region_rqclose_propagate, (DynFun*)region_rqclose_propagate_default},