Forráskód Böngészése

Still works on tabbing..

Martin Duquesnoy 12 éve
szülő
commit
3afdc65fb1
6 módosított fájl, 101 hozzáadás és 47 törlés
  1. 1 0
      src/barwin.h
  2. 88 45
      src/client.c
  3. 2 0
      src/client.h
  4. 2 2
      src/layout.c
  5. 6 0
      src/util.h
  6. 2 0
      src/wmfs.h

+ 1 - 0
src/barwin.h

@@ -23,6 +23,7 @@
 #define barwin_map(b)           XMapWindow(W->dpy, b->win);
 #define barwin_unmap(b)         XUnmapWindow(W->dpy, b->win);
 #define barwin_move(b, x, y)    XMoveWindow(W->dpy, b->win, x, y);
+#define barwin_reparent(b, w)   XReparentWindow(W->dpy, b->win, w, 0, 0);
 
 struct barwin* barwin_new(Window parent, int x, int y, int w, int h, Color fg, Color bg, bool entermask);
 void barwin_remove(struct barwin *b);

+ 88 - 45
src/client.c

@@ -64,7 +64,12 @@ CLIENT_ACTION_DIR(focus, Top)
 CLIENT_ACTION_DIR(focus, Bottom)
 
 /* uicb_client_tab_dir() */
-#define client_tab(c) client_moveresize(W->client, &c->geo)
+#define client_tab(c) do {                                                        \
+     layout_split_arrange_closed(W->client);                                      \
+     struct geo g = { XTABBED(c->geo.x), XTABBED(c->geo.y), c->geo.w, c->geo.h }; \
+     client_moveresize(W->client, &c->geo);                                       \
+     c->geo = g;                                                                  \
+} while( /* CONSTCOND */ 0);
 CLIENT_ACTION_DIR(tab, Right)
 CLIENT_ACTION_DIR(tab, Left)
 CLIENT_ACTION_DIR(tab, Top)
@@ -201,11 +206,11 @@ client_swap2(struct client *c1, struct client *c2)
      c1->tgeo = c2->geo;
      c2->tgeo = c1->geo;
 
-     client_moveresize(c1, &c1->tgeo);
-     client_moveresize(c2, &c2->tgeo);
-
      c1->flags |= CLIENT_IGNORE_ENTER;
      c2->flags |= CLIENT_IGNORE_ENTER;
+
+     client_moveresize(c1, &c1->tgeo);
+     client_moveresize(c2, &c2->tgeo);
 }
 
 static inline struct client*
@@ -326,33 +331,6 @@ client_grabbuttons(struct client *c, bool focused)
                ButtonMask, GrabModeAsync, GrabModeSync, None, None);
 }
 
-static void
-client_tab_etablish(struct client *c, struct geo *g)
-{
-     struct client *cc;
-
-     SLIST_FOREACH(cc, &c->tag->clients, tnext)
-     {
-          if(c != cc)
-          {
-               if(GEOCMP(c->geo, cc->geo))
-               {
-                    c->flags |= CLIENT_TABBED | CLIENT_TABMASTER;
-                    cc->flags |= CLIENT_TABBED;
-               }
-               else if(GEOCMP(*g, cc->geo) && cc->flags & CLIENT_TABBED)
-               {
-                    c->flags |= CLIENT_TABBED | CLIENT_TABMASTER;
-                    cc->flags |= CLIENT_TABBING;
-                    client_moveresize(cc, &c->geo);
-               }
-          }
-     }
-
-     if(c->flags & CLIENT_TABMASTER)
-          XRaiseWindow(W->dpy, c->frame);
-}
-
 #define CCOL(c) (c == c->tag->sel ? &c->scol : &c->ncol)
 static void
 client_frame_update(struct client *c, struct colpair *cp)
