diff --git a/src/client.c b/src/client.c index 4cd748c..608a96a 100644 --- a/src/client.c +++ b/src/client.c @@ -346,7 +346,7 @@ client_frame_update(struct client *c, struct colpair *cp) /* Get number of tabbed client if c is tabmaster */ if(c->flags & CLIENT_TABMASTER) SLIST_FOREACH(cc, &c->tag->clients, tnext) - if(cc->tabmaster == c) + if(c == cc->tabmaster) ++n; f = (c->geo.w - (c->border * (n - 2))) / n; @@ -367,7 +367,7 @@ client_frame_update(struct client *c, struct colpair *cp) int x = f; SLIST_FOREACH(cc, &c->tag->clients, tnext) - if(cc->tabmaster == c && cc->titlebar) + if(c == cc->tabmaster && cc->titlebar) { cc->titlebar->bg = c->ncol.bg; @@ -402,7 +402,8 @@ client_tab_focus(struct client *c) c->flags |= CLIENT_TABMASTER; c->flags &= ~CLIENT_TABBED; client_moveresize(c, &c->tabmaster->geo); - client_map(c); + if(c->tag == c->screen->seltag) + client_map(c); c->tabmaster->flags &= ~CLIENT_TABMASTER; c->tabmaster->flags |= CLIENT_TABBED; @@ -417,10 +418,15 @@ client_tab_focus(struct client *c) SLIST_FOREACH(cc, &c->tag->clients, tnext) if(cc != c && cc->tabmaster == c->tabmaster) + { cc->tabmaster = c; + client_update_props(cc, CPROP_TAB); + } c->tabmaster->tabmaster = c; + client_update_props(c->tabmaster, CPROP_TAB); c->tabmaster = NULL; + client_update_props(c, CPROP_TAB); } } @@ -438,6 +444,7 @@ _client_tab(struct client *c, struct client *cm) cm->tabmaster = c; client_focus(cm); + client_frame_update(cm, CCOL(cm)); } static void @@ -446,7 +453,7 @@ client_untab(struct client *c) struct client *cc = c->tabmaster; struct geo og = c->geo; - if(!(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER))) + if(c->flags & CLIENT_REMOVEALL || !(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER))) return; if(!cc) @@ -859,6 +866,13 @@ client_update_props(struct client *c, Flags f) PropModeReplace, (unsigned char*)g, 4); } + + if(f & CPROP_TAB) + { + Window w = (c->tabmaster ? c->tabmaster->win : 0); + XChangeProperty(W->dpy, c->win, ATOM("_WMFS_TABMASTER"), XA_WINDOW, 32, + PropModeReplace, (unsigned char*)&w, 1); + } } static void @@ -1191,11 +1205,15 @@ 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); + client_map(c); + XReparentWindow(W->dpy, c->win, W->root, c->rgeo.x, c->rgeo.y); + client_untab(c); + XDestroyWindow(W->dpy, c->frame); if(c->titlebar) diff --git a/src/client.h b/src/client.h index 939d098..515a1c0 100644 --- a/src/client.h +++ b/src/client.h @@ -42,6 +42,7 @@ void client_apply_tgeo(struct tag *t); #define CPROP_LOC 0x01 #define CPROP_FLAG 0x02 #define CPROP_GEO 0x04 +#define CPROP_TAB 0x08 void client_update_props(struct client *c, Flags f); inline void client_fac_hint(struct client *c); diff --git a/src/tag.c b/src/tag.c index afe999b..dfc9a9f 100644 --- a/src/tag.c +++ b/src/tag.c @@ -82,11 +82,13 @@ tag_client(struct tag *t, struct client *c) if(!(c->flags & CLIENT_IGNORE_LAYOUT)) layout_split_arrange_closed(c); + if(!(c->flags & CLIENT_REMOVEALL)) + { + SLIST_REMOVE(&c->tag->clients, c, client, tnext); - SLIST_REMOVE(&c->tag->clients, c, client, tnext); - - if(c->tag->sel == c || W->client == c) - client_focus( client_tab_next( client_next(c))); + if(c->tag->sel == c || W->client == c) + client_focus( client_tab_next( client_next(c))); + } } c->flags &= ~CLIENT_RULED; diff --git a/src/wmfs.c b/src/wmfs.c index dcfdde6..3c2a4e7 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -184,13 +184,13 @@ static void wmfs_scan(void) { struct geo g; - struct client *c; + struct client *c, *cc; int i, n, rf; int tag = -1, screen = -1, flags = -1; unsigned long ir, il; long *ret; XWindowAttributes wa; - Window usl, usl2, *w = NULL; + Window usl, usl2, *w = NULL, tm; Atom rt; SLIST_INIT(&W->h.client); @@ -243,6 +243,7 @@ wmfs_scan(void) == Success && ret) { flags = *ret; + flags &= ~(CLIENT_TABBED | CLIENT_REMOVEALL); XFree(ret); } @@ -256,11 +257,24 @@ wmfs_scan(void) g.w = ret[2]; g.h = ret[3]; + XFree(ret); + } + + if(XGetWindowProperty(W->dpy, w[i], ATOM("_WMFS_TABMASTER"), 0, 32, + False, XA_WINDOW, &rt, &rf, &ir, &il, + (unsigned char**)&ret) + == Success && ret) + { + tm = *ret; XFree(ret); } c = client_new(w[i], &wa, true); + if(tm != c->win) + c->tmp = tm; + tm = 0; + if(flags != -1) c->flags |= flags; @@ -275,6 +289,11 @@ wmfs_scan(void) } } + /* Re-adjust tabbed clients */ + SLIST_FOREACH(c, &W->h.client, next) + if((cc = client_gb_win(c->tmp)) && cc != c) + _client_tab(c, cc); + XFree(w); } @@ -348,7 +367,7 @@ wmfs_quit(void) { c = SLIST_FIRST(&W->h.client); client_update_props(c, CPROP_LOC | CPROP_FLAG | CPROP_GEO); - c->flags |= CLIENT_IGNORE_LAYOUT; + c->flags |= (CLIENT_IGNORE_LAYOUT | CLIENT_REMOVEALL); client_remove(c); } diff --git a/src/wmfs.h b/src/wmfs.h index 4f85666..556236a 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -163,8 +163,9 @@ struct client #define CLIENT_TABBED 0x40 #define CLIENT_TABMASTER 0x80 #define CLIENT_DYING 0x100 /* Saddest flag ever */ +#define CLIENT_REMOVEALL 0x200 Flags flags; - Window win, frame; + Window win, frame, tmp; SLIST_ENTRY(client) next; /* Global list */ SLIST_ENTRY(client) tnext; /* struct tag list */ SLIST_ENTRY(client) tbnext; /* Tabbed client list */