]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/frame.c
[svn-upgrade] Integrating new upstream version, ion3 (20070203)
[ion3.git] / ioncore / frame.c
index 0f3e8f285e374d6a5908ed4e1afcf23e84c800ad..d733c3f46252d475be9d40f990281d86fc43c3dd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * ion/ioncore/frame.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
@@ -37,8 +37,9 @@
 #include "bindmaps.h"
 #include "regbind.h"
 #include "gr.h"
-#include "activity.h"
 #include "llist.h"
+#include "framedpholder.h"
+#include "return.h"
 
 
 extern bool frame_set_background(WFrame *frame, bool set_always);
@@ -91,7 +92,7 @@ bool frame_init(WFrame *frame, WWindow *parent, const WFitParams *fp,
     frame_initialise_titles(frame);
     
     region_add_bindmap((WRegion*)frame, ioncore_frame_bindmap);
-    region_add_bindmap((WRegion*)frame, ioncore_frame_toplevel_bindmap);
+    region_add_bindmap((WRegion*)frame, ioncore_mplex_bindmap);
     
     frame_add_mode_bindmaps(frame);
     
@@ -130,15 +131,18 @@ static void frame_add_mode_bindmaps(WFrame *frame)
 {
     WFrameMode mode=frame->mode;
     
-    if(mode==FRAME_MODE_TILED || mode==FRAME_MODE_TILED_ALT){
-       region_add_bindmap((WRegion*)frame, ioncore_frame_toplevel_bindmap);
-        region_add_bindmap((WRegion*)frame, ioncore_frame_tiled_bindmap);
-    }else if(mode==FRAME_MODE_FLOATING){
+    if(mode==FRAME_MODE_FLOATING){
+       region_add_bindmap((WRegion*)frame, ioncore_mplex_toplevel_bindmap);
        region_add_bindmap((WRegion*)frame, ioncore_frame_toplevel_bindmap);
         region_add_bindmap((WRegion*)frame, ioncore_frame_floating_bindmap);
     }else if(mode==FRAME_MODE_TRANSIENT){
         region_add_bindmap((WRegion*)frame, ioncore_frame_transient_bindmap);
-    }
+    }else{
+        /* mode==FRAME_MODE_TILED || mode==FRAME_MODE_TILED_ALT || mode==FRAME_MODE_UNKNOWN */
+       region_add_bindmap((WRegion*)frame, ioncore_mplex_toplevel_bindmap);
+       region_add_bindmap((WRegion*)frame, ioncore_frame_toplevel_bindmap);
+        region_add_bindmap((WRegion*)frame, ioncore_frame_tiled_bindmap);
+    } 
 }
 
 
@@ -151,6 +155,7 @@ void frame_set_mode(WFrame *frame, WFrameMode mode)
     
     frame_release_brushes(frame);
     
+    region_remove_bindmap((WRegion*)frame, ioncore_mplex_toplevel_bindmap);
     region_remove_bindmap((WRegion*)frame, ioncore_frame_toplevel_bindmap);
     region_remove_bindmap((WRegion*)frame, ioncore_frame_tiled_bindmap);
     region_remove_bindmap((WRegion*)frame, ioncore_frame_floating_bindmap);
@@ -175,6 +180,7 @@ WFrameMode frame_mode(WFrame *frame)
 
 
 StringIntMap frame_modes[]={
+    {"unknown", FRAME_MODE_UNKNOWN},
     {"tiled", FRAME_MODE_TILED},
     {"tiled-alt", FRAME_MODE_TILED_ALT},
     {"floating", FRAME_MODE_FLOATING},
@@ -186,6 +192,7 @@ StringIntMap frame_modes[]={
 /*EXTL_DOC
  * Get frame mode.
  */
+EXTL_SAFE
 EXTL_EXPORT_AS(WFrame, mode)
 const char *frame_mode_extl(WFrame *frame)
 {
@@ -299,46 +306,6 @@ int frame_nth_tab_iw(WFrame *frame, int n)
 
 
 
-static void update_attr(WFrame *frame, int i, WRegion *reg)
-{
-    int flags=0;
-    static char *attrs[]={
-        "unselected-not_tagged-not_dragged-no_activity",
-        "selected-not_tagged-not_dragged-no_activity",
-        "unselected-tagged-not_dragged-no_activity",
-        "selected-tagged-not_dragged-no_activity",
-        "unselected-not_tagged-dragged-no_activity",
-        "selected-not_tagged-dragged-no_activity",
-        "unselected-tagged-dragged-no_activity",
-        "selected-tagged-dragged-no_activity",
-        "unselected-not_tagged-not_dragged-activity",
-        "selected-not_tagged-not_dragged-activity",
-        "unselected-tagged-not_dragged-activity",
-        "selected-tagged-not_dragged-activity",
-        "unselected-not_tagged-dragged-activity",
-        "selected-not_tagged-dragged-activity",
-        "unselected-tagged-dragged-activity",
-        "selected-tagged-dragged-activity"
-    };
-
-    if(i>=frame->titles_n){
-        /* Might happen when deinitialising */
-        return;
-    }
-    
-    if(reg==FRAME_CURRENT(frame))
-        flags|=0x01;
-    if(reg!=NULL && reg->flags&REGION_TAGGED)
-        flags|=0x02;
-    if(i==frame->tab_dragged_idx)
-        flags|=0x04;
-    if(reg!=NULL && region_is_activity_r(reg))
-        flags|=0x08;
-    
-    frame->titles[i].attr=attrs[flags];
-}
-
-
 void frame_update_attr_nth(WFrame *frame, int i)
 {
     WRegion *reg;
@@ -346,18 +313,18 @@ void frame_update_attr_nth(WFrame *frame, int i)
     if(i<0 || i>=frame->titles_n)
         return;
 
-    update_attr(frame, i, mplex_mx_nth((WMPlex*)frame, i));
+    frame_update_attr(frame, i, mplex_mx_nth((WMPlex*)frame, i));
 }
 
 
-static void update_attrs(WFrame *frame)
+static void frame_update_attrs(WFrame *frame)
 {
     int i=0;
     WRegion *sub;
     WLListIterTmp tmp;
     
     FRAME_MX_FOR_ALL(sub, frame, tmp){
-        update_attr(frame, i, sub);
+        frame_update_attr(frame, i, sub);
         i++;
     }
 }
@@ -371,6 +338,7 @@ static void frame_free_titles(WFrame *frame)
         for(i=0; i<frame->titles_n; i++){
             if(frame->titles[i].text)
                 free(frame->titles[i].text);
+            gr_stylespec_unalloc(&frame->titles[i].attr);
         }
         free(frame->titles);
         frame->titles=NULL;
@@ -383,7 +351,10 @@ static void do_init_title(WFrame *frame, int i, WRegion *sub)
 {
     frame->titles[i].text=NULL;
     frame->titles[i].iw=frame_nth_tab_iw(frame, i);
-    update_attr(frame, i, sub);
+    
+    gr_stylespec_init(&frame->titles[i].attr);
+    
+    frame_update_attr(frame, i, sub);
 }
 
 
@@ -551,6 +522,74 @@ void frame_activated(WFrame *frame)
 }
 
 
+void frame_quasiactivation(WFrame *frame, WRegion *reg, bool act)
+{
+    bool was, is;
+    
+    was=(frame->quasiactive_count>0);
+    
+    frame->quasiactive_count=maxof(0, frame->quasiactive_count 
+                                       + (act ? 1 : -1));
+                                       
+    is=(frame->quasiactive_count>0);
+    
+    if(was!=is && !REGION_IS_ACTIVE(frame))
+        window_draw((WWindow*)frame, FALSE);
+}
+
+
+static bool actinact(WRegion *reg, bool act)
+{
+    WPHolder *returnph=region_get_return(reg);
+    WFrame *frame;
+    
+    if(returnph==NULL || pholder_stale(returnph))
+        return FALSE;
+    
+    frame=OBJ_CAST(pholder_target(returnph), WFrame);
+    
+    if(frame!=NULL){
+        /* Ok, reg has return placeholder set to a frame: 
+         * do quasiactivation/inactivation 
+         */
+        frame_quasiactivation(frame, reg, act);
+    }
+    
+    return TRUE;
+}
+
+
+static bool activated(WRegion *reg)
+{
+    return actinact(reg, TRUE);
+}
+
+
+static bool inactivated(WRegion *reg)
+{
+    return actinact(reg, FALSE);
+}
+
+
+void ioncore_frame_quasiactivation_notify(WRegion *reg, 
+                                          WRegionNotify how)
+{
+    if(how==ioncore_g.notifies.activated || 
+       how==ioncore_g.notifies.pseudoactivated){
+        activated(reg);
+    }else if(how==ioncore_g.notifies.inactivated ||
+             how==ioncore_g.notifies.pseudoinactivated){
+        inactivated(reg);
+    }else if(how==ioncore_g.notifies.set_return){
+        if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg))
+            activated(reg);
+    }else if(how==ioncore_g.notifies.unset_return){
+        if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg))
+            inactivated(reg);
+    }
+}
+
+
 /*}}}*/
 
 
