]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/stacking.c
Imported Upstream version 20090110
[ion3.git] / ioncore / stacking.c
index 8d696cb26a9b51c46689438f5cdd7ad31ab556d8..0c6480d7b5331ecc7479ca59b16dd6a22f1a6360 100644 (file)
@@ -1,15 +1,13 @@
 /*
  * ion/ioncore/stacking.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 <libtu/rb.h>
+#include <libtu/minmax.h>
 
 #include "common.h"
 #include "region.h"
@@ -32,6 +30,7 @@ WStacking *create_stacking()
         st->szplcy=SIZEPOLICY_DEFAULT;
         st->hidden=FALSE;
         st->lnode=NULL;
+        st->pseudomodal=FALSE;
     }
     
     return st;
@@ -521,8 +520,8 @@ uint stacking_min_level(WStacking *stacking,
                         WStackingFilter *include_filt, 
                         void *filt_data)
 {
+    uint min_level=STACKING_LEVEL_BOTTOM;
     WStacking *st=NULL;
-    uint min_level=0;
     
     if(stacking==NULL)
         return STACKING_LEVEL_BOTTOM;
@@ -546,38 +545,48 @@ uint stacking_min_level(WStacking *stacking,
 }
 
 
-WStacking *stacking_find_to_focus(WStacking *stacking, WStacking *to_try,
+WStacking *stacking_find_to_focus(WStacking *stacking, 
+                                  WStacking *to_try,
                                   WStackingFilter *include_filt, 
                                   WStackingFilter *approve_filt, 
                                   void *filt_data)
 {
-    WStacking *st=NULL;
-    uint min_level=0;
+    uint min_level=STACKING_LEVEL_BOTTOM;
+    WStacking *st=NULL, *found=NULL;
     
     if(stacking==NULL)
         return NULL;
     
-    min_level=stacking_min_level(stacking, include_filt, filt_data);
-    
-    if(to_try!=NULL && to_try->level>=min_level)
-        return to_try;
-    
     st=stacking;
     do{
         st=st->prev;
         
+        if(st->reg==NULL)
+            continue;
+        
+        if(st!=to_try && (st->reg->flags&REGION_SKIP_FOCUS ||
+                          !cf(include_filt, filt_data, st))){
+            /* skip */
+            continue;
+        }
+        
         if(st->level<min_level)
-            break;
+            break; /* no luck */
         
-        if(st->reg!=NULL 
-           && !(st->reg->flags&REGION_SKIP_FOCUS)
-           && cf(include_filt, filt_data, st)
-           && cf(approve_filt, filt_data, st)){
+        if(st==to_try)
             return st;
+            
+        if(found==NULL && cf(approve_filt, filt_data, st)){
+            found=st;
+            if(to_try==NULL)
+                break;
         }
+            
+        if(st->level>=STACKING_LEVEL_MODAL1)
+            min_level=maxof(min_level, st->level);
     }while(st!=stacking);
     
-    return NULL;
+    return found;
 }
 
 
@@ -587,6 +596,12 @@ static bool mapped_filt(WStacking *st, void *unused)
 }
 
 
+static bool mapped_filt_neq(WStacking *st, void *st_neq)
+{
+    return (st!=(WStacking*)st_neq && mapped_filt(st, NULL));
+}
+
+
 static bool mgr_filt(WStacking *st, void *mgr_)
 {
     return (st->reg!=NULL && REGION_MANAGER(st->reg)==(WRegion*)mgr_);
@@ -613,5 +628,16 @@ uint stacking_min_level_mapped(WStacking *stacking)
 }
 
 
+bool stacking_must_focus(WStacking *stacking, WStacking *st)
+{
+    WStacking *stf=stacking_find_to_focus(stacking, NULL, 
+                                          mapped_filt_neq, NULL, st);
+    
+    return (stf==NULL || 
+            (st->level>stf->level &&
+             st->level>=STACKING_LEVEL_MODAL1));
+}
+
+
 /*}}}*/