]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/mplex.c
Add 20071109-1.
[ion3.git] / ioncore / mplex.c
index 71943a4595ca6829fe6da5ea8b267669eb3fe320..da1bd49b48218c0bd4cfd631cd097ed2fbf56646 100644 (file)
@@ -231,8 +231,8 @@ WRegion *mplex_mx_current(WMPlex *mplex)
 
 
 /*EXTL_DOC
- * Returns the \var{n}:th object managed by \var{mplex} on the
- * \var{l}:th layer.
+ * Returns the \var{n}:th object on the mutually exclusive
+ * list of \var{mplex}.
  */
 EXTL_SAFE
 EXTL_EXPORT_MEMBER
@@ -505,6 +505,27 @@ static void mplex_managed_rqgeom(WMPlex *mplex, WRegion *sub,
 }
 
 
+void mplex_set_szplcy(WMPlex *mplex, WRegion *sub, WSizePolicy szplcy)
+{
+    WStacking *node;
+
+    node=mplex_find_stacking(mplex, sub);
+    
+    if(node!=NULL)
+        node->szplcy=szplcy;
+}
+
+
+WSizePolicy mplex_get_szplcy(WMPlex *mplex, WRegion *sub)
+{
+    WStacking *node;
+
+    node=mplex_find_stacking(mplex, sub);
+    
+    return (node==NULL ? SIZEPOLICY_DEFAULT : node->szplcy);
+}
+
+
 /*}}}*/
 
 
