]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/region.c
[svn-upgrade] Integrating new upstream version, ion3 (20070203)
[ion3.git] / ioncore / region.c
index dede094fae0db007d9732d37cbbef10987260479..68be25d32e8695ecaeb7ae0b62ac5388e4afea2d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * ion/ioncore/region.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
@@ -26,6 +26,7 @@
 #include "extlconv.h"
 #include "activity.h"
 #include "region-iter.h"
+#include "return.h"
 
 
 #define D2(X)
@@ -33,8 +34,8 @@
 
 WHook *region_notify_hook=NULL;
 
-static void region_notify_change_(WRegion *reg, const char *how, 
-                                  Obj *detail);
+
+static void region_notify_change_(WRegion *reg, WRegionNotify how);
 
 
 /*{{{ Init & deinit */
@@ -73,7 +74,7 @@ void region_init(WRegion *reg, WWindow *par, const WFitParams *fp)
         reg->rootwin=((WRegion*)par)->rootwin;
         region_set_parent(reg, par);
     }else{
-        assert(OBJ_IS(reg, WRootWin));/* || OBJ_IS(reg, WScreen));*/
+        assert(OBJ_IS(reg, WRootWin));
     }
 }
 
@@ -103,6 +104,8 @@ static void destroy_children(WRegion *reg)
 
 void region_deinit(WRegion *reg)
 {
+    region_notify_change(reg, ioncore_g.notifies.deinit);
+    
     destroy_children(reg);
 
     if(ioncore_g.focus_next==reg){
@@ -111,6 +114,7 @@ void region_deinit(WRegion *reg)
     }
 
     region_detach_manager(reg);
+    region_unset_return(reg);
     region_unset_parent(reg);
     region_remove_bindings(reg);
     
@@ -192,18 +196,6 @@ void region_do_set_focus(WRegion *reg, bool warp)
 /*{{{ Manager region dynfuns */
 
 
-void region_managed_activated(WRegion *mgr, WRegion *reg)
-{
-    CALL_DYN(region_managed_activated, mgr, (mgr, reg));
-}
-
-
-void region_managed_inactivated(WRegion *mgr, WRegion *reg)
-{
-    CALL_DYN(region_managed_inactivated, mgr, (mgr, reg));
-}
-
-
 static bool region_managed_prepare_focus_default(WRegion *mgr, WRegion *reg, 
                                                  int flags, 
                                                  WPrepareFocusResult *res)
@@ -228,7 +220,7 @@ bool region_managed_prepare_focus(WRegion *mgr, WRegion *reg,
 }
 
 
-void region_managed_notify(WRegion *mgr, WRegion *reg, const char *how)
+void region_managed_notify(WRegion *mgr, WRegion *reg, WRegionNotify how)
 {
     CALL_DYN(region_managed_notify, mgr, (mgr, reg, how));
 }
@@ -377,7 +369,7 @@ bool region_reparent(WRegion *reg, WWindow *par,
 static bool region_rqclose_default(WRegion *reg, bool relocate)
 {
     WPHolder *ph;
-    bool refuse=TRUE;
+    bool refuse=TRUE, mcf;
     
     if((!relocate && !region_may_destroy(reg)) ||
        !region_manager_allows_destroying(reg)){
@@ -385,6 +377,7 @@ static bool region_rqclose_default(WRegion *reg, bool relocate)
     }
     
     ph=region_get_rescue_pholder(reg);
+    mcf=region_may_control_focus(reg);
     
     if(ph!=NULL){
         refuse=!region_rescue_clientwins(reg, ph);
@@ -396,7 +389,7 @@ static bool region_rqclose_default(WRegion *reg, bool relocate)
         return FALSE;
     }
 
-    mainloop_defer_destroy((Obj*)reg);
+    region_dispose(reg, mcf);
     
     return TRUE;
 }
@@ -478,6 +471,24 @@ bool region_manager_allows_destroying(WRegion *reg)
 }
 
 
+void region_dispose(WRegion *reg, bool was_mcf)
+{
+    if(was_mcf){
+        WPHolder *ph=region_get_return(reg);
+        if(ph!=NULL)
+            pholder_goto(ph);
+    }
+
+    mainloop_defer_destroy((Obj*)reg);
+}
+
+
+void region_dispose_(WRegion *reg)
+{
+    region_dispose(reg, region_may_control_focus(reg));
+}
+
+
 /*}}}*/
 
 
@@ -494,6 +505,7 @@ void region_detach_manager(WRegion *reg)
     if(mgr==NULL)
         return;
     
+#if 0
     /* Restore activity state to non-parent manager */
     if(region_may_control_focus(reg)){
         WRegion *par=REGION_PARENT_REG(reg);
@@ -504,11 +516,10 @@ void region_detach_manager(WRegion *reg)
              * be made to work.
              */
             par->active_sub=mgr;
-            /*if(region_xwindow(mgr)!=None){*/
-                region_do_set_focus(mgr, FALSE);
-            /*}*/
+            region_maybewarp_now(mgr, FALSE);
         }
     }
