]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/frame.c
Update cfg_kludge_flash for Flash 10
[ion3.git] / ioncore / frame.c
index bcecf23c557d6ea607c629731c22e9f8e60322ec..4f82aa4fa951a37b7b0d6601a569a542f5c811e9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * ion/ioncore/frame.c
  *
- * Copyright (c) Tuomo Valkonen 1999-2007
+ * Copyright (c) Tuomo Valkonen 1999-2009
  *
  * See the included file LICENSE for details.
  */
@@ -50,11 +50,32 @@ static void frame_add_mode_bindmaps(WFrame *frame);
 
 WHook *frame_managed_changed_hook=NULL;
 
-#define IS_FLOATING_MODE(FRAME) \
-    ((FRAME)->mode==FRAME_MODE_FLOATING || (FRAME)->mode==FRAME_MODE_TRANSIENT)
-#define FORWARD_CWIN_RQGEOM(FRAME) IS_FLOATING_MODE(FRAME)
-#define USE_MINMAX(FRAME) IS_FLOATING_MODE(FRAME)
-#define DEST_EMPTY(FRAME) IS_FLOATING_MODE(FRAME)
+#define FORWARD_CWIN_RQGEOM(FRAME) framemode_is_floating(frame_mode(FRAME))
+#define USE_MINMAX(FRAME) framemode_is_floating(frame_mode(FRAME))
+#define DEST_EMPTY(FRAME) framemode_is_floating(frame_mode(FRAME))
+
+
+WFrameMode framemode_unalt(WFrameMode mode)
+{
+    if(mode==FRAME_MODE_UNKNOWN_ALT)
+        return FRAME_MODE_UNKNOWN;
+    else if(mode==FRAME_MODE_TILED_ALT)
+        return FRAME_MODE_TILED;
+    else if(mode==FRAME_MODE_FLOATING_ALT)
+        return FRAME_MODE_FLOATING;
+    else if(mode==FRAME_MODE_TRANSIENT_ALT)
+        return FRAME_MODE_TRANSIENT;
+    else
+        return mode;
+}
+
+
+static WFrameMode framemode_is_floating(WFrameMode mode)
+{
+    WFrameMode modea=framemode_unalt(mode);
+    
+    return (modea==FRAME_MODE_FLOATING || modea==FRAME_MODE_TRANSIENT);
+}
 
 
 /*{{{ Destroy/create frame */
@@ -81,7 +102,6 @@ bool frame_init(WFrame *frame, WWindow *parent, const WFitParams *fp,
     frame->mode=mode;
     frame->tab_min_w=0;
     frame->bar_max_width_q=1.0;
-    frame->quasiact_source=NULL;
     
     gr_stylespec_init(&frame->baseattr);
     
@@ -130,13 +150,13 @@ void frame_deinit(WFrame *frame)
 
 static void frame_add_mode_bindmaps(WFrame *frame)
 {
-    WFrameMode mode=frame->mode;
+    WFrameMode modea=framemode_unalt(frame->mode);
     
-    if(mode==FRAME_MODE_FLOATING){
+    if(modea==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){
+    }else if(modea==FRAME_MODE_TRANSIENT){
         region_add_bindmap((WRegion*)frame, ioncore_frame_transient_bindmap);
         region_add_bindmap((WRegion*)frame, ioncore_frame_floating_bindmap);
     }else{
@@ -164,14 +184,10 @@ void frame_set_mode(WFrame *frame, WFrameMode mode)
     region_remove_bindmap((WRegion*)frame, ioncore_frame_transient_bindmap);
     
     frame->mode=mode;
-
-    frame_add_mode_bindmaps(frame);
     
-    frame_initialise_gr(frame);
+    frame_add_mode_bindmaps(frame);
     
-    mplex_fit_managed(&frame->mplex);
-    frame_recalc_bar(frame);
-    frame_set_background(frame, TRUE);
+    frame_updategr(frame);
 }
 
 
@@ -181,12 +197,15 @@ WFrameMode frame_mode(WFrame *frame)
 }
 
 
-StringIntMap frame_modes[]={
+static StringIntMap frame_modes[]={
     {"unknown", FRAME_MODE_UNKNOWN},
+    {"unknown-alt", FRAME_MODE_UNKNOWN_ALT},
     {"tiled", FRAME_MODE_TILED},
     {"tiled-alt", FRAME_MODE_TILED_ALT},
     {"floating", FRAME_MODE_FLOATING},
+    {"floating-alt", FRAME_MODE_FLOATING_ALT},
     {"transient", FRAME_MODE_TRANSIENT},
+    {"transient-alt", FRAME_MODE_TRANSIENT_ALT},
     END_STRINGINTMAP
 };
 
@@ -203,7 +222,9 @@ const char *frame_mode_extl(WFrame *frame)
 
 
 /*EXTL_DOC
- * Set frame mode.
+ * Set frame mode (one of
+ * \codestr{unknown}, \codestr{tiled}, \codestr{floating}, \codestr{transient},
+ * or any of these suffixed with \codestr{-alt}).
  */
 EXTL_EXPORT_AS(WFrame, set_mode)
 bool frame_set_mode_extl(WFrame *frame, const char *modestr)
@@ -386,7 +407,7 @@ static bool frame_initialise_titles(WFrame *frame)
         }
     }
     
-    frame_recalc_bar(frame);
+    frame_recalc_bar(frame, FALSE);
 
     return TRUE;
 }
