]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/group-ws.c
Imported Upstream version 20090110
[ion3.git] / ioncore / group-ws.c
index b50402cfd1b94992d812d0499906859c1d0a3655..d7b74473e37cff9be5406e77d96dcb17da185d89 100644 (file)
@@ -1,12 +1,9 @@
 /*
  * ion/ioncore/group-ws.c
  *
- * Copyright (c) Tuomo Valkonen 1999-2006
+ * 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 "group-ws.h"
 #include "group-cw.h"
 #include "grouppholder.h"
-#include "groupedpholder.h"
 #include "framedpholder.h"
 #include "float-placement.h"
 #include "resize.h"
+#include "conf.h"
 
 
 /*{{{ Settings */
 
 
-static bool default_ws_params_set=FALSE;
-static ExtlTab default_ws_params;
-
-
-/*EXTL_DOC
- * Set module basic settings. Currently only the \code{placement_method} 
- * parameter is supported.
- *
- * The method can be one  of ''udlr'', ''lrud'' (default) and ''random''. 
- * The ''udlr'' method looks for free space starting from top the top left
- * corner of the workspace moving first down keeping the x coordinate fixed.
- * If it find no free space, it start looking similarly at next x coordinate
- * unoccupied by other objects and so on. ''lrud' is the same but with the 
- * role of coordinates changed and both fall back to ''random'' placement 
- * if no free area was found.
- */
-
 void ioncore_groupws_set(ExtlTab tab)
 {
     char *method=NULL;
@@ -67,13 +47,6 @@ void ioncore_groupws_set(ExtlTab tab)
             warn(TR("Unknown placement method \"%s\"."), method);
         free(method);
     }
-    
-    if(extl_table_gets_t(tab, "default_ws_params", &t)){
-        if(default_ws_params_set)
-            extl_unref_table(default_ws_params);
-        default_ws_params=t;
-        default_ws_params_set=TRUE;
-    }
 }
 
 
@@ -85,9 +58,6 @@ void ioncore_groupws_get(ExtlTab t)
                        : (ioncore_placement_method==PLACEMENT_LRUD
                           ? "lrud" 
                           : "random")));
-    
-    if(default_ws_params_set)
-        extl_table_sets_t(t, "default_ws_params", default_ws_params);
 }
 
 
