]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/detach.c
Imported Upstream version 20090110
[ion3.git] / ioncore / detach.c
index 8493b9afbca73dc82922b053aafef49d8d8ad9d6..e175759e7d231d0d1681da036f5280b7746ac594 100644 (file)
@@ -1,14 +1,13 @@
 /*
  * ion/ioncore/detach.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 <string.h>
+
 #include <libtu/objp.h>
 #include <libtu/setparam.h>
 #include <libtu/minmax.h>
@@ -41,7 +40,8 @@ static void get_relative_geom(WRectangle *g, WRegion *reg, WRegion *mgr)
 }
 
 
-bool ioncore_do_detach(WRegion *reg, WGroup *grp, WFrameMode framemode)
+static bool ioncore_do_detach(WRegion *reg, WGroup *grp, WFrameMode framemode,
+                              uint framelevel)
 {
     WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
     WRegionAttachData data;
@@ -63,6 +63,7 @@ bool ioncore_do_detach(WRegion *reg, WGroup *grp, WFrameMode framemode)
     }
     
     if(framemode!=FRAME_MODE_UNKNOWN){
+        /* TODO: remove/obsolete this special case */
         WFramedParam fpa=FRAMEDPARAM_INIT;
         
         fpa.mode=framemode;
@@ -71,6 +72,9 @@ bool ioncore_do_detach(WRegion *reg, WGroup *grp, WFrameMode framemode)
         
         ap.geom_weak_set=TRUE;
         ap.geom_weak=0;
+
+        ap.level_set=TRUE;
+        ap.level=framelevel+1;
         
         get_relative_geom(&fpa.inner_geom, reg, (WRegion*)grp);
 