@@ -406,7 +427,8 @@ bool frame_fitrep(WFrame *frame, WWindow *par, const WFitParams *fp)
     
     old_geom=REGION_GEOM(frame);
     
-    window_do_fitrep(&(frame->mplex.win), par, &(fp->g));
+    if(!window_fitrep(&(frame->mplex.win), par, fp))
+        return FALSE;
 
     mplex_managed_geom((WMPlex*)frame, &mg);
     
@@ -453,36 +475,36 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret)
     woff=maxof(REGION_GEOM(frame).w-subgeom.w, 0);
     hoff=maxof(REGION_GEOM(frame).h-subgeom.h, 0);
 
-    if(FRAME_CURRENT(frame)!=NULL){
+    if(FRAME_CURRENT(frame)!=NULL)
         region_size_hints(FRAME_CURRENT(frame), hints_ret);
-        if(!USE_MINMAX(frame)){
-            hints_ret->max_set=0;
-            hints_ret->min_set=0;
-            /*hints_ret->base_set=0;*/
-            hints_ret->aspect_set=0;
-            hints_ret->no_constrain=FALSE;
-            /*hints_ret->no_constrain=TRUE;*/
-        }
-    }else{
+    else
         sizehints_clear(hints_ret);
-    }
     
     FRAME_MX_FOR_ALL(sub, frame, tmp){
         sizehints_adjust_for(hints_ret, sub);
     }
     
-    if(!hints_ret->base_set){
-        hints_ret->base_width=0;
-        hints_ret->base_height=0;
-        hints_ret->base_set=TRUE;
+    if(!USE_MINMAX(frame)){
+        hints_ret->max_set=0;
+        hints_ret->min_set=0;
+        /*hints_ret->base_set=0;*/
+        hints_ret->aspect_set=0;
+        hints_ret->no_constrain=FALSE;
+        /*hints_ret->no_constrain=TRUE;*/
     }
-
+    
     if(!hints_ret->min_set){
         hints_ret->min_width=0;
         hints_ret->min_height=0;
         hints_ret->min_set=TRUE;
     }
     
+    if(!hints_ret->base_set){
+        hints_ret->base_width=0;
+        hints_ret->base_height=0;
+        hints_ret->base_set=TRUE;
+    }
+    
     hints_ret->base_width+=woff;
     hints_ret->base_height+=hoff;
     hints_ret->max_width+=woff;
@@ -490,13 +512,14 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret)
     hints_ret->min_width+=woff;
     hints_ret->min_height+=hoff;
     
