Parcourir la source

Almost finish tabbing, reload/tagtransfert/maybesomemore to do

Martin Duquesnoy il y a 12 ans
Parent
commit
9aaaf7ef63
5 fichiers modifiés avec 169 ajouts et 55 suppressions
  1. 118 44
      src/client.c
  2. 46 8
      src/client.h
  3. 1 0
      src/config.h
  4. 3 1
      src/tag.c
  5. 1 2
      src/wmfs.h

+ 118 - 44
src/client.c

@@ -61,7 +61,7 @@ CLIENT_ACTION_DIR(focus, Top)
 CLIENT_ACTION_DIR(focus, Bottom)
 
 /* uicb_client_tab_dir() */
-#define client_tab(c) _client_tab(c, W->client)
+#define client_tab(c) _client_tab(W->client, c)
 CLIENT_ACTION_DIR(tab, Right)
 CLIENT_ACTION_DIR(tab, Left)
 CLIENT_ACTION_DIR(tab, Top)
@@ -323,6 +323,9 @@ client_grabbuttons(struct client *c, bool focused)
                ButtonMask, GrabModeAsync, GrabModeSync, None, None);
 }
 
+#define _XTEXT()                                \
+     if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0) \
+          xt = 0;
 void
 client_frame_update(struct client *c, struct colpair *cp)
 {
@@ -338,7 +341,7 @@ client_frame_update(struct client *c, struct colpair *cp)
           c->titlebar->bg = cp->bg;
 
           SLIST_FOREACH(cc, &c->tag->clients, tnext)
-               if(cc->tbgeo == &c->geo)
+               if(cc->tabmaster == c)
                     ++n;
 
           barwin_reparent(c->titlebar, c->frame);
@@ -346,8 +349,7 @@ client_frame_update(struct client *c, struct colpair *cp)
           barwin_resize(c->titlebar, (f = (c->geo.w / n)), c->tbarw);
           barwin_refresh_color(c->titlebar);
 
-          if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0)
-               xt = 0;
+          _XTEXT();
 
           draw_text(c->titlebar->dr, c->theme, xt,
                     TEXTY(c->theme, c->tbarw), cp->fg, c->title);
@@ -359,13 +361,12 @@ client_frame_update(struct client *c, struct colpair *cp)
                int x = f;
 
                SLIST_FOREACH(cc, &c->tag->clients, tnext)
-                    if(cc->tbgeo == &c->geo && cc->titlebar)
+                    if(cc->tabmaster == c && cc->titlebar)
                     {
                          cc->titlebar->bg = c->ncol.bg;
 
                          w = draw_textw(c->theme, cc->title);
-                         if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0)
-                              xt = 0;
+                         _XTEXT();
 
                          barwin_map(cc->titlebar);
                          barwin_reparent(cc->titlebar, c->frame);
@@ -384,6 +385,110 @@ client_frame_update(struct client *c, struct colpair *cp)
      }
 }
 
