changeset 3163:97650efd5b70

Fixed #274: Added support of fixnum values in stick property to specifiy a screen
author unexist
date Thu, 22 Dec 2011 18:52:13 +0100
parents 17394e21d0de
children 969d3f467b05
files src/subtle/client.c src/subtle/event.c src/subtle/ruby.c src/subtle/subtle.h
diffstat 4 files changed, 78 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/src/subtle/client.c	Mon Dec 19 19:54:12 2011 +0100
+++ b/src/subtle/client.c	Thu Dec 22 18:52:13 2011 +0100
@@ -867,10 +867,11 @@
 {
   SubTag *t = NULL;
 
+  DEAD(c);
   assert(c);
 
   /* Update flags and tags */
-  if(ALIVE(c) && (t = TAG(subArrayGet(subtle->tags, tag))))
+  if((t = TAG(subArrayGet(subtle->tags, tag))))
     {
       int i;
 
@@ -893,14 +894,18 @@
             }
         }
 
-      /* Set gravity and screens for matching views */
+      /* Set screen */
+      if(t->flags & SUB_CLIENT_MODE_STICK)
+        c->screenid  = t->screenid;
+
+      /* Set gravity matching views */
       for(i = 0; i < subtle->views->ndata; i++)
         {
           SubView *v = VIEW(subtle->views->data[i]);
 
-          /* Match only views with this tag */
+          /* Match views with this tag or sticky only */
           if(v->tags & (1L << (tag + 1)) || t->flags & SUB_CLIENT_MODE_STICK)
-            if(t->flags & SUB_TAG_GRAVITY) c->gravities[i] = t->gravity;
+            if(t->flags & SUB_TAG_GRAVITY) c->gravities[i] = t->gravityid;
         }
     }
 } /* }}} */