-    if(frame->barmode==FRAME_BAR_SHAPED){
+    /* shaded */ {
         int f=frame->flags&(FRAME_SHADED|FRAME_SHADED_TOGGLE);
         
         if(f==FRAME_SHADED || f==FRAME_SHADED_TOGGLE){
-            hints_ret->min_height=frame->bar_h;
-            hints_ret->max_height=frame->bar_h;
-            hints_ret->base_height=frame->bar_h;
+            int h=frame_shaded_height(frame);
+            hints_ret->min_height=h;
+            hints_ret->max_height=h;
+            hints_ret->base_height=h;
             if(!hints_ret->max_set){
                 hints_ret->max_width=INT_MAX;
                 hints_ret->max_set=TRUE;
@@ -509,97 +532,6 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret)
 /*}}}*/
 
 
-/*{{{ Focus  */
-
-
-static void frame_quasiactivation(WFrame *frame, Obj *src, bool act)
-{
-    if(frame->quasiact_source==src || act){
-        bool was, is;
-        
-        was=(frame->quasiact_source!=NULL);
-    
-        frame->quasiact_source=(act ? src : NULL);
-    
-        is=(frame->quasiact_source!=NULL);
-        
-        if(was!=is){
-            frame_quasiactivity_change(frame);
-            if(!REGION_IS_ACTIVE(frame))
-                window_draw((WWindow*)frame, FALSE);
-        }
-    }
-}
-
-
-static bool actinact(WRegion *reg, bool act)
-{
-    WPHolder *returnph=region_get_return(reg);
-    WFrame *frame=NULL;
-    Obj *src=NULL;
-    WRegion *tgt;
-    
-    if(returnph==NULL || pholder_stale(returnph))
-        return FALSE;
-    
-    tgt=pholder_target(returnph);
-
-    frame=OBJ_CAST(tgt, WFrame);
-    
-    if(frame!=NULL){
-        src=(Obj*)returnph;
-    }else{
-        /* Show quasiactivation for stuff detached from
-         * groups contained in the frame as well.
-         */
-        WGroup *grp=OBJ_CAST(tgt, WGroup);
-        if(grp!=NULL){
-            frame=REGION_MANAGER_CHK(grp, WFrame);
-            src=(Obj*)grp;
-        }
-    }
-    
-    if(frame!=NULL)
-        frame_quasiactivation(frame, src, 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);
-    }
-}
-
-
-/*}}}*/
-
-
 /*{{{ Client window rqgeom */
 
 
@@ -669,75 +601,78 @@ static void frame_managed_rqgeom_absolute(WFrame *frame, WRegion *sub,
 /*{{{ Frame recreate pholder stuff */
 
 
-static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame)
+static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame, WPHolder *rph)
 {
-    WPHolder *ph;
-    WFramedPHolder *fph;
     WFramedParam fparam=FRAMEDPARAM_INIT;
+    WFramedPHolder *fph=NULL;
     
-    ph=region_make_return_pholder((WRegion*)frame);
-    
-    if(ph==NULL){
-        return NULL;
-    }
-    
-    fparam.mode=frame->mode;
+    if(rph!=NULL){
+        fparam.mode=frame->mode;
     
-    fph=create_framedpholder(ph, &fparam);
+        fph=create_framedpholder(rph, &fparam);
     
-    if(fph==NULL){
-        destroy_obj((Obj*)ph);
-        return NULL;
+        if(fph==NULL)
+            destroy_obj((Obj*)rph);
     }
     
     return fph;
 }
 
 
-static void mplex_flatten_phs(WMPlex *mplex)
+static void mplex_migrate_phs_to_fph(WMPlex *mplex, WFramedPHolder *fph)
 {
-    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=mplex->misc_phs;
+    mplex->misc_phs=NULL;
     
     phs->recreate_pholder=fph;
     
     for(ph=phs; ph!=NULL; ph=ph->next)
-        watch_reset(&ph->mplex_watch);
+        ph->mplex=NULL;
 }
 
 
+
 bool frame_rescue_clientwins(WFrame *frame, WRescueInfo *info)
 {
-    frame_modify_pholders(frame);
-    return mplex_rescue_clientwins(&frame->mplex, info);
+    bool ret;
+    
+    ret=mplex_rescue_clientwins(&frame->mplex, info);
+    
+    /* Now, do placeholders. 
+     * We can't currently be arsed to keep them ordered with regions...
+     * First we check if we can simply recreate this frame, which takes
+     * care of e.g. floating frames being destroyed when entering full
+     * screen mode. If not, we check if the target would be a WMPlex, and
+     * migrate there. This takes care of frames destroyed in tilings.
+     */
+    mplex_flatten_phs(&frame->mplex);
+    
+    if(frame->mplex.misc_phs!=NULL){
+        WPHolder *ret_ph=region_make_return_pholder((WRegion*)frame);
+        WFramedPHolder *fph=frame_make_recreate_pholder(frame, ret_ph);
+        
+        if(fph!=NULL){
+            mplex_migrate_phs_to_fph(&frame->mplex, fph);
+        }else{
+            WPHolder *rescueph=rescueinfo_pholder(info);
+            if(rescueph!=NULL){
+                WRegion *target=pholder_target(rescueph);
+                WMPlex *other_mplex=OBJ_CAST(target, WMPlex);
+                    
+                if(other_mplex!=NULL){
+                    assert(other_mplex!=&frame->mplex);
+                    mplex_migrate_phs(&frame->mplex, other_mplex);
+                }
+            }
+        }
+    }
+    
+    return ret;
 }
 
-    
+
 /*}}}*/
 
 
@@ -763,17 +698,9 @@ bool frame_set_shaded(WFrame *frame, int sp)
             return FALSE;
         rq.geom.h=frame->saved_h;
     }else{
-        if(frame->barmode==FRAME_BAR_NONE){
+        if(frame->barmode==FRAME_BAR_NONE)
             return FALSE;
-        }else if(frame->barmode==FRAME_BAR_SHAPED){
-            rq.geom.h=frame->bar_h;
-        }else{
-            WRectangle tmp;
-            
-            frame_border_inner_geom(frame, &tmp);
-            
-            rq.geom.h=rq.geom.h-tmp.h;
-        }
+        rq.geom.h=frame_shaded_height(frame);
     }
     
     frame->flags|=FRAME_SHADED_TOGGLE;
@@ -868,7 +795,7 @@ void frame_managed_notify(WFrame *frame, WRegion *sub, WRegionNotify how)
        how==ioncore_g.notifies.tag){
        
         frame_update_attrs(frame);
-        frame_recalc_bar(frame);
+        frame_recalc_bar(frame, FALSE);
         frame_draw_bar(frame, FALSE);
     }
 }
