X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=ioncore%2Fmplex.c;h=5f0a87d3a5a8bd2cfe6786c42bd2ca32b977758c;hp=239d46f7e2134f012e9de16a01cf11859abbcfc7;hb=HEAD;hpb=720e6978185b09f2b2f60a6b96018238085a7238 diff --git a/ioncore/mplex.c b/ioncore/mplex.c index 239d46f..5f0a87d 100644 --- a/ioncore/mplex.c +++ b/ioncore/mplex.c @@ -1,7 +1,7 @@ /* * ion/ioncore/mplex.c * - * Copyright (c) Tuomo Valkonen 1999-2007. + * Copyright (c) Tuomo Valkonen 1999-2009. * * See the included file LICENSE for details. */ @@ -33,13 +33,13 @@ #include "saveload.h" #include "xwindow.h" #include "mplexpholder.h" +#include "grouppholder.h" #include "llist.h" #include "names.h" #include "sizepolicy.h" #include "stacking.h" #include "group.h" #include "navi.h" -#include "groupedpholder.h" #define SUBS_MAY_BE_MAPPED(MPLEX) \ @@ -98,7 +98,7 @@ bool mplex_do_init(WMPlex *mplex, WWindow *parent, mplex->mx_list=NULL; mplex->mx_current=NULL; - mplex->mx_phs=NULL; + mplex->misc_phs=NULL; mplex->mx_count=0; mplex->mgd=NULL; @@ -147,8 +147,8 @@ void mplex_deinit(WMPlex *mplex) assert(mplex->mgd==NULL); assert(mplex->mx_list==NULL); - while(mplex->mx_phs!=NULL){ - assert(mplexpholder_move(mplex->mx_phs, NULL, NULL, NULL)); + while(mplex->misc_phs!=NULL){ + assert(mplexpholder_move(mplex->misc_phs, NULL, NULL, NULL)); } window_deinit((WWindow*)mplex); @@ -246,7 +246,8 @@ WRegion *mplex_mx_nth(WMPlex *mplex, uint n) /*EXTL_DOC * Iterate over numbered/mutually exclusive region list of \var{mplex} * until \var{iterfn} returns \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE @@ -263,7 +264,8 @@ bool mplex_mx_i(WMPlex *mplex, ExtlFn iterfn) /*EXTL_DOC * Iterate over managed regions of \var{mplex} until \var{iterfn} returns * \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE @@ -432,7 +434,8 @@ bool mplex_fitrep(WMPlex *mplex, WWindow *par, const WFitParams *fp) bool wchg=(REGION_GEOM(mplex).w!=fp->g.w); bool hchg=(REGION_GEOM(mplex).h!=fp->g.h); - window_do_fitrep(&(mplex->win), par, &(fp->g)); + if(!window_fitrep(&(mplex->win), par, fp)) + return FALSE; if(wchg || hchg){ mplex_fit_managed(mplex); @@ -643,13 +646,6 @@ WStacking *mplex_find_to_focus(WMPlex *mplex, } -static WStacking *mplex_do_to_focus(WMPlex *mplex, WStacking *to_try, - PtrList **hidelist) -{ - return mplex_find_to_focus(mplex, to_try, NULL, hidelist); -} - - static WStacking *mplex_do_to_focus_on(WMPlex *mplex, WStacking *node, WStacking *to_try, PtrList **hidelist, bool *within) @@ -669,7 +665,13 @@ static WStacking *mplex_do_to_focus_on(WMPlex *mplex, WStacking *node, } } - st=mplex_do_to_focus(mplex, node, hidelist); + st=mplex_find_to_focus(mplex, node, NULL, hidelist); + + /* If 'node' points to a group, it isn't actually on the stacking list. + * Give it the focus, if there's nothing "proper" that could be focussed. + */ + if(st==NULL && grp!=NULL && REGION_IS_MAPPED(grp)) + st=node; if(st==node && within!=NULL) *within=TRUE; @@ -696,30 +698,33 @@ static WStacking *has_stacking_within(WMPlex *mplex, WRegion *reg) } +/* 1. Try keep focus in REGION_ACTIVE_SUB. + * 2. Choose something else, attempting previous in focus history. + */ static WStacking *mplex_to_focus(WMPlex *mplex) { - WStacking *to_try=NULL; + WStacking *foc=NULL, *fallback=NULL; WRegion *reg=NULL; - WStacking *st; - to_try=maybe_focusable(REGION_ACTIVE_SUB(mplex)); + foc=maybe_focusable(REGION_ACTIVE_SUB(mplex)); - if(to_try==NULL){ - /* Search focus history */ + if(foc==NULL){ + /* Search focus history if no specific attempt set.*/ for(reg=ioncore_g.focus_current; reg!=NULL; reg=reg->active_next){ - to_try=has_stacking_within(mplex, reg); - if(to_try!=NULL) + foc=has_stacking_within(mplex, reg); + if(foc!=NULL) break; } } - st=mplex_do_to_focus(mplex, to_try, NULL); - - return (st!=NULL - ? st - : (mplex->mx_current!=NULL - ? mplex->mx_current->st - : NULL)); + if(foc!=NULL){ + /* In the history search case, 'foc' might point to a group, + * since we don't properly try to find a stacking within it... + */ + return mplex_do_to_focus_on(mplex, foc, NULL, NULL, NULL); + }else{ + return mplex_find_to_focus(mplex, NULL, NULL, NULL); + } } @@ -728,6 +733,12 @@ void mplex_do_set_focus(WMPlex *mplex, bool warp) if(!MPLEX_MGD_UNVIEWABLE(mplex)){ WStacking *st=mplex_to_focus(mplex); + if(st==NULL){ + st=(mplex->mx_current!=NULL + ? mplex->mx_current->st + : NULL); + } + if(st!=NULL){ region_do_set_focus(st->reg, warp); return; @@ -738,6 +749,22 @@ void mplex_do_set_focus(WMPlex *mplex, bool warp) } +static void mplex_refocus(WMPlex *mplex, WStacking *node, bool warp) +{ + bool within=FALSE; + WStacking *foc=NULL; + + if(node!=NULL) + foc=mplex_do_to_focus_on(mplex, node, NULL, NULL, &within); + + if(foc==NULL || !within) + foc=mplex_to_focus(mplex); + + if(foc!=NULL) + region_maybewarp(foc->reg, warp); +} + + /*}}}*/ @@ -830,24 +857,6 @@ static void mplex_do_node_display(WMPlex *mplex, WStacking *node, } -static bool mplex_refocus(WMPlex *mplex, WStacking *node, bool warp) -{ - WStacking *foc=NULL; - bool within=FALSE; - - if(node!=NULL) - foc=mplex_do_to_focus_on(mplex, node, NULL, NULL, &within); - - if(foc==NULL || !within) - foc=mplex_to_focus(mplex); - - if(foc!=NULL) - region_maybewarp(foc->reg, warp); - - return within; -} - - bool mplex_do_prepare_focus(WMPlex *mplex, WStacking *node, WStacking *sub, int flags, WPrepareFocusResult *res) @@ -1339,18 +1348,24 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph) } +static void mplex_attach_fp(WMPlex *mplex, const WMPlexAttachParams *param, + WFitParams *fp) +{ + if(param->flags&MPLEX_ATTACH_GEOM) + fp->g=param->geom; + else + mplex_managed_geom(mplex, &(fp->g)); + + fp->mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS; +} + + WRegion *mplex_do_attach_pholder(WMPlex *mplex, WMPlexPHolder *ph, WRegionAttachData *data) { - WMPlexAttachParams *param=&(ph->param); WFitParams fp; - if(param->flags&MPLEX_ATTACH_GEOM) - fp.g=param->geom; - else - mplex_managed_geom(mplex, &(fp.g)); - - fp.mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS; + mplex_attach_fp(mplex, &ph->param, &fp); return region_attach_helper((WRegion*)mplex, (WWindow*)mplex, &fp, @@ -1598,9 +1613,19 @@ WPHolder *mplex_prepare_manage(WMPlex *mplex, const WClientWin *cwin, mph=create_mplexpholder(mplex, NULL, &ap); if(mph!=NULL){ - WGroupedPHolder *gph=create_groupedpholder((WPHolder*)mph); - if(gph!=NULL) + WGroupPHolder *gph; + WGroupAttachParams gp=GROUPATTACHPARAMS_INIT; + + gp.switchto_set=1; + gp.switchto=1; + gp.bottom=1; + + gph=create_grouppholder(NULL, NULL, &gp); + + if(gph!=NULL){ + gph->recreate_pholder=(WPHolder*)mph; return (WPHolder*)gph; + } } return (WPHolder*)mph; @@ -1683,13 +1708,29 @@ void mplex_managed_remove(WMPlex *mplex, WRegion *sub) } +void mplex_child_removed(WMPlex *mplex, WRegion *sub) +{ + if(sub!=NULL && sub==(WRegion*)(mplex->stdispwatch.obj)){ + watch_reset(&(mplex->stdispwatch)); + mplex_set_stdisp(mplex, NULL, NULL); + } +} + + +/*}}}*/ + + +/*{{{ Rescue */ + + bool mplex_rescue_clientwins(WMPlex *mplex, WRescueInfo *info) { bool ret1, ret2; WMPlexIterTmp tmp; WLListIterTmp ltmp; WLListNode *lnode, *was_current=mplex->mx_current; - + + /* First all mx stuff to move them nicely to another mplex (when that * is the case), switching to the current region in the target if * allowed by ph_flags_mask region_rescue. @@ -1712,40 +1753,11 @@ bool mplex_rescue_clientwins(WMPlex *mplex, WRescueInfo *info) } - -void mplex_child_removed(WMPlex *mplex, WRegion *sub) -{ - if(sub!=NULL && sub==(WRegion*)(mplex->stdispwatch.obj)){ - watch_reset(&(mplex->stdispwatch)); - mplex_set_stdisp(mplex, NULL, NULL); - } -} - - /*}}}*/ /*{{{ Status display support */ -#ifndef offsetof -# define offsetof(T,F) ((size_t)((char*)&((T*)0L)->F-(char*)0L)) -#endif - -#define STRUCTOF(T, F, FADDR) \ - ((T*)((char*)(FADDR)-offsetof(T, F))) - - -static void stdisp_watch_handler(Watch *watch, Obj *obj) -{ - /*WMPlex *mplex=STRUCTOF(WMPlex, stdispinfo, - STRUCTOF(WMPlexSTDispInfo, regwatch, watch)); - WMPlexSTDispInfo *di=&(mplex->stdispinfo); - WGenWS *ws=OBJ_CAST(REGION_MANAGER(obj), WGenWS); - * - if(ioncore_g.opmode!=IONCORE_OPMODE_DEINIT && ws!=NULL) - genws_unmanage_stdisp(ws, TRUE, FALSE);*/ -} - bool mplex_set_stdisp(WMPlex *mplex, WRegion *reg, const WMPlexSTDispInfo *din) @@ -1776,7 +1788,7 @@ bool mplex_set_stdisp(WMPlex *mplex, WRegion *reg, region_detach_manager(oldstdisp); } }else{ - watch_setup(&(mplex->stdispwatch), (Obj*)reg, stdisp_watch_handler); + watch_setup(&(mplex->stdispwatch), (Obj*)reg, NULL); mplex_remanage_stdisp(mplex); } @@ -1870,7 +1882,7 @@ WRegion *mplex_set_stdisp_extl(WMPlex *mplex, ExtlTab t) data.type=REGION_ATTACH_LOAD; data.u.tab=t; - + stdisp=region_attach_helper((WRegion*)mplex, (WWindow*)mplex, &fp, do_attach_stdisp, NULL, @@ -2113,16 +2125,6 @@ ExtlTab mplex_get_configuration(WMPlex *mplex) } -static WMPlex *tmp_mplex=NULL; -static WMPlexAttachParams *tmp_par=NULL; - -static WPHolder *pholder_callback() -{ - assert(tmp_mplex!=NULL); - return (WPHolder*)create_mplexpholder(tmp_mplex, NULL, tmp_par); -} - - void mplex_load_contents(WMPlex *mplex, ExtlTab tab) { ExtlTab substab, subtab; @@ -2138,27 +2140,26 @@ void mplex_load_contents(WMPlex *mplex, ExtlTab tab) n=extl_table_get_n(substab); for(i=1; i<=n; i++){ if(extl_table_geti_t(substab, i, &subtab)){ - /*mplex_attach_new(mplex, subtab);*/ WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT; - WRegionAttachData data; - char *tmp=NULL; + WFitParams fp; + WPHolder *ph; get_params(mplex, subtab, 0, &par); + mplex_attach_fp(mplex, &par, &fp); par.flags|=MPLEX_ATTACH_INDEX; par.index=LLIST_INDEX_LAST; - tmp_par=∥ - tmp_mplex=mplex; - - data.type=REGION_ATTACH_LOAD; - data.u.tab=subtab; + ph=(WPHolder*)create_mplexpholder(mplex, NULL, &par); - ioncore_set_sm_pholder_callback(pholder_callback); - - mplex_do_attach(mplex, &par, &data); - - tmp_mplex=NULL; + if(ph!=NULL){ + region_attach_load_helper((WRegion*)mplex, (WWindow*)mplex, &fp, + (WRegionDoAttachFn*)mplex_do_attach_final, + (void*)ph, subtab, &ph); + + if(ph!=NULL) + destroy_obj((Obj*)ph); + } extl_unref_table(subtab); }