Quellcode durchsuchen

Add layout_rotate_right/left

Martin Duquesnoy vor 12 Jahren
Ursprung
Commit
d66ada9acb
7 geänderte Dateien mit 119 neuen und 31 gelöschten Zeilen
  1. 9 4
      wmfs2/src/client.c
  2. 1 1
      wmfs2/src/client.h
  3. 4 3
      wmfs2/src/config.h
  4. 93 17
      wmfs2/src/layout.c
  5. 2 1
      wmfs2/src/layout.h
  6. 3 2
      wmfs2/src/parse.c
  7. 7 3
      wmfs2/wmfsrc2

+ 9 - 4
wmfs2/src/client.c

@@ -102,15 +102,19 @@ client_gb_win(Window w)
      return c;
 }
 
-struct client*
+inline struct client*
 client_gb_pos(struct tag *t, int x, int y)
 {
-     struct client *c;
+     struct client *c = SLIST_FIRST(&t->clients);
 
-     SLIST_FOREACH(c, &t->clients, tnext)
+     while(c)
+     {
           if(INAREA(x, y, c->geo))
                return c;
 
+          c = SLIST_NEXT(c, tnext);
+     }
+
      return NULL;
 }
 
@@ -125,6 +129,7 @@ client_next_with_pos(struct client *bc, Position p)
      struct client *c;
      int x, y;
      const static char scanfac[PositionLast] = { +10, -10, 0, 0 };
+     Position ip = Bottom - p;
 
      /*
       * Set start place of pointer (edge with position
@@ -139,7 +144,7 @@ client_next_with_pos(struct client *bc, Position p)
      while((c = client_gb_pos(bc->tag, x, y)) == bc)
      {
           x += scanfac[p];
-          y += scanfac[Bottom - p];
+          y += scanfac[ip];
      }
 
      return c;

+ 1 - 1
wmfs2/src/client.h

@@ -11,7 +11,7 @@
 
 void client_configure(struct client *c);
 struct client *client_gb_win(Window w);
-struct client *client_gb_pos(struct tag *t, int x, int y);
+inline struct client *client_gb_pos(struct tag *t, int x, int y);
 struct client *client_next_with_pos(struct client *bc, Position p);
 void client_swap(struct client *c1, struct client *c2);
 void client_focus(struct client *c);

+ 4 - 3
wmfs2/src/config.h

@@ -31,9 +31,10 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
      { "tag_prev", uicb_tag_prev },
 
      /* Layout */
-     { "layout_vmirror", uicb_layout_vmirror },
-     { "layout_hmirror", uicb_layout_hmirror },
-     { "layout_rotate",  uicb_layout_rotate },
+     { "layout_vmirror",      uicb_layout_vmirror },
+     { "layout_hmirror",      uicb_layout_hmirror },
+     { "layout_rotate_left",  uicb_layout_rotate_left },
+     { "layout_rotate_right", uicb_layout_rotate_right },
 
      /* Client */
      { "client_close",         uicb_client_close },

+ 93 - 17
wmfs2/src/layout.c

@@ -169,27 +169,104 @@ layout_split_integrate(struct client *c, struct client *sc)
      client_moveresize(c, g);
 }
 
-void
+/* Arrange inter-clients holes:
+ *  ___________      ___________
+ * |     ||    | -> |      |    |
+ * |  A  || B  | -> |  A  >| B  |
+ * |     ||    | -> |     >|    |
+ * |_____||____| -> |______|____|
+ *        ^ void
+ *
+ * and client-screen edge holes
+ *  ___________      ___________
+ * |     |    || -> |     |     |
+ * |  A  |  B || -> |  A  |  B >|
+ * |     |    || -> |     |    >|
+ * |_____|----'| -> |_____|__v__|
+ *          ^^^ void
+ */
+static inline void
+layout_fix_hole(struct client *c)
+{
+     struct client *cr = client_next_with_pos(c, Right);
+     struct client *cb = client_next_with_pos(c, Bottom);
+
+     c->geo.w += (cr ? cr->geo.x : c->screen->ugeo.w) - (c->geo.x + c->geo.w);
+     c->geo.h += (cb ? cb->geo.y : c->screen->ugeo.h) - (c->geo.y + c->geo.h);
+
+     client_moveresize(c, c->geo);
+}
+
+/* Layout rotation: Rotate 90° all client to right or left.
+ * Avoid if(left) condition in layout_rotate loop; use func ptr
+ *
+ * Left rotation
+ *  _____________        _____________
+ * |    |   B    |  ->  |     A       |
+ * |  A |________|  ->  |-------------|
+ * |    |    |   |  ->  |  C  |  B    |
+ * |    |  C | D |  ->  |_____|       |
+ * |____|____|___|  ->  |_____|_______|
+ *                       ^ D
+ * Right rotation
+ *  _____________        _____________
+ * |    |   B    |  ->  |   |_________|< D
+ * |  A |________|  ->  | B |   C     |
+ * |    |    |   |  ->  |___|_________|
+ * |    |  C | D |  ->  |     A       |
+ * |____|____|___|  ->  |_____________|
+ *
+ */
+
+static inline void
+_pos_rotate_left(struct geo *g, struct geo ug, struct geo og)
+{
+     g->x = (ug.h - (og.y + og.h));
+     g->y = og.x;
+}
+
+static inline void
+_pos_rotate_right(struct geo *g, struct geo ug, struct geo og)
+{
+     g->x = og.y;
+     g->y = (ug.w - (og.x + og.w));
+}
+
+static void
 layout_rotate(struct tag *t, bool left)
 {
      struct client *c;
-     struct geo g, ug = t->screen->ugeo;
+     struct geo g;
+     float f1 = (float)t->screen->ugeo.w / (float)t->screen->ugeo.h;
+     float f2 = 1 / f1;
+     void (*pos)(struct geo*, struct geo, struct geo) =
+          (left ? _pos_rotate_left : _pos_rotate_right);
 
      SLIST_FOREACH(c, &t->clients, tnext)
      {
-          g = c->geo;
-          c->geo.x = (g.y * ug.h) / ug.w;
-          c->geo.y = (g.x * ug.w) / ug.h;
+          pos(&g, t->screen->ugeo, c->geo);
 
-          c->geo.w = (g.h * ug.w) / ug.h;
-          c->geo.h = (g.w * ug.h) / ug.w;
+          g.x *= f1;
+          g.y *= f2;
+          g.w = c->geo.h * f1;
+          g.h = c->geo.w * f2;
 
-          client_moveresize(c, c->geo);
+          client_moveresize(c, g);
      }
+
+     /* Rotate sometimes do not set back perfect size.. */
+     SLIST_FOREACH(c, &t->clients, tnext)
+          layout_fix_hole(c);
 }
 
 void