@@ -149,44 +119,26 @@ EXTL_EXPORT_AS(WGroupWS, attach_framed)
 bool groupws_attach_framed_extl(WGroupWS *ws, WRegion *reg, ExtlTab t)
 {
     WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
-    WFramedParam fp=FRAMEDPARAM_INIT;
-    ExtlTab gt;
+    WFramedParam frp=FRAMEDPARAM_INIT;
     
     if(reg==NULL)
         return FALSE;
     
-    fp.gravity=ForgetGravity;
-    
-    if(extl_table_is_bool_set(t, "switchto")){
-        ap.switchto_set=TRUE;
-        ap.switchto=TRUE;
-    }
+    group_get_attach_params(&ws->grp, t, &ap);
     
-    if(extl_table_gets_t(t, "geom", &gt)){
-        int pos=0, size=0;
-        
-        fp.inner_geom.x=0;
-        fp.inner_geom.y=0;
-
-        if(extl_table_gets_i(gt, "x", &(ap.geom.x)))
-            pos++;
-        if(extl_table_gets_i(gt, "y", &(ap.geom.y)))
-            pos++;
-    
-        if(extl_table_gets_i(gt, "w", &(ap.geom.w)))
-            size++;
-        if(extl_table_gets_i(gt, "h", &(ap.geom.h)))
-            size++;
-        
-        fp.inner_geom.w=maxof(fp.inner_geom.w, 1);
-        fp.inner_geom.h=maxof(fp.inner_geom.h, 1);
-        
-        fp.inner_geom_gravity_set=(size==2 && pos==2);
+    /* Sensible size is given in framedparams */
+    if(ap.geom_set){
+        ap.geom_set=0;
+        ap.geom_weak_set=1;
+        ap.geom_weak=0;
         
-        extl_unref_table(gt);
+        frp.inner_geom_gravity_set=1;
+        frp.inner_geom=ap.geom;
+        frp.gravity=NorthWestGravity;
+        extl_table_gets_i(t, "gravity", &frp.gravity);
     }
     
-    return groupws_attach_framed(ws, &ap, &fp, reg);
+    return groupws_attach_framed(ws, &ap, &frp, reg);
 }
 
 
@@ -196,50 +148,15 @@ bool groupws_attach_framed_extl(WGroupWS *ws, WRegion *reg, ExtlTab t)
 /*{{{ groupws_prepare_manage */
 
 
-#define REG_OK(R) OBJ_IS(R, WMPlex)
-
-
-static WMPlex *find_existing(WGroupWS *ws)
-{
-    WGroupIterTmp tmp;
-    WRegion *r=(ws->grp.current_managed!=NULL 
-                ? ws->grp.current_managed->reg 
-                : NULL);
-    
-    if(r!=NULL && REG_OK(r))
-        return (WMPlex*)r;
-    
-    FOR_ALL_MANAGED_BY_GROUP(&ws->grp, r, tmp){
-        if(REG_OK(r))
-            return (WMPlex*)r;
-    }
-    
-    return NULL;
-}
-
-
 static WPHolder *groupws_do_prepare_manage(WGroupWS *ws, 
                                            const WClientWin *cwin,
                                            const WManageParams *param, 
-                                           int redir, int geom_weak)
+                                           int geom_weak)
 {
     WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
     WFramedParam fp=FRAMEDPARAM_INIT;
     WPHolder *ph;
     
-    if(redir==MANAGE_REDIR_PREFER_YES){
-        WMPlex *m=find_existing(ws);
-        if(m!=NULL){
-            WPHolder *ph;
-            ph=region_prepare_manage((WRegion*)m, cwin, param,
-                                     MANAGE_REDIR_STRICT_YES);
-            if(ph!=NULL)
-                return ph;
-        }
-    }
-    
-    if(redir==MANAGE_REDIR_STRICT_YES)
-        return NULL;
 
     fp.inner_geom_gravity_set=TRUE;
     fp.inner_geom=param->geom;
@@ -253,8 +170,21 @@ static WPHolder *groupws_do_prepare_manage(WGroupWS *ws,
     if(ph!=NULL)
         ph=pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
     
-    if(ph!=NULL)
-        ph=pholder_either((WPHolder*)create_groupedpholder((WPHolder*)ph), ph);
+    if(ph!=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=ph;
+            return (WPHolder*)gph;
+        }
+    }
     
     return ph;
 }
