4 * Copyright (c) Tuomo Valkonen 1999-2006.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
12 #include <libtu/objp.h>
14 #include <ioncore/common.h>
15 #include <ioncore/mplex.h>
16 #include <ioncore/focus.h>
17 #include <ioncore/group.h>
18 #include <ioncore/group-ws.h>
19 #include <ioncore/framedpholder.h>
23 static WGroup *find_group(WRegion *reg, bool *detach_framed)
25 WRegion *mgr=REGION_MANAGER(reg);
26 bool was_grouped=FALSE;
28 if(OBJ_IS(mgr, WMPlex)){
29 WMPlex *mplex=(WMPlex*)mgr;
31 mgr=REGION_MANAGER(mgr);
32 if(OBJ_IS(mgr, WGroup)){
33 assert(mplex->mgd!=NULL);
34 if(mplex->mgd->reg==reg && mplex->mgd->mgr_next==NULL){
35 /* Nothing to detach */
40 was_grouped=OBJ_IS(mgr, WGroup);
45 mgr=REGION_MANAGER(mgr);
46 if(OBJ_IS(mgr, WGroup))
50 if(mgr==NULL && was_grouped)
51 warn(TR("Already detached."));
57 static void get_relative_geom(WRectangle *g, WRegion *reg, WRegion *mgr)
59 WWindow *rel=REGION_PARENT(mgr), *w;
63 for(w=REGION_PARENT(reg);
64 w!=rel && (WRegion*)w!=mgr;
67 g->x+=REGION_GEOM(w).x;
68 g->y+=REGION_GEOM(w).y;
74 * Detach \var{reg}, i.e. make it managed by its nearest ancestor
75 * \type{WGroup}, framed if \var{reg} is not itself \type{WFrame}.
78 bool mod_tiling_detach(WRegion *reg)
80 bool detach_framed=!OBJ_IS(reg, WFrame);
81 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
82 WRegionAttachData data;
85 grp=find_group(reg, &detach_framed);
91 ap.switchto=region_may_control_focus(reg);
94 get_relative_geom(&ap.geom, reg, (WRegion*)grp);
96 /* TODO: Retain (root-relative) geometry of reg for framed
97 * detach instead of making a frame of this size?
100 data.type=REGION_ATTACH_REPARENT;
104 WFramedParam fp=FRAMEDPARAM_INIT;
106 return (region_attach_framed((WRegion*)grp, &fp,
107 (WRegionAttachFn*)group_do_attach,
110 return (group_do_attach(grp, &ap, &data)!=NULL);
115 static WRegion *mkbottom_fn(WWindow *parent, const WFitParams *fp,
118 WRegion *reg=(WRegion*)param;
120 WSplitRegion *node=NULL;
122 if(!region_fitrep(reg, parent, fp))
125 tiling=create_tiling(parent, fp, NULL, FALSE);
130 node=create_splitregion(®ION_GEOM(tiling), reg);
132 tiling->split_tree=(WSplit*)node;
133 tiling->split_tree->ws_if_root=tiling;
135 region_detach_manager(reg);
137 if(tiling_managed_add(tiling, reg))
138 return (WRegion*)tiling;
140 #warning "TODO: reattach?"
142 destroy_obj((Obj*)tiling->split_tree);
143 tiling->split_tree=NULL;
146 destroy_obj((Obj*)tiling);
152 * Create a new \type{WTiling} 'bottom' for the group of \var{reg},
153 * consisting of \var{reg}.
156 bool mod_tiling_mkbottom(WRegion *reg)
158 WGroup *grp=REGION_MANAGER_CHK(reg, WGroup);
159 WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
160 WRegionAttachData data;
164 warn(TR("Not member of a group"));
168 if(grp->bottom!=NULL){
169 warn(TR("Manager group already has bottom"));
174 ap.level=STACKING_LEVEL_BOTTOM;
177 ap.szplcy=SIZEPOLICY_FULL_EXACT;
179 ap.switchto_set=TRUE;
180 ap.switchto=region_may_control_focus(reg);
184 data.type=REGION_ATTACH_NEW;
185 data.u.n.fn=mkbottom_fn;
188 /* kele... poisto samalla kuin attach */
189 return (group_do_attach(grp, &ap, &data)!=NULL);