From 3afdc65fb1373e10541bf7b60b6892899ea5527b Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Tue, 15 Nov 2011 21:58:48 +0100 Subject: [PATCH] Still works on tabbing.. --- src/barwin.h | 1 + src/client.c | 133 ++++++++++++++++++++++++++++++++++----------------- src/client.h | 2 + src/layout.c | 4 +- src/util.h | 6 +++ src/wmfs.h | 2 + 6 files changed, 101 insertions(+), 47 deletions(-) diff --git a/src/barwin.h b/src/barwin.h index d57df88..a9831f3 100644 --- a/src/barwin.h +++ b/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); diff --git a/src/client.c b/src/client.c index 1146dc2..1edc6fd 100644 --- a/src/client.c +++ b/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); + SLIST_FOREACH(cc, &c->tag->clients, tnext) + if(GEOCMP(c->geo, cc->geo)) + ++n; + + 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, - PAD, TEXTY(c->theme, c->tbarw), cp->fg, - c->title); - + (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); diff --git a/src/client.h b/src/client.h index 83c6aba..cb43065 100644 --- a/src/client.h +++ b/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); diff --git a/src/layout.c b/src/layout.c index 3fa635e..eeddd15 100644 --- a/src/layout.c +++ b/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; diff --git a/src/util.h b/src/util.h index 6442bd0..1ac4694 100644 --- a/src/util.h +++ b/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 diff --git a/src/wmfs.h b/src/wmfs.h index 28b1441..6cd681b 100644 --- a/src/wmfs.h +++ b/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 */