From 9aaaf7ef635ec9bcb6a451cfa67eca252e2c1492 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Sat, 19 Nov 2011 04:14:16 +0100 Subject: [PATCH] Almost finish tabbing, reload/tagtransfert/maybesomemore to do --- src/client.c | 162 +++++++++++++++++++++++++++++++++++++-------------- src/client.h | 54 ++++++++++++++--- src/config.h | 1 + src/tag.c | 4 +- src/wmfs.h | 3 +- 5 files changed, 169 insertions(+), 55 deletions(-) diff --git a/src/client.c b/src/client.c index 731a829..acd86f9 100644 --- a/src/client.c +++ b/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) diff --git a/src/client.h b/src/client.h index cf08169..77a86e8 100644 --- a/src/client.h +++ b/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; - cc->flags |= CLIENT_TABBED; + c->geo = c->tgeo = g; - client_unmap(cc); - client_focus(c); + 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); + + /* Parent tabbed client take new master as tabmaster */ + SLIST_FOREACH(cc, &c->tag->clients, tnext) + if(cc->tabmaster == c->tabmaster) + cc->tabmaster = c; + + c->tabmaster->tabmaster = c; + c->tabmaster = NULL; } #endif /* CLIENT_H */ diff --git a/src/config.h b/src/config.h index ee9fd41..a2197aa 100644 --- a/src/config.h +++ b/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 } }; diff --git a/src/tag.c b/src/tag.c index 9fef547..ddd9fee 100644 --- a/src/tag.c +++ b/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) diff --git a/src/wmfs.h b/src/wmfs.h index 5e67691..4f85666 100644 --- a/src/wmfs.h +++ b/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 */