@@ -630,7 +651,7 @@ static WStacking *mplex_do_to_focus(WMPlex *mplex, WStacking *to_try,
 
 static WStacking *mplex_do_to_focus_on(WMPlex *mplex, WStacking *node,
                                        WStacking *to_try, 
-                                       PtrList **hidelist)
+                                       PtrList **hidelist, bool *within)
 {
     WGroup *grp=OBJ_CAST(node->reg, WGroup);
     WStacking *st;
@@ -638,26 +659,21 @@ static WStacking *mplex_do_to_focus_on(WMPlex *mplex, WStacking *node,
     if(grp!=NULL){
         if(to_try==NULL)
             to_try=grp->current_managed;
+        /* Only will return stuff within 'node' */
         st=mplex_find_to_focus(mplex, to_try, node, hidelist);
-        if(st!=NULL || to_try!=NULL)
+        if(st!=NULL){
+            if(within!=NULL)
+                *within=TRUE;
             return st;
-        if(hidelist!=NULL)
-            ptrlist_clear(hidelist);
-        /* We don't know whether something is blocking focus here,
-         * or if there was nothing to focus (as node->reg itself
-         * isn't on the stacking list).
-         */
+        }
     }
     
     st=mplex_do_to_focus(mplex, node, hidelist);
     
-    if(st==node)
-        return st;
+    if(st==node && within!=NULL)
+        *within=TRUE;
         
-    if(hidelist!=NULL)
-        ptrlist_clear(hidelist);
-    
-    return NULL;
+    return st;
 }
 
 
@@ -816,22 +832,18 @@ static void mplex_do_node_display(WMPlex *mplex, WStacking *node,
 static bool mplex_refocus(WMPlex *mplex, WStacking *node, bool warp)
 {
     WStacking *foc=NULL;
-    bool ret=TRUE;
+    bool within=FALSE;
     
-    if(node!=NULL){
-        foc=mplex_do_to_focus_on(mplex, node, NULL, NULL);
-        ret=(foc!=NULL);
-    }
+    if(node!=NULL)
+        foc=mplex_do_to_focus_on(mplex, node, NULL, NULL, &within);
         
-    if(foc==NULL){
-        ret=FALSE;
+    if(foc==NULL || !within)
         foc=mplex_to_focus(mplex);
-    }
     
     if(foc!=NULL)
         region_maybewarp(foc->reg, warp);
     
-    return ret;
+    return within;
 }
 
 
@@ -843,6 +855,7 @@ bool mplex_do_prepare_focus(WMPlex *mplex, WStacking *node,
     PtrList *hidelist=NULL;
     PtrList **hidelistp=(ew ? NULL : &hidelist);
     WStacking *foc;
+    /*bool within=FALSE;*/
     
     if(sub==NULL && node==NULL)
         return FALSE;
@@ -854,10 +867,7 @@ bool mplex_do_prepare_focus(WMPlex *mplex, WStacking *node,
     if(!region_prepare_focus((WRegion*)mplex, flags, res))
         return FALSE;
 
-    if(node!=NULL)
-        foc=mplex_do_to_focus_on(mplex, node, sub, hidelistp);
-    else
-        foc=mplex_do_to_focus(mplex, sub, hidelistp);
+    foc=mplex_do_to_focus_on(mplex, node, sub, hidelistp, NULL /*&within*/);
 
     if(foc!=NULL){
         while(hidelist!=NULL){
@@ -876,10 +886,7 @@ bool mplex_do_prepare_focus(WMPlex *mplex, WStacking *node,
         res->reg=foc->reg;
         res->flags=flags;
         
-        if(sub==NULL)
-            return (foc==node);
-        else
-            return (foc==sub);
+        return (foc==sub || (sub==NULL && foc==node));
     }else{
         return FALSE;
     }
@@ -1162,7 +1169,6 @@ bool mplex_managed_rqorder(WMPlex *mplex, WRegion *reg, WRegionOrder order)
 static bool mplex_stack(WMPlex *mplex, WStacking *st)
 {
     WStacking *tmp=NULL;
-    Window bottom=None, top=None;
     WStacking **stackingp=mplex_get_stackingp(mplex);
     
     if(stackingp==NULL)
@@ -1225,7 +1231,7 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph)
     
     sw=(!hidden && (param->flags&MPLEX_ATTACH_SWITCHTO 
                     || (param->flags&MPLEX_ATTACH_UNNUMBERED
-                        ? modal
+                        ? FALSE
                         : (mplex_current_node(mplex)==NULL))));
     
     hidden=(hidden || (!sw && !(param->flags&MPLEX_ATTACH_UNNUMBERED)));
@@ -1263,14 +1269,19 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph)
     node->pseudomodal=(param->flags&MPLEX_ATTACH_PSEUDOMODAL ? 1 : 0);
     
     if(lnode!=NULL){
+        WMPlexPHolder *ph2, *phn, *php;
+        
         llist_link_after(&(mplex->mx_list), 
                          (ph!=NULL ? ph->after : NULL), 
                          lnode);
         mplex->mx_count++;
         
-        /* Move following placeholders after new node */
-        while(ph->next!=NULL)
-            mplexpholder_move(ph->next, mplex, NULL, lnode);
+        
+        /* Move placeholders after new node */
+        for(php=NULL, ph2=ph; ph2!=NULL; php=ph2, ph2=phn){
+            phn=ph2->next;
+            mplexpholder_move(ph2, mplex, php, lnode);
+        }
     }
     
     LINK_ITEM(mplex->mgd, node, mgr_next, mgr_prev);
@@ -1280,6 +1291,9 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph)
     
     region_set_manager(reg, (WRegion*)mplex);
     
+    if(param->flags&MPLEX_ATTACH_PASSIVE)
+        reg->flags|=REGION_SKIP_FOCUS;
+    
     if(!(param->flags&MPLEX_ATTACH_WHATEVER)){
         WFitParams fp;
         
@@ -1297,9 +1311,20 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph)
         mplex_do_node_display(mplex, node, FALSE);
     else
         region_unmap(reg);
-    
-    if(sw && mcf)
-        mplex_refocus(mplex, node, FALSE);
+        
+    if(mcf){
+        if(sw){
+            mplex_refocus(mplex, node, FALSE);
+        }else if(!hidden && 
+                 (level>=STACKING_LEVEL_MODAL1 || OBJ_IS(reg, WGroup))){
+            /* New modal regions may require focusing, so try to
+             * give focus back to currently active object.
+             * (There seems to be some problem with uncontained
+             * client windows still..)
+             */
+            mplex_refocus(mplex, NULL, FALSE);
+        }
+    }
     
     if(lnode!=NULL)
         mplex_managed_changed(mplex, MPLEX_CHANGE_ADD, sw, reg);
@@ -1382,7 +1407,6 @@ WRegion *mplex_attach_simple(WMPlex *mplex, WRegion *reg, int flags)
 static void get_params(WMPlex *mplex, ExtlTab tab, int mask,
                        WMPlexAttachParams *par)
 {
-    int layer=1;
     int tmp;
     char *tmpstr;
     int ok=~mask;
@@ -1408,6 +1432,9 @@ static void get_params(WMPlex *mplex, ExtlTab tab, int mask,
     if(extl_table_is_bool_set(tab, "hidden"))
         par->flags|=MPLEX_ATTACH_HIDDEN&ok;
         
+    if(extl_table_is_bool_set(tab, "passive"))
+        par->flags|=MPLEX_ATTACH_PASSIVE&ok;
+        
     if(extl_table_is_bool_set(tab, "pseudomodal"))
         par->flags|=MPLEX_ATTACH_PSEUDOMODAL&ok;
 
@@ -1489,6 +1516,7 @@ WRegion *mplex_attach_new_(WMPlex *mplex, WMPlexAttachParams *par,
  *  \var{hidden} & (boolean) Attach hidden, if not prevented
  *                  by e.g. the mutually exclusive list being empty.
  *                  This option overrides \var{switchto}. \\
+ *  \var{passive} & (boolean) Skip in certain focusing operations. \\
  *  \var{pseudomodal} & (boolean) The attached region is ``pseudomodal''
  *                      if the stacking level dictates it to be modal.
  *                      This means that the region may be hidden to display
@@ -1653,7 +1681,20 @@ bool mplex_rescue_clientwins(WMPlex *mplex, WRescueInfo *info)
 {
     bool ret1, ret2;
     WMPlexIterTmp tmp;
+    WLListIterTmp ltmp;
+    WLListNode *lnode, *was_current=mplex->mx_current;
+    
+    /* First all mx stuff to move them nicely to another mplex (when that 
+     * is the case), switching to the current region in the target if 
+     * allowed by ph_flags_mask region_rescue.
+     */
+    FOR_ALL_NODES_ON_LLIST(lnode, mplex->mx_list, ltmp){
+        int sw=(lnode==was_current ? PHOLDER_ATTACH_SWITCHTO : 0);
+        region_do_rescue_this(lnode->st->reg, info, sw);
+    }
     
+    /* Then the rest (possibly retrying failed mx stuff).
+     */
     mplex_iter_init(&tmp, mplex);
     ret1=region_rescue_some_clientwins((WRegion*)mplex, info,
                                        (WRegionIterator*)mplex_iter,
@@ -1772,11 +1813,12 @@ static bool do_attach_stdisp(WRegion *mplex, WRegion *reg, void *unused)
  * 
  * \begin{tabularx}{\linewidth}{lX}
  *   \tabhead{Field & Description}
- *   \var{pos} & The corner of the screen to place the status display
- *               in: one of \codestr{tl}, \codestr{tr}, \codestr{bl} 
+ *   \var{pos} & (string) The corner of the screen to place the status 
+ *               display in: one of \codestr{tl}, \codestr{tr}, \codestr{bl} 
  *               or \codestr{br}. \\
- *   \var{action} & If this field is set to \codestr{keep}, \var{corner}
- *                  and \var{orientation} are changed for the existing
+ *   \var{fullsize} & (boolean) Waste all available space. \\
+ *   \var{action} & (string) If this field is set to \codestr{keep}, 
+ *                  \var{pos} and \var{fullsize} are changed for the existing
  *                  status display. If this field is set to \codestr{remove},
  *                  the existing status display is removed. If this
  *                  field is not set or is set to \codestr{replace}, a