@@ -80,12 +84,18 @@ bool ioncore_do_detach(WRegion *reg, WGroup *grp, WFrameMode framemode)
     }else{
         WStacking *st=ioncore_find_stacking(reg);
         
+        ap.level_set=TRUE;
+        ap.level=framelevel+1;
+
         if(st!=NULL){
             ap.szplcy=st->szplcy;
             ap.szplcy_set=TRUE;
             
-            ap.level=maxof(st->level, STACKING_LEVEL_NORMAL);
-            ap.level_set=TRUE;
+            /* Hack for modal detached queries, while transients become
+             * non-modal detached.
+             */
+            if(st->level>STACKING_LEVEL_MODAL1)
+                ap.level=st->level;
         }
         
         ap.geom_set=TRUE;
@@ -114,23 +124,29 @@ static WRegion *check_mplex(WRegion *reg, WFrameMode *mode)
         
     *mode=FRAME_MODE_FLOATING;
     
-    if(OBJ_IS(mplex, WFrame)
-       && frame_mode((WFrame*)mplex)==FRAME_MODE_TRANSIENT){
-        *mode=FRAME_MODE_TRANSIENT;
+    if(OBJ_IS(mplex, WFrame)){
+        WFrameMode mode2=frame_mode((WFrame*)mplex);
+        if(framemode_unalt(mode2)==FRAME_MODE_TRANSIENT)
+            *mode=mode2;
     }
     
     return (WRegion*)mplex;
 }
 
 
-static WGroup *find_group(WRegion *reg)
+static WGroup *find_group(WRegion *reg, uint *level)
 {
     WRegion *mgr=REGION_MANAGER(reg);
     
     while(mgr!=NULL){
+        reg=mgr;
         mgr=REGION_MANAGER(mgr);
-        if(OBJ_IS(mgr, WGroup))
+        if(OBJ_IS(mgr, WGroup)){
+            WStacking *st=ioncore_find_stacking((WRegion*)reg);
+            if(st!=NULL)
+                *level=st->level;
             break;
+        }
     }
     
     return (WGroup*)mgr;
@@ -139,14 +155,14 @@ static WGroup *find_group(WRegion *reg)
 
 bool ioncore_detach(WRegion *reg, int sp)
 {
-    WPHolder *ph=region_get_return(reg);
     WFrameMode mode;
     WGroup *grp;
     bool set, nset;
+    uint level=STACKING_LEVEL_NORMAL;
     
     reg=region_groupleader_of(reg);
     
-    grp=find_group(check_mplex(reg, &mode));
+    grp=find_group(check_mplex(reg, &mode), &level);
     
     /* reg is only considered detached if there's no higher-level group
      * to attach to, thus causing 'toggle' to cycle.
@@ -158,7 +174,7 @@ bool ioncore_detach(WRegion *reg, int sp)
         return set;
 
     if(!set){
-        return ioncore_do_detach(reg, grp, mode);
+        return ioncore_do_detach(reg, grp, mode, level);
     }else{
         WPHolder *ph=region_get_return(reg);
         
@@ -176,14 +192,17 @@ bool ioncore_detach(WRegion *reg, int sp)
 
 
 /*EXTL_DOC
- * Detach or reattach \var{reg}, depending on whether \var{how}
- * is 'set'/'unset'/'toggle'. (Detaching means making \var{reg} 
- * managed by its nearest ancestor \type{WGroup}, framed if \var{reg} is
- * not itself \type{WFrame}. Reattaching means making it managed where
- * it used to be managed, if a return-placeholder exists.)
- * If \var{reg} is the 'bottom' of some group, the whole group is
- * detached. If \var{reg} is a \type{WWindow}, it is put into a 
- * frame.
+ * Detach or reattach \var{reg} or any group it is the leader of
+ * (see \fnref{WRegion.groupleader_of}), depending on whether \var{how} 
+ * is \codestr{set}, \codestr{unset} or \codestr{toggle}. If this
+ * region is not a window, it is put into a frame.
+ *
+ * Detaching a region means having it managed by its nearest ancestor
+ * \type{WGroup}. Reattaching means having it managed where it used 
+ * to be managed, if a ``return placeholder'' exists.
+ *
+ * Additionally, setting \var{how} to \codestr{forget}, can be used to
+ * clear this return placeholder of the group leader of \var{reg}.
  */
 EXTL_EXPORT_AS(ioncore, detach)
 bool ioncore_detach_extl(WRegion *reg, const char *how)
@@ -191,31 +210,33 @@ bool ioncore_detach_extl(WRegion *reg, const char *how)
     if(how==NULL)
         how="set";
     
+    if(strcmp(how, "forget")==0){
+        region_unset_return(region_groupleader_of(reg));
+        return FALSE;
+    }
+    
     return ioncore_detach(reg, libtu_string_to_setparam(how));
 }
 
 
 void do_unsqueeze(WRegion *reg)
 {
-    WSizeHints hints;
+    WSizeHints h;
     
-    if(REGION_MANAGER_CHK(reg, WScreen)!=NULL)
+    if(OBJ_IS(reg, WScreen))
         return;
     
-    region_size_hints(reg, &hints);
+    region_size_hints(reg, &h);
 
-    if(!hints.min_set)
+    if(!h.min_set)
         return;
         
-    if(hints.min_width<=REGION_GEOM(reg).w &&
-       hints.min_height<=REGION_GEOM(reg).h){
+    if(h.min_width<=REGION_GEOM(reg).w && 
+       h.min_height<=REGION_GEOM(reg).h){
         return;
     }
     
-    if(!ioncore_detach(reg, SETPARAM_SET))
-        return;
-        
-    do_unsqueeze(reg);
+    ioncore_detach(reg, SETPARAM_SET);
 }
 
 
@@ -229,7 +250,7 @@ EXTL_EXPORT
 void ioncore_unsqueeze(WRegion *reg, bool override)
 {
     if(ioncore_g.unsqueeze_enabled || override)
-        do_unsqueeze(region_groupleader_of(reg));
+        do_unsqueeze(reg);
 }