X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=mod_tiling%2Ftiling.c;h=48bbb86f506a3976f57258831660bb12a4710544;hp=159f001a0a9af20f7980469f19dc9f3fc0ae10f1;hb=e3aec18706513a87eaa7839dfdaf7e0fcd0d8d2a;hpb=803afbc1cd633f6c025bcd9537e9b7e9aedadd0d diff --git a/mod_tiling/tiling.c b/mod_tiling/tiling.c index 159f001..48bbb86 100644 --- a/mod_tiling/tiling.c +++ b/mod_tiling/tiling.c @@ -1,12 +1,9 @@ /* * ion/mod_tiling/tiling.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 @@ -48,10 +45,6 @@ static WTilingIterTmp tiling_iter_default_tmp; /*{{{ Some helper routines */ -#define STDISP_OF(WS) \ - ((WS)->stdispnode!=NULL ? (WS)->stdispnode->regnode.reg : NULL) - - static WSplitRegion *get_node_check(WTiling *ws, WRegion *reg) { WSplitRegion *node; @@ -266,32 +259,6 @@ Window tiling_xwindow(const WTiling *ws) } -/* -WRegion *tiling_rqclose_propagate(WTiling *ws, WRegion *maybe_sub) -{ - return (region_rqclose((WRegion*)ws, FALSE) ? (WRegion*)ws : NULL); -} -*/ - -WPHolder *tiling_prepare_manage_transient(WTiling *ws, - const WClientWin *transient, - const WManageParams *param, - int unused) -{ - /* Transient manager searches should not cross tilings unless - * explicitly floated. - */ - if(extl_table_is_bool_set(transient->proptab, "float")){ - return region_prepare_manage_transient_default((WRegion*)ws, - transient, - param, - unused); - }else{ - return NULL; - } -} - - /*}}}*/ @@ -465,6 +432,8 @@ void tiling_manage_stdisp(WTiling *ws, WRegion *stdisp, tiling_unmanage_stdisp(ws, TRUE, TRUE); return; } + + stdisp->flags|=REGION_SKIP_FOCUS; dg=((WSplit*)(ws->stdispnode))->geom; @@ -500,7 +469,7 @@ bool tiling_managed_add_default(WTiling *ws, WRegion *reg) Window bottom=None, top=None; WFrame *frame; - if(STDISP_OF(ws)!=reg){ + if(TILING_STDISP_OF(ws)!=reg){ if(!ptrlist_insert_last(&(ws->managed_list), reg)) return FALSE; } @@ -509,8 +478,7 @@ bool tiling_managed_add_default(WTiling *ws, WRegion *reg) frame=OBJ_CAST(reg, WFrame); if(frame!=NULL){ - WFrameMode mode=frame_mode(frame); - if(mode!=FRAME_MODE_TILED && mode!=FRAME_MODE_TILED_ALT) + if(framemode_unalt(frame_mode(frame))!=FRAME_MODE_TILED) frame_set_mode(frame, FRAME_MODE_TILED); } @@ -535,30 +503,25 @@ bool tiling_managed_add(WTiling *ws, WRegion *reg) } -static WRegion *create_initial_frame(WTiling *ws, WWindow *parent, - const WFitParams *fp) +bool tiling_do_attach_initial(WTiling *ws, WRegion *reg) { - WRegion *reg=ws->create_frame_fn(parent, fp); - - if(reg==NULL) - return NULL; + assert(ws->split_tree==NULL); + + ws->split_tree=(WSplit*)create_splitregion(®ION_GEOM(reg), reg); + if(ws->split_tree==NULL) + return FALSE; - ws->split_tree=(WSplit*)create_splitregion(&(fp->g), reg); - if(ws->split_tree==NULL){ - destroy_obj((Obj*)reg); - return NULL; - } ws->split_tree->ws_if_root=ws; if(!tiling_managed_add(ws, reg)){ - destroy_obj((Obj*)reg); destroy_obj((Obj*)ws->split_tree); - return NULL; + ws->split_tree=NULL; + return FALSE; } - - return reg; + + return TRUE; } - + static WRegion *create_frame_tiling(WWindow *parent, const WFitParams *fp) { @@ -575,7 +538,8 @@ bool tiling_init(WTiling *ws, WWindow *parent, const WFitParams *fp, : create_frame_tiling); ws->stdispnode=NULL; ws->managed_list=NULL; - + ws->batchop=FALSE; + ws->dummywin=XCreateWindow(ioncore_g.dpy, parent->win, fp->g.x, fp->g.y, 1, 1, 0, CopyFromParent, InputOnly, @@ -589,7 +553,18 @@ bool tiling_init(WTiling *ws, WWindow *parent, const WFitParams *fp, REGION_PLEASE_WARP); if(ci){ - if(create_initial_frame(ws, parent, fp)==NULL){ + WRegionAttachData data; + WRegion *res; + + data.type=REGION_ATTACH_NEW; + data.u.n.fn=(WRegionCreateFn*)ws->create_frame_fn; + data.u.n.param=NULL; + + res=region_attach_helper((WRegion*)ws, parent, fp, + (WRegionDoAttachFn*)tiling_do_attach_initial, + NULL, &data); + + if(res==NULL){ XDestroyWindow(ioncore_g.dpy, ws->dummywin); return FALSE; } @@ -648,44 +623,30 @@ void tiling_deinit(WTiling *ws) } -bool tiling_managed_may_destroy(WTiling *ws, WRegion *reg) +WRegion *tiling_managed_disposeroot(WTiling *ws, WRegion *reg) { WTilingIterTmp tmp; WRegion *mgd; - - FOR_ALL_MANAGED_BY_TILING(mgd, ws, tmp){ - if(mgd!=STDISP_OF(ws) && mgd!=reg){ - return TRUE; - } - } - return region_manager_allows_destroying((WRegion*)ws); -} - - -bool tiling_may_destroy(WTiling *ws, WRegion *reg) -{ - WTilingIterTmp tmp; - WRegion *mgd; + if(ws->batchop) + return reg; FOR_ALL_MANAGED_BY_TILING(mgd, ws, tmp){ - if(mgd!=STDISP_OF(ws)){ - warn(TR("Workspace not empty - refusing to destroy.")); - return FALSE; - } + if(mgd!=TILING_STDISP_OF(ws) && mgd!=reg) + return reg; } - return TRUE; + return region_disposeroot((WRegion*)ws); } -bool tiling_rescue_clientwins(WTiling *ws, WPHolder *ph) +bool tiling_rescue_clientwins(WTiling *ws, WRescueInfo *info) { WTilingIterTmp tmp; ptrlist_iter_init(&tmp, ws->managed_list); - return region_rescue_some_clientwins((WRegion*)ws, ph, + return region_rescue_some_clientwins((WRegion*)ws, info, (WRegionIterator*)ptrlist_iter, &tmp); } @@ -693,13 +654,14 @@ bool tiling_rescue_clientwins(WTiling *ws, WPHolder *ph) void tiling_do_managed_remove(WTiling *ws, WRegion *reg) { - if(STDISP_OF(ws)==reg){ + if(TILING_STDISP_OF(ws)==reg){ ws->stdispnode->regnode.reg=NULL; }else{ ptrlist_remove(&(ws->managed_list), reg); } region_unset_manager(reg, (WRegion*)ws); + splittree_set_node_of(reg, NULL); } @@ -711,30 +673,50 @@ static bool nostdispfilter(WSplit *node) void tiling_managed_remove(WTiling *ws, WRegion *reg) { - bool ds=OBJ_IS_BEING_DESTROYED(ws); bool act=REGION_IS_ACTIVE(reg); bool mcf=region_may_control_focus((WRegion*)ws); WSplitRegion *node=get_node_check(ws, reg); - WRegion *other; + bool norestore=(OBJ_IS_BEING_DESTROYED(ws) || ws->batchop); + WRegion *other=NULL; - other=tiling_do_navi_next(ws, reg, REGION_NAVI_ANY, TRUE, FALSE); + if(!norestore) + other=tiling_do_navi_next(ws, reg, REGION_NAVI_ANY, TRUE, FALSE); tiling_do_managed_remove(ws, reg); if(node==(WSplitRegion*)(ws->stdispnode)) ws->stdispnode=NULL; - if(node==NULL) - return; - - splittree_remove((WSplit*)node, (!ds && other!=NULL)); - - if(!ds){ - if(other==NULL) - region_dispose((WRegion*)ws, mcf); - else if(act && mcf) - region_warp(other); + if(node!=NULL){ + bool reused=FALSE; + + if(other==NULL && !norestore){ + WWindow *par=REGION_PARENT(ws); + WFitParams fp; + + assert(par!=NULL); + + fp.g=node->split.geom; + fp.mode=REGION_FIT_EXACT; + + other=(ws->create_frame_fn)(par, &fp); + + if(other!=NULL){ + node->reg=other; + splittree_set_node_of(other, node); + tiling_managed_add(ws, other); + reused=TRUE; + }else{ + warn(TR("Tiling in useless state.")); + } + } + + if(!reused) + splittree_remove((WSplit*)node, (!norestore && other!=NULL)); } + + if(!norestore && other!=NULL && act && mcf) + region_warp(other); } @@ -1010,19 +992,16 @@ static WFrame *tiling_do_split(WTiling *ws, WSplit *node, destroy_obj((Obj*)newframe); return NULL; } - - /* Restack */ - if(ws->split_tree!=NULL) - split_restack(ws->split_tree, ws->dummywin, Above); return newframe; } /*EXTL_DOC - * Create a new frame on \var{ws} above/below/left of/right of - * \var{node} as indicated by \var{dirstr}. If \var{dirstr} is - * prefixed with ''floating:'' a floating split is created. + * Create a new frame on \var{ws} \codestr{above}, \codestr{below} + * \codestr{left} of, or \codestr{right} of \var{node} as indicated + * by \var{dirstr}. If \var{dirstr} is prefixed with + * \codestr{floating:} a floating split is created. */ EXTL_EXPORT_MEMBER WFrame *tiling_split(WTiling *ws, WSplit *node, const char *dirstr) @@ -1048,11 +1027,12 @@ WFrame *tiling_split_top(WTiling *ws, const char *dirstr) /*EXTL_DOC * Split \var{frame} creating a new frame to direction \var{dirstr} - * (one of ''left'', ''right'', ''top'' or ''bottom'') of \var{frame}. + * (one of \codestr{left}, \codestr{right}, \codestr{top} or + * \codestr{bottom}) of \var{frame}. * If \var{attach_current} is set, the region currently displayed in * \var{frame}, if any, is moved to thenew frame. - * If \var{dirstr} is prefixed with ''floating:'' a floating split is - * created. + * If \var{dirstr} is prefixed with \codestr{floating:}, a floating + * split is created. */ EXTL_EXPORT_MEMBER WFrame *tiling_split_at(WTiling *ws, WFrame *frame, const char *dirstr, @@ -1087,23 +1067,25 @@ WFrame *tiling_split_at(WTiling *ws, WFrame *frame, const char *dirstr, /*EXTL_DOC - * Try to relocate regions managed by \var{frame} to another frame - * and, if possible, destroy the frame. + * Try to relocate regions managed by \var{reg} to another frame + * and, if possible, destroy it. */ EXTL_EXPORT_MEMBER -bool tiling_unsplit_at(WTiling *ws, WFrame *frame) +void tiling_unsplit_at(WTiling *ws, WRegion *reg) { - if(frame==NULL){ - warn(TR("Nil frame.")); - return FALSE; - } + WPHolder *ph; - if(REGION_MANAGER(frame)!=(WRegion*)ws){ - warn(TR("The frame is not managed by the workspace.")); - return FALSE; + if(reg==NULL || REGION_MANAGER(reg)!=(WRegion*)ws) + return; + + ph=region_get_rescue_pholder_for((WRegion*)ws, reg); + + if(ph!=NULL){ + region_rescue(reg, ph, REGION_RESCUE_NODEEP|REGION_RESCUE_PHFLAGS_OK); + destroy_obj((Obj*)ph); } - return region_rqclose((WRegion*)frame, TRUE); + region_defer_rqdispose(reg); } @@ -1127,7 +1109,8 @@ WRegion *tiling_current(WTiling *ws) /*EXTL_DOC * Iterate over managed regions of \var{ws} 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 @@ -1155,7 +1138,8 @@ WSplit *tiling_split_tree(WTiling *ws) /*EXTL_DOC * Return the most previously active region next to \var{reg} in - * direction \var{dirstr} (left/right/up/down). The region \var{reg} + * direction \var{dirstr} (\codestr{left}, \codestr{right}, \codestr{up}, + * or \codestr{down}). The region \var{reg} * must be managed by \var{ws}. If \var{any} is not set, the status display * is not considered. */ @@ -1176,8 +1160,8 @@ WRegion *tiling_nextto(WTiling *ws, WRegion *reg, const char *dirstr, /*EXTL_DOC * Return the most previously active region on \var{ws} with no * other regions next to it in direction \var{dirstr} - * (left/right/up/down). If \var{any} is not set, the status - * display is not considered. + * (\codestr{left}, \codestr{right}, \codestr{up}, or \codestr{down}). + * If \var{any} is not set, the status display is not considered. */ EXTL_SAFE EXTL_EXPORT_MEMBER @@ -1353,8 +1337,8 @@ WSplitSplit *tiling_set_floating(WTiling *ws, WSplitSplit *split, int sp) /*EXTL_DOC * Toggle floating of a split's sides at \var{split} as indicated by the - * parameter \var{how} (set/unset/toggle). A split of the appropriate is - * returned, if there was a change. + * parameter \var{how} (\codestr{set}, \codestr{unset}, or \codestr{toggle}). + * A split of the appropriate is returned, if there was a change. */ EXTL_EXPORT_AS(WTiling, set_floating) WSplitSplit *tiling_set_floating_extl(WTiling *ws, WSplitSplit *split, @@ -1368,9 +1352,10 @@ WSplitSplit *tiling_set_floating_extl(WTiling *ws, WSplitSplit *split, /*EXTL_DOC * Toggle floating of the sides of a split containin \var{reg} as indicated - * by the parameters \var{how} (set/unset/toggle) and \var{dirstr} - * (left/right/up/down/any). The new status is returned (and \code{false} - * also on error). + * by the parameters \var{how} (\codestr{set}, \codestr{unset}, or + * \codestr{toggle}) and \var{dirstr} (\codestr{left}, \codestr{right}, + * \codestr{up}, or \codestr{down}). The new status is returned + * (and \code{false} also on error). */ EXTL_EXPORT_AS(WTiling, set_floating_at) bool tiling_set_floating_at_extl(WTiling *ws, WRegion *reg, const char *how, @@ -1716,11 +1701,8 @@ static DynFunTab tiling_dynfuntab[]={ {(DynFun*)region_get_configuration, (DynFun*)tiling_get_configuration}, - {(DynFun*)region_managed_may_destroy, - (DynFun*)tiling_managed_may_destroy}, - - {(DynFun*)region_may_destroy, - (DynFun*)tiling_may_destroy}, + {(DynFun*)region_managed_disposeroot, + (DynFun*)tiling_managed_disposeroot}, {(DynFun*)region_current, (DynFun*)tiling_current}, @@ -1752,9 +1734,6 @@ static DynFunTab tiling_dynfuntab[]={ {(DynFun*)region_xwindow, (DynFun*)tiling_xwindow}, - {(DynFun*)region_prepare_manage_transient, - (DynFun*)tiling_prepare_manage_transient}, - END_DYNFUNTAB };