@@ -1133,13 +1138,13 @@
  /** subClientToggle {{{
   * @brief Toggle various states of client
   * @param[in]  c        A #SubClient
-  * @param[in]  type     Toggle type
+  * @param[in]  flag     Toggle flag
   * @param[in]  gravity  Whether gravity should be set
   **/
 
 void
 subClientToggle(SubClient *c,
-  int type,
+  int flag,
   int gravity)
 {
   int flags = 0, nstates = 0;
@@ -1148,16 +1153,16 @@
   DEAD(c);
   assert(c);
 
-  if(c->flags & type) ///< Unset flags
+  if(c->flags & flag) ///< Unset flags
     {
-      c->flags &= ~type;
+      c->flags &= ~flag;
 
       /* Unset float/center mode */
-      if(type & (SUB_CLIENT_MODE_FLOAT|SUB_CLIENT_MODE_CENTER))
-        c->flags |= SUB_CLIENT_ARRANGE;
+      if(flag & (SUB_CLIENT_MODE_FLOAT|SUB_CLIENT_MODE_CENTER))
+        c->flags |= SUB_CLIENT_ARRANGE; ///< Force rearrange
 
       /* Unset stick mode */
-      if(type & SUB_CLIENT_MODE_STICK)
+      if(flag & SUB_CLIENT_MODE_STICK)
         {
           /* Update highlight urgent client */
           if(c->flags & SUB_CLIENT_MODE_URGENT)
@@ -1165,11 +1170,11 @@
         }
 
       /* Unset borderless or fullscreen mode */
-      if(type & (SUB_CLIENT_MODE_BORDERLESS|SUB_CLIENT_MODE_FULL))
+      if(flag & (SUB_CLIENT_MODE_BORDERLESS|SUB_CLIENT_MODE_FULL))
         {
           c->flags |= SUB_CLIENT_ARRANGE; ///< Force rearrange
 
-          if(type & SUB_CLIENT_MODE_BORDERLESS ||
+          if(flag & SUB_CLIENT_MODE_BORDERLESS ||
               !(c->flags & SUB_CLIENT_MODE_BORDERLESS))
             XSetWindowBorderWidth(subtle->dpy, c->win,
               subtle->styles.clients.border.top);
@@ -1177,10 +1182,10 @@
     }
   else ///< Set flags
     {
-      c->flags |= type;
+      c->flags |= flag;
 
       /* Set sticky mode */
-      if(type & SUB_CLIENT_MODE_STICK)
+      if(flag & SUB_CLIENT_MODE_STICK)
         {
           SubClient *focus = NULL;
 
@@ -1195,22 +1200,27 @@
                   SubView *v = VIEW(subtle->views->data[i]);
 
                   /* Check visibility manually */
-                  if(!(v->tags & c->tags))
-                    if(-1 != c->gravityid) c->gravities[i] = c->gravityid;
+                  if(!(v->tags & c->tags) && -1 != c->gravityid)
+                    c->gravities[i] = c->gravityid;
                 }
             }
 
-          /* Prefer screen of current window, set it and re-arrange*/
-          if((focus = CLIENT(subSubtleFind(subtle->windows.focus[0],
-              CLIENTID))) && VISIBLE(c))
-            c->screenid = focus->screenid;
-          else subScreenCurrent(&c->screenid);
+          /* Set screen when unset */
+          if(-1 == c->screenid)
+            {
+              /* Find screen: Prefer screen of current window */
+              if(subtle->flags & SUB_SUBTLE_SKIP_WARP &&
+                  (focus = CLIENT(subSubtleFind(subtle->windows.focus[0],
+                  CLIENTID))) && VISIBLE(focus))
+                c->screenid = focus->screenid;
+              else subScreenCurrent(&c->screenid);
+            }
 
-          c->flags |= SUB_CLIENT_ARRANGE;
+          c->flags |= SUB_CLIENT_ARRANGE; ///< Force rearrange
         }
 
       /* Set fullscreen mode */
-      if(type & SUB_CLIENT_MODE_FULL)
+      if(flag & SUB_CLIENT_MODE_FULL)
         {
           /* Exclude fixed windows from fullscreen mode */
           if(c->flags & SUB_CLIENT_MODE_FIXED)
@@ -1223,20 +1233,20 @@
         }
 
       /* Set floating or zaphod or borderless mode */
-      if(type & (SUB_CLIENT_MODE_FLOAT|SUB_CLIENT_MODE_ZAPHOD|
+      if(flag & (SUB_CLIENT_MODE_FLOAT|SUB_CLIENT_MODE_ZAPHOD|
           SUB_CLIENT_MODE_BORDERLESS))
         c->flags |= SUB_CLIENT_ARRANGE; ///< Force rearrange
 
       /* Set borderless mode */
-      if(type & SUB_CLIENT_MODE_BORDERLESS)
+      if(flag & SUB_CLIENT_MODE_BORDERLESS)
         XSetWindowBorderWidth(subtle->dpy, c->win, 0);
 
       /* Set urgent mode */
-      if(type & SUB_CLIENT_MODE_URGENT)
+      if(flag & SUB_CLIENT_MODE_URGENT)
         subtle->urgent_tags |= c->tags;
 
       /* Set center mode */
-      if(type & SUB_CLIENT_MODE_CENTER)
+      if(flag & SUB_CLIENT_MODE_CENTER)
         {
           SubScreen *s = SCREEN(subtle->screens->data[c->screenid]);
 
@@ -1250,12 +1260,12 @@
         }
 
       /* Set dock and desktop type */
-      if(type & (SUB_CLIENT_TYPE_DOCK|SUB_CLIENT_TYPE_DESKTOP))
+      if(flag & (SUB_CLIENT_TYPE_DOCK|SUB_CLIENT_TYPE_DESKTOP))
         {
           XSetWindowBorderWidth(subtle->dpy, c->win, 0);
 
           /* Special treatment */
-          if(type & SUB_CLIENT_TYPE_DESKTOP)
+          if(flag & SUB_CLIENT_TYPE_DESKTOP)
             {
               SubScreen *s = SCREEN(subtle->screens->data[c->screenid]);
 
@@ -1275,7 +1285,7 @@
     }
 
   /* Sort for keeping stacking order */
-  if(type & (SUB_CLIENT_MODE_FLOAT|SUB_CLIENT_MODE_FULL|
+  if(flag & (SUB_CLIENT_MODE_FLOAT|SUB_CLIENT_MODE_FULL|
       SUB_CLIENT_TYPE_DESKTOP|SUB_CLIENT_TYPE_DOCK))
     subClientRestack(c, SUB_CLIENT_RESTACK_UP);
 
@@ -1301,7 +1311,7 @@
   /* Hook: Mode */
   subHookCall((SUB_HOOK_TYPE_CLIENT|SUB_HOOK_ACTION_MODE), (void *)c);
 
-  subSubtleLogDebugSubtle("Toggle: type=%d, gravity=%d\n", type, gravity);
+  subSubtleLogDebugSubtle("Toggle: flag=%d, gravity=%d\n", flag, gravity);
 } /* }}} */
 
   /** subClientSetStrut {{{
--- a/src/subtle/event.c	Mon Dec 19 19:54:12 2011 +0100
+++ b/src/subtle/event.c	Thu Dec 22 18:52:13 2011 +0100
@@ -898,7 +898,8 @@
                     int sid = 0;
 
                     /* Find screen: Prefer screen of current window */
-                    if((c = CLIENT(subSubtleFind(subtle->windows.focus[0],
+                    if(subtle->flags & SUB_SUBTLE_SKIP_WARP &&
+                        (c = CLIENT(subSubtleFind(subtle->windows.focus[0],
                         CLIENTID))) && VISIBLE(c))
                       sid = c->screenid;
                     else subScreenCurrent(&sid);
--- a/src/subtle/ruby.c	Mon Dec 19 19:54:12 2011 +0100
+++ b/src/subtle/ruby.c	Thu Dec 22 18:52:13 2011 +0100
@@ -1039,9 +1039,17 @@
       if(t->flags & SUB_TAG_GRAVITY)
         {
           /* Disable tag gravity when gravity can't be found */
-          if(-1 == (t->gravity = RubyValueToGravity(t->gravity)))
+          if(-1 == (t->gravityid = RubyValueToGravity(t->gravityid)))
             t->flags &= ~SUB_TAG_GRAVITY;
         }
+
+      /* Update screens */
+      if(t->flags & SUB_CLIENT_MODE_STICK)
+        {
+          if(-1 != t->screenid &&
+              (0 > t->screenid || subtle->screens->ndata <= t->screenid))
+            t->flags &= ~SUB_CLIENT_MODE_STICK;
+        }
     }
 
   subTagPublish();
@@ -2044,8 +2052,8 @@
   VALUE *argv,
   VALUE self)
 {
-  int flags = 0;
-  unsigned long gravity = 0;
+  int flags = 0, screenid = -1;
+  unsigned long gravityid = 0;
   XRectangle geom = { 0 };
   VALUE name = Qnil, match = Qnil, params = Qnil, value = Qnil;
 
@@ -2072,8 +2080,8 @@
           CHAR2SYM("gravity"))) || T_FIXNUM == rb_type(value) ||
           T_ARRAY == rb_type(value))
         {
-          flags   |= SUB_TAG_GRAVITY;
-          gravity  = value; ///< Lazy eval
+          flags     |= SUB_TAG_GRAVITY;
+          gravityid  = value; ///< Lazy eval
         }
 
       /* Set geometry */
@@ -2105,7 +2113,7 @@
           else if(CHAR2SYM("dialog")  == value) flags = SUB_CLIENT_TYPE_DIALOG;
         }
 
-      /* Check tri-state properties */
+      /* Check state properties */
       if(Qtrue == (value = rb_hash_lookup(params,
         CHAR2SYM("borderless")))) flags |= SUB_CLIENT_MODE_BORDERLESS;
 
@@ -2125,13 +2133,22 @@
         CHAR2SYM("resize")))) flags |= SUB_CLIENT_MODE_RESIZE;
 
       if(Qtrue == (value = rb_hash_lookup(params,
-        CHAR2SYM("stick")))) flags |= SUB_CLIENT_MODE_STICK;
-
-      if(Qtrue == (value = rb_hash_lookup(params,
         CHAR2SYM("urgent")))) flags |= SUB_CLIENT_MODE_URGENT;
 
       if(Qtrue == (value = rb_hash_lookup(params,
         CHAR2SYM("zaphod")))) flags |= SUB_CLIENT_MODE_ZAPHOD;
+
+      /* Set stick screen */
+      if(RTEST(value = rb_hash_lookup(params, CHAR2SYM("stick"))))
+        {
+          /* Either screen id or just true */
+          if(FIXNUM_P(value))
+            {
+              screenid  = FIX2INT(value);
+              flags    |= SUB_CLIENT_MODE_STICK;
+            }
+          else if(Qtrue == value) flags |= SUB_CLIENT_MODE_STICK;
+        }
     }
 
   /* Check value type */
@@ -2151,9 +2168,10 @@
               VALUE entry = Qnil, rargs[2] = { 0 };
 
               /* Set tag values */
-              t->flags   |= flags;
-              t->gravity  = gravity;
-              t->geom     = geom;
+              t->flags     |= flags;
+              t->gravityid = gravityid;
+              t->screenid  = screenid;
+              t->geom      = geom;
 
               /* Add matcher */
               rargs[0] = (VALUE)t;
--- a/src/subtle/subtle.h	Mon Dec 19 19:54:12 2011 +0100
+++ b/src/subtle/subtle.h	Thu Dec 22 18:52:13 2011 +0100
@@ -223,7 +223,7 @@
 #define SUB_CLIENT_UNMAP              (1L << 14)                  ///< Ignore unmaps
 #define SUB_CLIENT_ARRANGE            (1L << 15)                  ///< Re-arrange client
 
-#define SUB_CLIENT_MODE_FULL          (1L << 16)                  ///< Fullscreen mode
+#define SUB_CLIENT_MODE_FULL          (1L << 16)                  ///< Fullscreen mode (also used in tags)
 #define SUB_CLIENT_MODE_FLOAT         (1L << 17)                  ///< Float mode
 #define SUB_CLIENT_MODE_STICK         (1L << 18)                  ///< Stick mode
 #define SUB_CLIENT_MODE_URGENT        (1L << 19)                  ///< Urgent mode
@@ -719,7 +719,8 @@
 {
   FLAGS             flags;                                        ///< Tag flags
   char              *name;                                        ///< Tag name
-  unsigned long     gravity;                                      ///< Tag gravity
+  unsigned long     gravityid;                                    ///< Tag gravity
+  int               screenid;                                     ///< Tag screen
   XRectangle        geom;                                         ///< Tag geometry
   struct subarray_t *matcher;                                     ///< Tag matcher
 } SubTag; /* }}} */
@@ -776,7 +777,7 @@
 void subClientRestack(SubClient *c, int dir);                     ///< Restack clients
 void subClientArrange(SubClient *c, int gravityid,
   int screenid);                                                  ///< Arrange client
-void subClientToggle(SubClient *c, int type, int gravity);        ///< Toggle client state
+void subClientToggle(SubClient *c, int flag, int gravity);        ///< Toggle client state
 void subClientSetStrut(SubClient *c);                             ///< Set client strut
 void subClientSetProtocols(SubClient *c);                         ///< Set client protocols
 void subClientSetSizeHints(SubClient *c, int *flags);             ///< Set client normal hints