+void
+_client_tab(struct client *c, struct client *cm)
+{
+     /* Do not tab already tabed client */
+     if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER))
+          return;
+
+     layout_split_arrange_closed(c);
+
+     struct geo g = cm->geo;
+
+     /* Isolate tabbed client */
+     client_unmap(c);
+     g.x += W->xmaxw;
+     g.y += W->xmaxh;
+     c->geo = c->tgeo = g;
+
+     c->tabmaster = cm;
+     cm->tabmaster = NULL;
+
+     c->flags |= CLIENT_TABBED;
+     cm->flags |= CLIENT_TABMASTER;
+
+     client_focus(cm);
+}
+
+
+static void
+client_tab_focus(struct client *c)
+{
+     if(c->flags & CLIENT_TABBED && c->tabmaster)
+     {
+          struct client *cc;
+          struct geo g = c->tabmaster->geo;
+
+          c->flags |=  CLIENT_TABMASTER;
+          c->flags &= ~CLIENT_TABBED;
+          client_moveresize(c, &c->tabmaster->geo);
+          client_map(c);
+
+          c->tabmaster->flags &= ~CLIENT_TABMASTER;
+          c->tabmaster->flags |=  CLIENT_TABBED;
+          client_unmap(c->tabmaster);
+
+          if(!(c->flags & CLIENT_DYING))
+          {
+               g.x += W->xmaxw;
+               g.y += W->xmaxh;
+               c->tabmaster->geo = c->tabmaster->tgeo = g;
+          }
+
+          SLIST_FOREACH(cc, &c->tag->clients, tnext)
+               if(cc != c && cc->tabmaster == c->tabmaster)
+                    cc->tabmaster = c;
+
+          c->tabmaster->tabmaster = c;
+          c->tabmaster = NULL;
+     }
+}
+
+static void
+client_untab(struct client *c)
+{
+     struct client *cc = c->tabmaster;
+     struct geo og = c->geo;
+
+     if(!(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER)))
+          return;
+
+     c->flags &= ~CLIENT_TABMASTER;
+
+     if(!cc)
+          SLIST_FOREACH(cc, &c->tag->clients, tnext)
+               if(cc->tabmaster == c)
+                    break;
+
+     if(cc)
+     {
+          client_tab_focus(cc);
+          c->flags &= ~CLIENT_TABBED;
+          c->tabmaster = NULL;
+
+          if(!(c->flags & CLIENT_DYING))
+          {
+               c->geo = c->tgeo = og;
+
+               layout_split_integrate(c, cc);
+               client_moveresize(c, &c->geo);
+               client_map(c);
+          }
+
+          client_frame_update(cc, CCOL(cc));
+     }
+}
+
+void
+uicb_client_untab(Uicb cmd)
+{
+     (void)cmd;
+
+     if(W->client)
+          client_untab(W->client);
+}
+
 void
 client_focus(struct client *c)
 {
@@ -399,35 +504,7 @@ client_focus(struct client *c)
      {
           c->tag->sel = c;
           client_grabbuttons(c, true);
-
-          if(c->flags & CLIENT_TABBED)
-          {
-               struct geo ocg = c->geo;
-               struct client *cc, *tc;
-
-               SLIST_FOREACH(cc, &c->tag->clients, tnext)
-                    if(c->tbgeo == &cc->geo)
-                    {
-                         c->flags  &= ~CLIENT_TABBED;
-                         cc->flags |=  CLIENT_TABBED;
-
-                         client_map(c);
-                         client_unmap(cc);
-
-                         client_moveresize(c, c->tbgeo);
-                         client_moveresize(cc, &ocg);
-
-                         cc->tbgeo = &c->geo;
-                         c->tbgeo  = NULL;
-
-                         SLIST_FOREACH(tc, &c->tag->clients, tnext)
-                              if(tc->flags & CLIENT_TABBED && tc->tbgeo == &cc->geo)
-                                   tc->tbgeo = &c->geo;
-
-                         break;
-                    }
-          }
-
+          client_tab_focus(c);
           client_frame_update(c, &c->scol);
           XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
      }
@@ -829,8 +906,6 @@ client_winsize(struct client *c, struct geo *g)
 void
 client_moveresize(struct client *c, struct geo *g)
 {
-     struct geo og = c->geo;
-
      if(c->flags & CLIENT_TABBED)
           return;
 
@@ -846,11 +921,8 @@ client_moveresize(struct client *c, struct geo *g)
           }
 
      /* Real geo regarding full root size */
-     if(!(c->flags & CLIENT_TABSLAVE))
-     {
-          c->rgeo.x += c->screen->ugeo.x;
-          c->rgeo.y += c->screen->ugeo.y;
-     }
+     c->rgeo.x += c->screen->ugeo.x;
+     c->rgeo.y += c->screen->ugeo.y;
 
      XMoveResizeWindow(W->dpy, c->frame,
                        c->rgeo.x, c->rgeo.y,
@@ -1094,10 +1166,12 @@ client_fac_hint(struct client *c)
 void
 client_remove(struct client *c)
 {
+     c->flags |= CLIENT_DYING;
      XGrabServer(W->dpy);
      XSetErrorHandler(wmfs_error_handler_dummy);
      XReparentWindow(W->dpy, c->win, W->root, c->rgeo.x, c->rgeo.y);
-     WIN_STATE(c->win, Map);
+     client_map(c);
+     client_untab(c);
      XDestroyWindow(W->dpy, c->frame);
 
      if(c->titlebar)

+ 46 - 8
src/client.h

@@ -22,6 +22,8 @@ void client_swap2(struct client *c1, struct client *c2);
 void client_swap(struct client *c, enum position p);
 #define CCOL(c) (c == c->tag->sel ? &c->scol : &c->ncol)
 void client_frame_update(struct client *c, struct colpair *cp);
+void client_tab_pull(struct client *c);
+void _client_tab(struct client *c, struct client *cm);
 void client_focus(struct client *c);
 void client_get_name(struct client *c);
 void client_close(struct client *c);
@@ -43,6 +45,7 @@ void client_apply_tgeo(struct tag *t);
 void client_update_props(struct client *c, Flags f);
 
 inline void client_fac_hint(struct client *c);
+void uicb_client_untab(Uicb cmd);
 
 /* Generated */
 void uicb_client_resize_Right(Uicb);
@@ -85,6 +88,23 @@ client_prev(struct client *c)
      return cc;
 }
 
+static inline struct client*
+clien_tab_next(struct client *c)
+{
+     struct client *cc;
+
+     if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER))
+          SLIST_FOREACH(cc, &c->tag->clients, tnext)
+          {
+               if(c == cc)
+                    continue;
+               if(c->tabmaster == c || c->tabmaster == c->tabmaster)
+                    return cc;
+          }
+
+     return NULL;
+}
+
 static inline void
 client_map(struct client *c)
 {
@@ -100,19 +120,37 @@ client_unmap(struct client *c)
 }
 
 static inline void