-uicb_layout_rotate(Uicb cmd)
+uicb_layout_rotate_left(Uicb cmd)
+{
+     layout_rotate(W->screen->seltag, true);
+}
+
+void
+uicb_layout_rotate_right(Uicb cmd)
 {
      layout_rotate(W->screen->seltag, false);
 }
@@ -204,6 +281,13 @@ uicb_layout_rotate(Uicb cmd)
  * |  A |_______|  ->  |_______| A  |
  * |    | C | D |  ->  | D | C |    |
  * |____|___|___|  ->  |___|___|____|
+ *
+ * Horizontal mirror
+ *  ____________        ____________
+ * |    |   B   |  ->  |    | C | D |
+ * |  A |_______|  ->  |  A |___|___|
+ * |    | C | D |  ->  |    |   B   |
+ * |____|___|___|  ->  |____|_______|
  */
 void
 uicb_layout_vmirror(Uicb cmd)
@@ -217,14 +301,6 @@ uicb_layout_vmirror(Uicb cmd)
      }
 }
 
-/*
- * Horinzontal mirror
- *  ____________        ____________
- * |    |   B   |  ->  |    | C | D |
- * |  A |_______|  ->  |  A |___|___|
- * |    | C | D |  ->  |    |   B   |
- * |____|___|___|  ->  |____|_______|
- */
 void
 uicb_layout_hmirror(Uicb cmd)
 {

+ 2 - 1
wmfs2/src/layout.h

@@ -33,7 +33,8 @@ void layout_split_integrate(struct client *c, struct client *sc);
 void layout_split_arrange_closed(struct client *ghost);
 void uicb_layout_vmirror(Uicb cmd);
 void uicb_layout_hmirror(Uicb cmd);
-void uicb_layout_rotate(Uicb cmd);
+void uicb_layout_rotate_left(Uicb cmd);
+void uicb_layout_rotate_right(Uicb cmd);
 
 #endif /* LAYOUT_H */
 

+ 3 - 2
wmfs2/src/parse.c

@@ -655,8 +655,9 @@ int
 get_conf(const char *filename)
 {
      struct conf_sec *s;
-     struct keyword *head = parse_keywords(filename);
-     struct keyword *kw   = parse_keywords(filename);
+     struct keyword *head, *kw;
+
+     head = kw = parse_keywords(filename);
 
      if(!head)
           return -1; /* TODO ERREUR */

+ 7 - 3
wmfs2/wmfsrc2

@@ -116,8 +116,7 @@
   [key] mod = {"Super"} key = "q" func = "client_close" [/key]
 
   # Focus next / prev client
-  [key] mod = { "Alt" } key = "Tab" func = "client_focus_next" [/key]
-  [key] mod = { "Alt", "Shift" } key = "Tab" func = "client_focus_prev" [/key]
+  [key] mod = { "Alt" } key = "Tab" func = "client_focus_next" [/key][key] mod = { "Alt", "Shift" } key = "Tab" func = "client_focus_prev" [/key]
 
   # Focus next client with direction
   [key] mod = {"Alt"} key = "h" func = "client_focus_left"   [/key]
@@ -125,7 +124,7 @@
   [key] mod = {"Alt"} key = "k" func = "client_focus_top"    [/key]
   [key] mod = {"Alt"} key = "j" func = "client_focus_bottom" [/key]
 
- # swap next client with direction:
+  # swap next client with direction:
   [key] mod = {"Control", "Shift"} key = "h" func = "client_swap_left"   [/key]
   [key] mod = {"Control", "Shift"} key = "l" func = "client_swap_right"  [/key]
   [key] mod = {"Control", "Shift"} key = "k" func = "client_swap_top"    [/key]
@@ -141,5 +140,10 @@
   [key] mod = {"Super", "Control"} key = "k" func = "client_resize_bottom" cmd = "-20" [/key]
   [key] mod = {"Super", "Control"} key = "j" func = "client_resize_bottom" cmd = "20" [/key]
 
+  # Layout manipulation
+  [key] mod = {"Super"}          key = "m" func = "layout_vmirror" [/key]
+  [key] mod = {"Super", "Shift"} key = "m" func = "layout_hmirror" [/key]
+  [key] mod = {"Super"}          key = "r" func = "layout_rotate_right" [/key]
+  [key] mod = {"Super", "Shift"} key = "r" func = "layout_rotate_left" [/key]
 
 [/keys]