X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=mod_tiling%2Fops.c;h=75570e04406aa0d7c393148474856f4c967bf6d2;hp=c86a80a94f6bbb2fc69a88b6b034d1d3b83bb0ea;hb=ae4260bb64817c11f9a7140324cd3e3ba113e297;hpb=8366314611bf30a0f31d25bf5f5023186fa87692 diff --git a/mod_tiling/ops.c b/mod_tiling/ops.c index c86a80a..75570e0 100644 --- a/mod_tiling/ops.c +++ b/mod_tiling/ops.c @@ -1,150 +1,56 @@ /* * ion/mod_tiling/ops.c * - * Copyright (c) Tuomo Valkonen 1999-2006. + * Copyright (c) Tuomo Valkonen 1999-2007. * - * 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 - #include #include #include +#include #include -#include -#include #include "tiling.h" -static WGroup *find_group(WRegion *reg, bool *detach_framed) -{ - WRegion *mgr=REGION_MANAGER(reg); - bool was_grouped=FALSE; - - if(OBJ_IS(mgr, WMPlex)){ - WMPlex *mplex=(WMPlex*)mgr; - *detach_framed=TRUE; - mgr=REGION_MANAGER(mgr); - if(OBJ_IS(mgr, WGroup)){ - assert(mplex->mgd!=NULL); - if(mplex->mgd->reg==reg && mplex->mgd->mgr_next==NULL){ - /* Nothing to detach */ - return NULL; - } - } - }else{ - was_grouped=OBJ_IS(mgr, WGroup); - *detach_framed=FALSE; - } - - while(mgr!=NULL){ - mgr=REGION_MANAGER(mgr); - if(OBJ_IS(mgr, WGroup)) - break; - } - - if(mgr==NULL && was_grouped) - warn(TR("Already detached.")); - - return (WGroup*)mgr; -} - - -static void get_relative_geom(WRectangle *g, WRegion *reg, WRegion *mgr) -{ - WWindow *rel=REGION_PARENT(mgr), *w; - - *g=REGION_GEOM(reg); - - for(w=REGION_PARENT(reg); - w!=rel && (WRegion*)w!=mgr; - w=REGION_PARENT(w)){ - - g->x+=REGION_GEOM(w).x; - g->y+=REGION_GEOM(w).y; - } -} - - -/*EXTL_DOC - * Detach \var{reg}, i.e. make it managed by its nearest ancestor - * \type{WGroup}, framed if \var{reg} is not itself \type{WFrame}. - */ -EXTL_EXPORT -bool mod_tiling_detach(WRegion *reg) -{ - bool detach_framed=!OBJ_IS(reg, WFrame); - WGroupAttachParams ap=GROUPATTACHPARAMS_INIT; - WRegionAttachData data; - WGroup *grp; - - grp=find_group(reg, &detach_framed); - - if(grp==NULL) - return FALSE; - - ap.switchto_set=TRUE; - ap.switchto=region_may_control_focus(reg); - - ap.geom_set=TRUE; - get_relative_geom(&ap.geom, reg, (WRegion*)grp); - - /* TODO: Retain (root-relative) geometry of reg for framed - * detach instead of making a frame of this size? - */ - - data.type=REGION_ATTACH_REPARENT; - data.u.reg=reg; - - if(detach_framed){ - WFramedParam fp=FRAMEDPARAM_INIT; - - return (region_attach_framed((WRegion*)grp, &fp, - (WRegionAttachFn*)group_do_attach, - &ap, &data)!=NULL); - }else{ - return (group_do_attach(grp, &ap, &data)!=NULL); - } -} +/*{{{ mkbottom */ static WRegion *mkbottom_fn(WWindow *parent, const WFitParams *fp, void *param) { - WRegion *reg=(WRegion*)param; + WRegion *reg=(WRegion*)param, *res; + WRegionAttachData data; WTiling *tiling; - WSplitRegion *node=NULL; + WFitParams fp2; - if(!region_fitrep(reg, parent, fp)) - return NULL; + fp2.mode=REGION_FIT_EXACT; + fp2.g=fp->g; - tiling=create_tiling(parent, fp, NULL, FALSE); + tiling=create_tiling(parent, &fp2, NULL, FALSE); if(tiling==NULL) return NULL; - - node=create_splitregion(®ION_GEOM(tiling), reg); - if(node!=NULL){ - tiling->split_tree=(WSplit*)node; - tiling->split_tree->ws_if_root=tiling; - - region_detach_manager(reg); - if(tiling_managed_add(tiling, reg)) - return (WRegion*)tiling; - - #warning "TODO: reattach?" - - destroy_obj((Obj*)tiling->split_tree); - tiling->split_tree=NULL; - } + data.type=REGION_ATTACH_REPARENT; + data.u.reg=reg; - destroy_obj((Obj*)tiling); - return NULL; + /* Warning! Potentially dangerous call to remove a `reg` from the same + * group we're being attached to, and from the attach routine of which + * this function is called from! + */ + res=region_attach_helper((WRegion*)tiling, parent, &fp2, + (WRegionDoAttachFn*)tiling_do_attach_initial, + NULL, &data); + + if(res==NULL){ + destroy_obj((Obj*)tiling); + return NULL; + } + + return (WRegion*)tiling; } @@ -158,14 +64,13 @@ bool mod_tiling_mkbottom(WRegion *reg) WGroup *grp=REGION_MANAGER_CHK(reg, WGroup); WGroupAttachParams ap=GROUPATTACHPARAMS_INIT; WRegionAttachData data; - WRegion *tiling; if(grp==NULL){ warn(TR("Not member of a group")); return FALSE; } - if(grp->bottom!=NULL){ + if(group_bottom(grp)!=NULL){ warn(TR("Manager group already has bottom")); return FALSE; } @@ -185,6 +90,74 @@ bool mod_tiling_mkbottom(WRegion *reg) data.u.n.fn=mkbottom_fn; data.u.n.param=reg; - /* kele... poisto samalla kuin attach */ + /* See the "Warning!" above. */ return (group_do_attach(grp, &ap, &data)!=NULL); } + + +/*}}}*/ + + +/*{{{ untile */ + + +/*EXTL_DOC + * If \var{tiling} is managed by some group, float the frames in + * the tiling in that group, and dispose of \var{tiling}. + */ +EXTL_EXPORT +bool mod_tiling_untile(WTiling *tiling) +{ + WGroup *grp=REGION_MANAGER_CHK(tiling, WGroup); + WGroupAttachParams param=GROUPATTACHPARAMS_INIT; + WTilingIterTmp tmp; + WRegion *reg, *reg2; + + if(grp==NULL){ + warn(TR("Not member of a group")); + return FALSE; + } + + if(group_bottom(grp)==(WRegion*)tiling) + group_set_bottom(grp, NULL); + + /* Setting `batchop` will stop `tiling_managed_remove` from + * resizing remaining frames into freed space. It will also + * stop the tiling from being destroyed by actions of + * `tiling_managed_disposeroot`. + */ + tiling->batchop=TRUE; + + FOR_ALL_MANAGED_BY_TILING(reg, tiling, tmp){ + WRegionAttachData data; + + /* Don't bother with the status display */ + if(reg==TILING_STDISP_OF(tiling)) + continue; + + /* Don't bother with regions containing no client windows. */ + if(!region_rescue_needed(reg)) + continue; + + data.type=REGION_ATTACH_REPARENT; + data.u.reg=reg; + + param.geom_set=TRUE; + param.geom=REGION_GEOM(reg); + + reg2=group_do_attach(grp, ¶m, &data); + + if(reg2==NULL) + warn(TR("Unable to move a region from tiling to group.")); + } + + tiling->batchop=FALSE; + + region_dispose((WRegion*)tiling); + + return TRUE; +} + + +/*}}}*/ +