+#endif
 
     region_set_activity(reg, SETPARAM_UNSET);
 
@@ -518,6 +529,39 @@ void region_detach_manager(WRegion *reg)
 }
 
 
+void region_unset_manager_pseudoactivity(WRegion *reg)
+{
+    WRegion *mgr=reg->manager, *par=REGION_PARENT_REG(reg);
+    
+    if(mgr==NULL || mgr==par || !REGION_IS_PSEUDOACTIVE(mgr))
+        return;
+        
+    mgr->flags&=~REGION_PSEUDOACTIVE;
+    
+    region_notify_change(mgr, ioncore_g.notifies.pseudoinactivated);
+    
+    region_unset_manager_pseudoactivity(mgr);
+}
+
+
+void region_set_manager_pseudoactivity(WRegion *reg)
+{
+    WRegion *mgr=reg->manager, *par=REGION_PARENT_REG(reg);
+    
+    if(!REGION_IS_ACTIVE(reg) && !REGION_IS_PSEUDOACTIVE(reg))
+        return;
+        
+    if(mgr==NULL || mgr==par || REGION_IS_PSEUDOACTIVE(mgr))
+        return;
+    
+    mgr->flags|=REGION_PSEUDOACTIVE;
+    
+    region_notify_change(mgr, ioncore_g.notifies.pseudoactivated);
+    
+    region_set_manager_pseudoactivity(mgr);
+}
+
+
 /* This should only be called within region_managed_remove,
  * _after_ any managed lists and other essential structures
  * of mgr have been broken.
@@ -526,13 +570,17 @@ void region_unset_manager(WRegion *reg, WRegion *mgr)
 {
     if(reg->manager!=mgr)
         return;
+        
+    region_notify_change_(reg, ioncore_g.notifies.unset_manager);
+    
+    region_unset_manager_pseudoactivity(reg);
     
     reg->manager=NULL;
     
     if(region_is_activity_r(reg))
         region_clear_mgd_activity(mgr);
-
-    region_notify_change_(reg, "unset_manager", (Obj*)mgr);
+    
+    region_unset_return(reg);
 }
 
 
@@ -546,10 +594,12 @@ void region_set_manager(WRegion *reg, WRegion *mgr)
     
     reg->manager=mgr;
     
+    region_set_manager_pseudoactivity(reg);
+    
     if(region_is_activity_r(reg))
         region_mark_mgd_activity(mgr);
     
-    region_notify_change_(reg, "set_manager", (Obj*)mgr);
+    region_notify_change_(reg, ioncore_g.notifies.set_manager);
 }
 
 
@@ -776,54 +826,53 @@ void region_rootpos(WRegion *reg, int *xret, int *yret)
 }
 
 
-static bool mrsh_not(WHookDummy *fn, void *p)
+typedef struct{
+    WRegion *reg;
+    WRegionNotify how;
+} MRSHP;
+
+
+static bool mrsh_notify_change(WHookDummy *fn, void *p_)
 {
-    WRegion *reg=(WRegion*)((void**)p)[0];
-    const char *how=(const char*)((void**)p)[1];
-    Obj *detail=(Obj*)((void**)p)[2];
+    MRSHP *p=(MRSHP*)p_;
     
-    fn(reg, how, detail);
+    fn(p->reg, p->how);
     
     return TRUE;
 }
 
 
-static bool mrshe_not(ExtlFn fn, void *p)
+static bool mrshe_notify_change(ExtlFn fn, void *p_)
 {
-    WRegion *reg=(WRegion*)((void**)p)[0];
-    const char *how=(const char*)((void**)p)[1];
-    Obj *detail=(Obj*)((void**)p)[2];
+    MRSHP *p=(MRSHP*)p_;
     
-    extl_call(fn, "oso", NULL, reg, how, detail);
+    extl_call(fn, "os", NULL, p->reg, stringstore_get(p->how));
     
     return TRUE;
 }
 
 
-static void region_notify_change_(WRegion *reg, const char *how, 
-                                  Obj *detail)
+static void region_notify_change_(WRegion *reg, WRegionNotify how)
 {
-    const void *p[3];
+    MRSHP p;
+    
+    p.reg=reg;
+    p.how=how;
     
-    p[0]=reg;
-    p[1]=how;
-    p[2]=detail;
-
     extl_protect(NULL);
-    hook_call(region_notify_hook, p, mrsh_not, mrshe_not),
+    hook_call(region_notify_hook, &p, mrsh_notify_change, mrshe_notify_change),
     extl_unprotect(NULL);
-    
 }
 
 
-void region_notify_change(WRegion *reg, const char *how)
+void region_notify_change(WRegion *reg, WRegionNotify how)
 {
     WRegion *mgr=REGION_MANAGER(reg);
 
     if(mgr!=NULL)
         region_managed_notify(mgr, reg, how);
     
-    region_notify_change_(reg, how, NULL);
+    region_notify_change_(reg, how);
 }