@@ -362,20 +340,52 @@ client_frame_update(struct client *c, struct colpair *cp)
 
      if(c->titlebar && c->title)
      {
-          int w = draw_textw(c->theme, c->title);
+          struct client *cc;
+          int f, n = 0, w = draw_textw(c->theme, c->title);
 
           c->titlebar->fg = cp->fg;
           c->titlebar->bg = cp->bg;
 
-          barwin_move(c->titlebar, (c->geo.w >> 1) - (w >> 1) - PAD, 0);
-          barwin_resize(c->titlebar, w + (PAD << 1), c->tbarw);
-          barwin_refresh_color(c->titlebar);
+          SLIST_FOREACH(cc, &c->tag->clients, tnext)
+               if(GEOCMP(c->geo, cc->geo))
+                    ++n;
 
-          draw_text(c->titlebar->dr, c->theme,
-                    PAD, TEXTY(c->theme, c->tbarw), cp->fg,
-                    c->title);
+          if(!n)
+               return;
 
+          barwin_reparent(c->titlebar, c->frame);
+          barwin_move(c->titlebar, 0, 0);
+          barwin_resize(c->titlebar, (f = (c->geo.w / n)), c->tbarw);
+          barwin_refresh_color(c->titlebar);
+          draw_text(c->titlebar->dr, c->theme,
+                    (f >> 1) - (w >> 1) - PAD,
+                    TEXTY(c->theme, c->tbarw), cp->fg, c->title);
           barwin_refresh(c->titlebar);
+
+          /* Tabbing case, multiple titlebar in frame */
+          if(n > 1)
+          {
+               int x = f;
+
+               SLIST_FOREACH(cc, &c->tag->clients, tnext)
+                    if(GEOCMPTAB(c->geo, cc->geo) && cc->titlebar)
+                    {
+                         cc->titlebar->bg = c->ncol.bg;
+
+                         barwin_reparent(cc->titlebar, c->frame);
+                         barwin_move(cc->titlebar, x, 0);
+                         barwin_resize(cc->titlebar, f, c->tbarw);
+                         barwin_refresh_color(cc->titlebar);
+
+                         draw_text(cc->titlebar->dr, c->theme,
+                                   (f >> 1) - (draw_textw(c->theme, cc->title) >> 1) - PAD,
+                                   TEXTY(c->theme, c->tbarw), c->ncol.fg, cc->title);
+
+                         barwin_refresh(cc->titlebar);
+
+                         x += f + PAD;
+                    }
+          }
      }
 }
 
@@ -396,6 +406,25 @@ client_focus(struct client *c)
           client_grabbuttons(c, true);
           client_frame_update(c, &c->scol);
 
+          if(c->flags & CLIENT_TABSLAVE)
+          {
+               struct geo og = c->geo;
+               struct client *cc;
+
+               SLIST_FOREACH(cc, &c->tag->clients, tnext)
+                    if(GEOCMPTAB(cc->geo, c->geo) && cc->flags & CLIENT_TABMASTER)
+                    {
+                         client_moveresize(c, &cc->geo);
+                         client_moveresize(cc, &og);
+                         c->flags  &= ~CLIENT_TABSLAVE;
+                         cc->flags |=  CLIENT_TABSLAVE;
+                         c->flags  |=  CLIENT_TABMASTER;
+                         cc->flags &= ~CLIENT_TABMASTER;
+
+                         break;
+                    }
+          }
+
           XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
      }
      else
@@ -646,6 +675,7 @@ client_new(Window w, XWindowAttributes *wa, bool scan)
      c->screen = W->screen;
      c->theme  = THEME_DEFAULT;
      c->tag    = NULL;
+     c->tabmaster = NULL;
 
      /* struct geometry */
      c->geo.x = wa->x;
@@ -778,6 +808,7 @@ client_winsize(struct client *c, struct geo *g)
 
      client_geo_hints(&c->wgeo, (int*)c->sizeh);
 
+
      /* Check possible problem for tile integration */
      if(ow < c->sizeh[MINW] || oh < c->sizeh[MINH])
           if(ow + oh < og.w + og.h)
@@ -794,6 +825,19 @@ client_winsize(struct client *c, struct geo *g)
      return false;
 }
 
+static void
+client_tab_etablish(struct client *c)
+{
+     struct client *cc;
+
+     SLIST_FOREACH(cc, &c->tag->clients, tnext)
+          if(GEOCMPTAB(c->geo, cc->geo))
+          {
+               c->flags |= CLIENT_TABMASTER;
+               cc->flags |= CLIENT_TABSLAVE;
+          }
+}
+
 void
 client_moveresize(struct client *c, struct geo *g)
 {
@@ -811,8 +855,11 @@ client_moveresize(struct client *c, struct geo *g)
           }
 
      /* Real geo regarding full root size */