@@ -262,12 +192,14 @@ static WPHolder *groupws_do_prepare_manage(WGroupWS *ws,
 
 WPHolder *groupws_prepare_manage(WGroupWS *ws, const WClientWin *cwin,
                                  const WManageParams *param,
-                                 int redir)
+                                 int priority)
 {
+    int cpriority=MANAGE_PRIORITY_SUB(priority, MANAGE_PRIORITY_GROUP);
+    int bpriority=MANAGE_PRIORITY_SUBX(priority, MANAGE_PRIORITY_GROUP);
     WRegion *b=(ws->grp.bottom!=NULL ? ws->grp.bottom->reg : NULL);
     WPHolder *ph=NULL;
     bool act_b=(ws->grp.bottom==ws->grp.current_managed);
-    bool always_float, use_bottom;
+    bool use_bottom;
     int weak=0;
     
     if(param->maprq && ioncore_g.opmode!=IONCORE_OPMODE_INIT
@@ -288,13 +220,23 @@ WPHolder *groupws_prepare_manage(WGroupWS *ws, const WClientWin *cwin,
                 : act_b);
     
     if(b!=NULL && use_bottom)
-        ph=region_prepare_manage(b, cwin, param, redir);
+        ph=region_prepare_manage(b, cwin, param, bpriority);
+    
+    if(ph==NULL){
+        /* Check current */
+        WRegion *r=(ws->grp.current_managed!=NULL 
+                    ? ws->grp.current_managed->reg 
+                    : NULL);
+        
+        if(r!=NULL && r!=b)
+            ph=region_prepare_manage(r, cwin, param, cpriority);
+    }
+    
+    if(ph==NULL && MANAGE_PRIORITY_OK(priority, MANAGE_PRIORITY_GROUP))
+        ph=groupws_do_prepare_manage(ws, cwin, param, weak);
     
-    if(ph==NULL)
-        ph=groupws_do_prepare_manage(ws, cwin, param, redir, weak);
-
     if(ph==NULL && b!=NULL && !use_bottom)
-        ph=region_prepare_manage(b, cwin, param, redir);
+        ph=region_prepare_manage(b, cwin, param, cpriority);
     
     return ph;
 }
@@ -315,7 +257,7 @@ WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin,
     fp.inner_geom_gravity_set=TRUE;
     fp.inner_geom=param->geom;
     fp.gravity=param->gravity;
-    fp.mkframe=create_transient_frame;
+    fp.mode=FRAME_MODE_TRANSIENT;
     
     ap.geom_weak_set=1;
     ap.geom_weak=0;
@@ -326,24 +268,28 @@ WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin,
 }
 
 
-WPHolder *groupws_get_rescue_pholder_for(WGroupWS *ws, 
-                                         WRegion *forwhat)
+static bool group_empty_for_bottom_stdisp(WGroup *ws)
 {
-    WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
-    WFramedParam fp=FRAMEDPARAM_INIT;
-    WPHolder *ph;
+    WGroupIterTmp tmp;
+    WStacking *st;
     
-    ap.geom_set=TRUE;
-    ap.geom=REGION_GEOM(forwhat);
+    FOR_ALL_NODES_IN_GROUP(ws, st, tmp){
+        if(st!=ws->bottom && st!=ws->managed_stdisp)
+            return FALSE;
+    }
+    
+    return TRUE;
+}
 
-    ap.geom_weak_set=1;
-    ap.geom_weak=(REGION_PARENT(forwhat)!=REGION_PARENT(ws)
-                  ? REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y
-                  : 0);
 
-    ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
+static WRegion *groupws_managed_disposeroot(WGroupWS *ws, WRegion *reg)
+{
+    if(group_bottom(&ws->grp)==reg){
+        if(group_empty_for_bottom_stdisp(&ws->grp))
+            return region_disposeroot((WRegion*)ws);
+    }
     
-    return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
+    return reg;
 }
 
 
@@ -379,7 +325,7 @@ void groupws_deinit(WGroupWS *ws)
 
 
 WRegion *groupws_load(WWindow *par, const WFitParams *fp, 
-                       ExtlTab tab)
+                      ExtlTab tab)
 {
     WGroupWS *ws;
     
@@ -394,27 +340,19 @@ WRegion *groupws_load(WWindow *par, const WFitParams *fp,
 }
 
 
-WRegion *groupws_load_default(WWindow *par, const WFitParams *fp)
-{
-    return groupws_load(par, fp, (default_ws_params_set
-                                  ? default_ws_params
-                                  : extl_table_none()));
-}
-
-
 static DynFunTab groupws_dynfuntab[]={
     {(DynFun*)region_prepare_manage, 
      (DynFun*)groupws_prepare_manage},
     
     {(DynFun*)region_prepare_manage_transient,
      (DynFun*)groupws_prepare_manage_transient},
+     
+    {(DynFun*)region_managed_disposeroot,
+     (DynFun*)groupws_managed_disposeroot},
     
     {(DynFun*)region_handle_drop,
      (DynFun*)groupws_handle_drop},
     
-    {(DynFun*)region_get_rescue_pholder_for,
-     (DynFun*)groupws_get_rescue_pholder_for},
-    
     {region_manage_stdisp,
      group_manage_stdisp},