]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/manage.c
[svn-upgrade] Integrating new upstream version, ion3 (20070318)
[ion3.git] / ioncore / manage.c
index fda8d7b6117fcb6198d6403a282e1a32ef65ac69..2eb6f38b8f97e02bb2cfb54402cc6c417867338a 100644 (file)
@@ -22,6 +22,7 @@
 #include "extlconv.h"
 #include "return.h"
 #include "conf.h"
+#include "detach.h"
 #include "group-ws.h"
 
 
@@ -135,15 +136,56 @@ static bool handle_target_winprops(WClientWin *cwin, const WManageParams *param,
 }
 
 
+static bool try_fullscreen(WClientWin *cwin, WScreen *dflt, 
+                           const WManageParams *param)
+{
+    WScreen *fs_scr=NULL;
+    bool fs=FALSE, tmp;
+    
+    /* Check fullscreen mode. (This is intentionally not done
+     * for transients and windows with target winprops.)
+     */
+    if(extl_table_gets_b(cwin->proptab, "fullscreen", &tmp)){
+        if(!tmp)
+            return FALSE;
+        fs_scr=dflt;
+    }
+
+    if(fs_scr==NULL)
+        fs_scr=netwm_check_initial_fullscreen(cwin);
+
+    if(fs_scr==NULL)
+        fs_scr=clientwin_fullscreen_chkrq(cwin, param->geom.w, param->geom.h);
+    
+    if(fs_scr!=NULL){
+        WPHolder *fs_ph=region_prepare_manage((WRegion*)fs_scr, cwin, param,
+                                              MANAGE_REDIR_STRICT_NO);
+        
+        if(fs_ph!=NULL){
+            int swf=(param->switchto ? PHOLDER_ATTACH_SWITCHTO : 0);
+            
+            cwin->flags|=CLIENTWIN_FS_RQ;
+            
+            fs=pholder_attach(fs_ph, swf, (WRegion*)cwin);
+            
+            if(!fs)
+                cwin->flags&=~CLIENTWIN_FS_RQ;
+                
+            destroy_obj((Obj*)fs_ph);
+        }
+    }
+
+    return fs;
+}
+
+
 bool clientwin_do_manage_default(WClientWin *cwin, 
                                  const WManageParams *param)
 {
-    WRegion *r=NULL, *r2;
     WScreen *scr=NULL;
     WPHolder *ph=NULL;
-    int fs=-1;
-    int swf;
-    bool ok, tmp;
+    int swf=(param->switchto ? PHOLDER_ATTACH_SWITCHTO : 0);
+    bool ok, uq=FALSE;
 
     /* Find a suitable screen */
     scr=clientwin_find_suitable_screen(cwin, param);
@@ -160,6 +202,7 @@ bool clientwin_do_manage_default(WClientWin *cwin,
         assert(param->tfor!=cwin);
         ph=region_prepare_manage_transient((WRegion*)param->tfor, cwin, 
                                            param, 0);
+        uq=TRUE;
     }
 
     if(ph==NULL){
@@ -167,46 +210,30 @@ bool clientwin_do_manage_default(WClientWin *cwin,
         ph=region_prepare_manage((WRegion*)scr, cwin, param,
                                  MANAGE_REDIR_PREFER_YES);
 
-        /* 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){
-        /* Full-screen mode succesfull. */
-        if(pholder_target(ph)==(WRegion*)scr){
-            /* Discard useless placeholder. */
+        if(try_fullscreen(cwin, scr, param)){
+            if(pholder_target(ph)!=(WRegion*)region_screen_of((WRegion*)cwin)){
+                WRegion *grp=region_groupleader_of((WRegion*)cwin);
+                if(region_do_set_return(grp, ph))
+                    return TRUE;
+            }
             destroy_obj((Obj*)ph);
             return TRUE;
         }
         
-        if(!region_do_set_return((WRegion*)cwin, ph))
-            destroy_obj((Obj*)ph);
-        
-        return TRUE;
     }
-        
+
     if(ph==NULL)
         return FALSE;
     
     /* Not in full-screen mode; use the placeholder to attach. */
     
-    swf=(param->switchto ? PHOLDER_ATTACH_SWITCHTO : 0);
     ok=pholder_attach(ph, swf, (WRegion*)cwin);
+    
     destroy_obj((Obj*)ph);
     
+    if(uq && ok)
+        ioncore_unsqueeze((WRegion*)cwin, FALSE);
+    
     return ok;
 }
 
@@ -294,6 +321,14 @@ bool region_manage_clientwin(WRegion *reg, WClientWin *cwin,
 /*{{{ Rescue */
 
 
+DECLSTRUCT(WRescueInfo){
+    WPHolder *ph;
+    WRegion *get_rescue;
+    bool failed_get;
+    bool test;
+};
+
+
 static WRegion *iter_children(void *st)
 {
     WRegion **nextp=(WRegion**)st;
@@ -303,50 +338,101 @@ static WRegion *iter_children(void *st)
 }
 
 
-bool region_rescue_child_clientwins(WRegion *reg, WPHolder *ph)
+bool region_rescue_child_clientwins(WRegion *reg, WRescueInfo *info)
 {
     WRegion *next=reg->children;
-    return region_rescue_some_clientwins(reg, ph, iter_children, &next);
+    return region_rescue_some_clientwins(reg, info, iter_children, &next);
 }
 
 
-bool region_rescue_some_clientwins(WRegion *reg, WPHolder *ph,
+bool region_rescue_some_clientwins(WRegion *reg, WRescueInfo *info,
                                    WRegionIterator *iter, void *st)
 {
     bool res=FALSE;
     int fails=0;
 
+    if(info->failed_get)
+        return FALSE;
+    
     reg->flags|=REGION_CWINS_BEING_RESCUED;
     
     while(TRUE){
         WRegion *tosave=iter(st);
+        WClientWin *cwin;
         
         if(tosave==NULL)
             break;
         
-        if(!OBJ_IS(tosave, WClientWin)){
-            if(!region_rescue_clientwins(tosave, ph))
+        cwin=OBJ_CAST(tosave, WClientWin);
+        
+        if(cwin==NULL){
+            if(!region_rescue_clientwins(tosave, info)){
                 fails++;
-        }else{
-            if(!pholder_attach(ph, 0, tosave))
+                if(info->failed_get)
+                    break;
+            }
+        }else if(info->test){
+            fails++;
+            break;
+        }else if(!(cwin->flags&CLIENTWIN_UNMAP_RQ)){
+            if(info->ph==NULL){
+                info->ph=region_get_rescue_pholder(info->get_rescue);
+                if(info->ph==NULL){
+                    info->failed_get=TRUE;
+                    break;
+                }
+            }
+            if(!pholder_attach(info->ph, 0, (WRegion*)cwin))
                 fails++;
         }
     }
     
     reg->flags&=~REGION_CWINS_BEING_RESCUED;
 
-    return (fails==0);
+    return (fails==0 && !info->failed_get);
 }
 
 
-bool region_rescue_clientwins(WRegion *reg, WPHolder *ph)
+bool region_rescue_clientwins(WRegion *reg, WRescueInfo *info)
 {
     bool ret=FALSE;
-    CALL_DYN_RET(ret, bool, region_rescue_clientwins, reg, (reg, ph));
+    CALL_DYN_RET(ret, bool, region_rescue_clientwins, reg, (reg, info));
+    return ret;
+}
+
+
+bool region_rescue(WRegion *reg, WPHolder *ph_param)
+{
+    WRescueInfo info;
+    bool ret;
+    
+    info.ph=ph_param;
+    info.test=FALSE;
+    info.get_rescue=reg;
+    info.failed_get=FALSE;
+    
+    ret=region_rescue_clientwins(reg, &info);
+    
+    if(info.ph!=ph_param)
+        destroy_obj((Obj*)info.ph);
+    
     return ret;
 }
 
 
+bool region_rescue_needed(WRegion *reg)
+{
+    WRescueInfo info;
+    
+    info.ph=NULL;
+    info.test=TRUE;
+    info.get_rescue=reg;
+    info.failed_get=FALSE;
+    
+    return !region_rescue_clientwins(reg, &info);
+}
+
+
 /*}}}*/