-     c->rgeo.x += c->screen->ugeo.x;
-     c->rgeo.y += c->screen->ugeo.y;
+     if(!(c->flags & CLIENT_TABSLAVE))
+     {
+          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,
@@ -824,11 +871,7 @@ client_moveresize(struct client *c, struct geo *g)
 
      c->flags &= ~CLIENT_DID_WINSIZE;
 
-     if(c->flags & CLIENT_TABBING)
-          c->flags ^= CLIENT_TABBING;
-     else
-          client_tab_etablish(c, &og);
-
+     client_tab_etablish(c);
      client_frame_update(c, CCOL(c));
      client_update_props(c, CPROP_GEO);
      client_configure(c);

+ 2 - 0
src/client.h

@@ -9,6 +9,8 @@
 #include "wmfs.h"
 #include "layout.h"
 
+#define TCLIENT_CHECK(C) (C->flags & CLIENT_TABBED && !(C->flags & CLIENT_TABMASTER))
+
 inline void client_configure(struct client *c);
 struct client *client_gb_win(Window w);
 struct client *client_gb_frame(Window w);

+ 2 - 2
src/layout.c

@@ -274,7 +274,7 @@ layout_split_check_row_dir(struct client *c, struct client *g, enum position p)
 
      SLIST_FOREACH(cc, &c->tag->clients, tnext)
           if(GEO_PARENTROW(cgeo, cc->geo, RPOS(p))
-                    && GEO_CHECK_ROW(cc->geo, g->geo, p))
+             && GEO_CHECK_ROW(cc->geo, g->geo, p))
           {
                s += (LDIR(p) ? cc->geo.h : cc->geo.w);
 
@@ -346,7 +346,7 @@ layout_split_arrange_closed(struct client *ghost)
                g = c->geo;
                SLIST_FOREACH(cc, &c->tag->clients, tnext)
                     if(GEO_PARENTROW(g, cc->geo, RPOS(p))
-                              && GEO_CHECK_ROW(cc->geo, ghost->geo, p))
+                       && GEO_CHECK_ROW(cc->geo, ghost->geo, p))
                     {
                          layout_split_arrange_size(&ghost->geo, cc, p);
                          b = true;

+ 6 - 0
src/util.h

@@ -25,6 +25,8 @@
      X##t##Window(W->dpy, w);     \
 } while( /* CONSTCOND */ 0);
 
+#define DMAXH               DisplayHeight(W->dpy, W->xscreen)
+#define DMAXW               DisplayWidth(W->dpy, W->xscreen)
 #define ATOM(a)             XInternAtom(W->dpy, (a), False)
 #define LEN(x)              (sizeof(x) / sizeof(*x))
 #define FLAGINT(i)          (1 << i)
@@ -33,6 +35,10 @@
 #define ABS(j)              (j < 0 ? -j : j)
 #define INAREA(i, j, a)     ((i) >= (a).x && (i) <= (a).x + (a).w && (j) >= (a).y && (j) <= (a).y + (a).h)
 #define GEOCMP(g1, g2)      ((g1).x == (g2).x && (g1).y == (g2).y && (g1).w == (g2).w && (g1).h == (g2).h)
+#define XTABBED(x)          (-DMAXW - x)
+#define YTABBED(y)          (-DMAXH - y)
+#define GEOCMPTAB(g1, g2)   ((g1).x == XTABBED((g2).x) && (g1).y == YTABBED((g2).y) && (g1).w == (g2).w && (g1).h == -(g2).h)
+
 
 /*
  * "#RRGGBB" -> 0xRRGGBB

+ 2 - 0
src/wmfs.h

@@ -150,6 +150,7 @@ struct client
      struct geo geo, wgeo, tgeo, ttgeo, rgeo;
      struct colpair ncol, scol;
      struct theme *theme;
+     struct client *tabmaster;
      int sizeh[SHLAST];
      char *title;
      int border, tbarw;
@@ -162,6 +163,7 @@ struct client
 #define CLIENT_TABBED        0x40
 #define CLIENT_TABMASTER     0x80
 #define CLIENT_TABBING       0x100
+#define CLIENT_TABSLAVE      0x200
      Flags flags;
      Window win, frame;
      SLIST_ENTRY(client) next;   /* Global list */