]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/manage.c
[svn-upgrade] Integrating new upstream version, ion3 (20070203)
[ion3.git] / ioncore / manage.c
index f1d78a0a95ac567f82cb3870e5de232e1d62e778..fda8d7b6117fcb6198d6403a282e1a32ef65ac69 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * ion/ioncore/manage.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
@@ -20,6 +20,9 @@
 #include "pointer.h"
 #include "netwm.h"
 #include "extlconv.h"
+#include "return.h"
+#include "conf.h"
+#include "group-ws.h"
 
 
 /*{{{ Add */
@@ -34,16 +37,22 @@ WScreen *clientwin_find_suitable_screen(WClientWin *cwin,
     FOR_ALL_SCREENS(scr){
         if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin))
             continue;
-        if(REGION_IS_ACTIVE(scr)){
-            found=scr;
-            if(!respectpos)
-                break;
-        }
-        
-        if(rectangle_contains(&REGION_GEOM(scr), param->geom.x, param->geom.y)){
-            found=scr;
-            if(respectpos)
-                break;
+            
+        if(!OBJ_IS(scr, WRootWin)){
+            /* The root window itself is only a fallback */
+            
+            if(REGION_IS_ACTIVE(scr)){
+                found=scr;
+                if(!respectpos)
+                    break;
+            }
+            
+            if(rectangle_contains(&REGION_GEOM(scr), 
+                                  param->geom.x, param->geom.y)){
+                found=scr;
+                if(respectpos)
+                    break;
+            }
         }
         
         if(found==NULL)
@@ -54,6 +63,78 @@ WScreen *clientwin_find_suitable_screen(WClientWin *cwin,
 }
 
 
+/*extern WRegion *ioncore_newly_created;*/
+
+
+static WPHolder *try_target(WClientWin *cwin, const WManageParams *param, 
+                            const char *target)
+{
+    WRegion *r=ioncore_lookup_region(target, NULL);
+        
+    if(r==NULL)
+        return NULL;
+            
+    return region_prepare_manage(r, cwin, param, MANAGE_REDIR_PREFER_NO);
+}
+
+
+static bool handle_target_winprops(WClientWin *cwin, const WManageParams *param,
+                                   WScreen *scr, WPHolder **ph_ret)
+{
+    char *layout=NULL, *target=NULL;
+    WPHolder *ph=NULL;
+    bool mgd=FALSE;
+    
+    if(extl_table_gets_s(cwin->proptab, "target", &target))
+        ph=try_target(cwin, param, target);
+    
+    if(ph==NULL && extl_table_gets_s(cwin->proptab, "new_group", &layout)){
+        ExtlTab lo=ioncore_get_layout(layout);
+        
+        free(layout);
+        
+        if(lo!=extl_table_none()){
+            WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT;
+            int mask=MPLEX_ATTACH_SWITCHTO;
+            WRegion *reg;
+            
+            if(param->switchto)
+                par.flags|=MPLEX_ATTACH_SWITCHTO;
+            
+            /*ioncore_newly_created=(WRegion*)cwin;*/
+            
+            reg=mplex_attach_new_(&scr->mplex, &par, mask, lo);
+            
+            extl_unref_table(lo);
+            
+            /*ioncore_newly_created=NULL;*/
+            
+            mgd=(region_manager((WRegion*)cwin)!=NULL);
+            
+            if(reg!=NULL && !mgd){
+                if(target!=NULL)
+                    ph=try_target(cwin, param, target);
+                
+                if(ph==NULL){
+                    ph=region_prepare_manage(reg, cwin, param, 
+                                             MANAGE_REDIR_PREFER_YES);
+                    
+                    if(ph==NULL)
+                        destroy_obj((Obj*)reg);
+                }
+            }
+        }
+    }
+    
+    if(target!=NULL)
+        free(target);
+    
+    *ph_ret=ph;
+    
+    return mgd;
+}
+
+
 bool clientwin_do_manage_default(WClientWin *cwin, 
                                  const WManageParams *param)
 {
@@ -64,13 +145,6 @@ bool clientwin_do_manage_default(WClientWin *cwin,
     int swf;
     bool ok, tmp;
 
-    /* Check if param->tfor or any of its managers want to manage cwin. */
-    if(param->tfor!=NULL){
-        assert(param->tfor!=cwin);
-        ph=region_prepare_manage_transient((WRegion*)param->tfor, cwin, 
-                                           param, 0);
-    }
-    
     /* Find a suitable screen */
     scr=clientwin_find_suitable_screen(cwin, param);
     if(scr==NULL){
@@ -78,24 +152,36 @@ bool clientwin_do_manage_default(WClientWin *cwin,
         return FALSE;
     }
     
+    if(handle_target_winprops(cwin, param, scr, &ph))
+        return TRUE;
+        
+    /* Check if param->tfor or any of its managers want to manage cwin. */
+    if(ph==NULL && param->tfor!=NULL){
+        assert(param->tfor!=cwin);
+        ph=region_prepare_manage_transient((WRegion*)param->tfor, cwin, 
+                                           param, 0);
+    }
+
     if(ph==NULL){
         /* Find a placeholder for non-fullscreen state */
         ph=region_prepare_manage((WRegion*)scr, cwin, param,
                                  MANAGE_REDIR_PREFER_YES);
-    }
-    
-    /* Check fullscreen mode */
-    if(extl_table_gets_b(cwin->proptab, "fullscreen", &tmp))
-        fs=tmp;
 
-    if(fs<0)
-        fs=netwm_check_initial_fullscreen(cwin, param->switchto);
+        /* Check fullscreen mode. (This is intentionally not done
+         * for transients and windows with target winprops.)
+         */
+        if(extl_table_gets_b(cwin->proptab, "fullscreen", &tmp))
+            fs=tmp;
+
+        if(fs<0)
+            fs=netwm_check_initial_fullscreen(cwin, param->switchto);
     
-    if(fs<0){
-        fs=clientwin_check_fullscreen_request(cwin, 
-                                              param->geom.w,
-                                              param->geom.h,
-                                              param->switchto);
+        if(fs<0){
+            fs=clientwin_check_fullscreen_request(cwin, 
+                                                  param->geom.w,
+                                                  param->geom.h,
+                                                  param->switchto);
+        }
     }
 
     if(fs>0){
@@ -105,8 +191,10 @@ bool clientwin_do_manage_default(WClientWin *cwin,
             destroy_obj((Obj*)ph);
             return TRUE;
         }
-        assert(cwin->fs_pholder==NULL);
-        cwin->fs_pholder=ph;
+        
+        if(!region_do_set_return((WRegion*)cwin, ph))
+            destroy_obj((Obj*)ph);
+        
         return TRUE;
     }