-_client_tab(struct client *c, struct client *cc)
+client_tab_slave(struct client *c)
 {
-     layout_split_arrange_closed(cc);
-
-     /* Fake geo to don't act in layout functions */
      struct geo g = { W->xmaxw + c->geo.x, W->xmaxh + c->geo.y, c->geo.w, c->geo.h };
 
-     cc->tbgeo = &c->geo;
+     c->flags &= ~CLIENT_TABMASTER;
+     c->flags |=  CLIENT_TABBED;
+
+     c->geo = c->tgeo = g;
+
+     client_unmap(c);
+}
+
+static inline void
+client_tab_master(struct client *c)
+{
+     struct client *cc;
+
+     c->flags |=  CLIENT_TABMASTER;
+     c->flags &= ~CLIENT_TABBED;
+
+     client_moveresize(c, &c->tabmaster->geo);
+     client_map(c);
+     client_tab_slave(c->tabmaster);
 
-     cc->flags |= CLIENT_TABBED;
+     /* Parent tabbed client take new master as tabmaster */
+     SLIST_FOREACH(cc, &c->tag->clients, tnext)
+          if(cc->tabmaster == c->tabmaster)
+               cc->tabmaster = c;
 
-     client_unmap(cc);
-     client_focus(c);
+     c->tabmaster->tabmaster = c;
+     c->tabmaster = NULL;
 }
 
 #endif /* CLIENT_H */

+ 1 - 0
src/config.h

@@ -60,6 +60,7 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
      { "client_focus_prev",    uicb_client_focus_prev },
      { "client_swap_next",     uicb_client_swapsel_next },
      { "client_swap_prev",     uicb_client_swapsel_prev },
+     { "client_untab",         uicb_client_untab },
      { NULL, NULL }
 };
 

+ 3 - 1
src/tag.c

@@ -53,7 +53,8 @@ tag_screen(struct screen *s, struct tag *t)
       */
      if(!SLIST_EMPTY(&t->clients))
      {
-          client_map(c);
+          SLIST_FOREACH(c, &t->clients, tnext)
+               client_map(c);
           client_focus(t->sel);
      }
 
@@ -77,6 +78,7 @@ tag_client(struct tag *t, struct client *c)
           if(!(c->flags & CLIENT_IGNORE_LAYOUT))
                layout_split_arrange_closed(c);
 
+
           SLIST_REMOVE(&c->tag->clients, c, client, tnext);
 
           if(c->tag->sel == c || W->client == c)

+ 1 - 2
src/wmfs.h

@@ -162,8 +162,7 @@ struct client
 #define CLIENT_RULED         0x20
 #define CLIENT_TABBED        0x40
 #define CLIENT_TABMASTER     0x80
-#define CLIENT_TABBING       0x100
-#define CLIENT_TABSLAVE      0x200
+#define CLIENT_DYING         0x100 /* Saddest flag ever */
      Flags flags;
      Window win, frame;
      SLIST_ENTRY(client) next;   /* Global list */