@@ -620,6 +659,73 @@ static void frame_managed_rqgeom_absolute(WFrame *frame, WRegion *sub,
 /*}}}*/
 
 
+/*{{{ Frame recreate pholder stuff */
+
+
+static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame)
+{
+    WPHolder *ph;
+    WFramedPHolder *fph;
+    WFramedParam fparam=FRAMEDPARAM_INIT;
+    
+    ph=region_make_return_pholder((WRegion*)frame);
+    
+    if(ph==NULL)
+        return NULL;
+        
+    fparam.mode=frame->mode;
+    
+    fph=create_framedpholder(ph, &fparam);
+    
+    if(fph==NULL){
+        destroy_obj((Obj*)ph);
+        return NULL;
+    }
+    
+    return fph;
+}
+
+
+static void mplex_flatten_phs(WMPlex *mplex)
+{
+    WLListNode *node;
+    WLListIterTmp tmp;
+
+    FOR_ALL_NODES_ON_LLIST(node, mplex->mx_list, tmp){
+        WMPlexPHolder *last=(mplex->mx_phs==NULL ? NULL : mplex->mx_phs->prev);
+        mplex_move_phs(mplex, node, last, NULL);
+    }
+}
+
+
+static void frame_modify_pholders(WFrame *frame)
+{
+    WFramedPHolder *fph;
+    WMPlexPHolder *phs, *ph;
+    
+    mplex_flatten_phs(&frame->mplex);
+    
+    if(frame->mplex.mx_phs==NULL)
+        return;
+    
+    fph=frame_make_recreate_pholder(frame);
+    
+    if(fph==NULL)
+        return;
+    
+    phs=frame->mplex.mx_phs;
+    frame->mplex.mx_phs=NULL;
+    
+    phs->recreate_pholder=fph;
+    
+    for(ph=phs; ph!=NULL; ph=ph->next)
+        watch_reset(&ph->mplex_watch);
+}
+
+
+/*}}}*/
+
+
 /*{{{ Misc. */
 
 
@@ -724,9 +830,9 @@ bool frame_is_numbers(WFrame *frame)
 }
 
 
-void frame_managed_notify(WFrame *frame, WRegion *sub, const char *how)
+void frame_managed_notify(WFrame *frame, WRegion *sub, WRegionNotify how)
 {
-    update_attrs(frame);
+    frame_update_attrs(frame);
     frame_recalc_bar(frame);
     frame_draw_bar(frame, FALSE);
 }
@@ -755,7 +861,7 @@ static void frame_managed_changed(WFrame *frame, int mode, bool sw,
     if(mode!=MPLEX_CHANGE_SWITCHONLY)
         frame_initialise_titles(frame);
     else
-        update_attrs(frame);
+        frame_update_attrs(frame);
 
     if(sw)
         need_draw=!frame_set_background(frame, FALSE);
@@ -776,8 +882,10 @@ static void frame_managed_changed(WFrame *frame, int mode, bool sw,
 
 static void frame_destroy_empty(WFrame *frame)
 {
-    if(EMPTY_AND_SHOULD_BE_DESTROYED(frame))
+    if(EMPTY_AND_SHOULD_BE_DESTROYED(frame)){
+        frame_modify_pholders(frame);
         destroy_obj((Obj*)frame);
+    }
 }