@@ -880,7 +807,7 @@ static void frame_size_changed_default(WFrame *frame,
     int bar_w=frame->bar_w;
     
     if(wchg)
-        frame_recalc_bar(frame);
+        frame_recalc_bar(frame, TRUE);
     
     if(frame->barmode==FRAME_BAR_SHAPED &&
        ((!wchg && hchg) || (wchg && bar_w==frame->bar_w))){
@@ -894,14 +821,6 @@ static void frame_managed_changed(WFrame *frame, int mode, bool sw,
 {
     bool need_draw=TRUE;
     
-    if(mode==MPLEX_CHANGE_REMOVE && (Obj*)reg==frame->quasiact_source){
-        /* Reset indirect quasiactivation through group that
-         * is being removed.
-         */
-        frame->quasiact_source=NULL;
-        frame_quasiactivity_change(frame);
-    }
-    
     if(mode!=MPLEX_CHANGE_SWITCHONLY)
         frame_initialise_titles(frame);
     else
@@ -924,7 +843,7 @@ WRegion *frame_managed_disposeroot(WFrame *frame, WRegion *reg)
     if(DEST_EMPTY(frame) &&
        frame->mplex.mgd!=NULL && 
        frame->mplex.mgd->reg==reg && 
-       frame->mplex.mgd->next==NULL){
+       frame->mplex.mgd->mgr_next==NULL){
         WRegion *tmp=region_disposeroot((WRegion*)frame);
         return (tmp!=NULL ? tmp : reg);
     }
@@ -953,7 +872,7 @@ WPHolder *frame_prepare_manage_transient(WFrame *frame,
     /* Transient manager searches should not cross tiled frames
      * unless explicitly floated.
      */
-    if(IS_FLOATING_MODE(frame) ||
+    if(framemode_is_floating(frame_mode(frame)) ||
        extl_table_is_bool_set(transient->proptab, "float")){
         return region_prepare_manage_transient_default((WRegion*)frame,
                                                        transient,
@@ -1020,7 +939,13 @@ WRegion *frame_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
     int mode=FRAME_MODE_UNKNOWN;
     WFrame *frame;
     
-    extl_table_gets_i(tab, "mode", &mode);
+    if(!extl_table_gets_i(tab, "mode", &mode)){
+        char *tmp;
+        if(extl_table_gets_s(tab, "mode", &tmp)){
+            mode=stringintmap_value(frame_modes, tmp, mode);
+            free(tmp);
+        }
+    }
     
     frame=create_frame(par, fp, mode);
     
@@ -1028,6 +953,14 @@ WRegion *frame_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
         frame_do_load(frame, tab);
     
     if(DEST_EMPTY(frame) && frame->mplex.mgd==NULL){
+        if(frame->mplex.misc_phs!=NULL){
+            /* Session management hack */
+            WFramedPHolder *fph;
+            fph=frame_make_recreate_pholder(frame, ioncore_get_load_pholder());
+            if(fph!=NULL)
+                mplex_migrate_phs_to_fph(&frame->mplex, fph);
+        }
+        
         destroy_obj((Obj*)frame);
         return NULL;
     }