diff --git a/src/client.c b/src/client.c index 608a96a..2a34698 100644 --- a/src/client.c +++ b/src/client.c @@ -450,8 +450,9 @@ _client_tab(struct client *c, struct client *cm) static void client_untab(struct client *c) { - struct client *cc = c->tabmaster; + struct client *ct, *cc = c->tabmaster; struct geo og = c->geo; + bool chk = false; if(c->flags & CLIENT_REMOVEALL || !(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER))) return; @@ -471,6 +472,20 @@ client_untab(struct client *c) if(!(c->flags & CLIENT_DYING)) { + + /* Looking for tabbed client in cc, if there is not + * remove cc CLIENT_TABMASTER flag. + */ + SLIST_FOREACH(ct, &c->tag->clients, tnext) + if(ct->tabmaster == cc) + { + chk = true; + break; + } + + if(!chk) + cc->flags &= ~CLIENT_TABMASTER; + c->geo = c->tgeo = og; layout_split_integrate(c, cc); diff --git a/src/config.h b/src/config.h index a2197aa..a15f3e3 100644 --- a/src/config.h +++ b/src/config.h @@ -25,10 +25,11 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] = { "reload", uicb_reload }, /* Tag */ - { "tag_set", uicb_tag_set }, - { "tag", uicb_tag_set_with_name }, - { "tag_next", uicb_tag_next }, - { "tag_prev", uicb_tag_prev }, + { "tag_set", uicb_tag_set }, + { "tag", uicb_tag_set_with_name }, + { "tag_next", uicb_tag_next }, + { "tag_prev", uicb_tag_prev }, + { "tag_client", uicb_tag_client }, /* Layout */ { "layout_vmirror", uicb_layout_vmirror }, diff --git a/src/tag.c b/src/tag.c index dfc9a9f..cc176dd 100644 --- a/src/tag.c +++ b/src/tag.c @@ -43,9 +43,13 @@ tag_screen(struct screen *s, struct tag *t) { struct client *c; + t->prev = s->seltag; + s->seltag = t; + /* Unmap previous tag's frame */ - SLIST_FOREACH(c, &s->seltag->clients, tnext) - client_unmap(c); + if(t->prev != t) + SLIST_FOREACH(c, &t->prev->clients, tnext) + client_unmap(c); /* * Map selected tag's frame, only if there is @@ -60,8 +64,6 @@ tag_screen(struct screen *s, struct tag *t) client_focus( client_tab_next(t->sel)); } - s->seltag = t; - infobar_elem_screen_update(s, ElemTag); ewmh_update_wmfs_props(); @@ -71,12 +73,10 @@ tag_screen(struct screen *s, struct tag *t) void tag_client(struct tag *t, struct client *c) { - struct tag *ot = c->tag; - /* Remove client from its previous tag */ if(c->tag && !(c->flags & CLIENT_RULED)) { - if(c->tag == t || c->flags & CLIENT_TABBED) + if(c->tag == t) return; if(!(c->flags & CLIENT_IGNORE_LAYOUT)) @@ -97,6 +97,7 @@ tag_client(struct tag *t, struct client *c) if(!t) return; + c->prevtag = c->tag; c->tag = t; client_update_props(c, CPROP_LOC); @@ -109,17 +110,20 @@ tag_client(struct tag *t, struct client *c) if(c->flags & CLIENT_IGNORE_LAYOUT) c->flags ^= CLIENT_IGNORE_LAYOUT; - else + else if(!(c->flags & CLIENT_TABBED)) layout_split_integrate(c, t->sel); if(c->flags & CLIENT_TABMASTER) { struct client *cc; - SLIST_FOREACH(cc, &ot->clients, tnext) + SLIST_FOREACH(cc, &c->prevtag->clients, tnext) if(cc->tabmaster == c) - cc->tag = t; + tag_client(t, cc); } + + if(t != W->screen->seltag) + client_unmap(c); } void @@ -129,7 +133,7 @@ uicb_tag_set(Uicb cmd) struct tag *t; TAILQ_FOREACH(t, &W->screen->tags, next) - if(++i == n) + if(++i == n && t != W->screen->seltag) { tag_screen(W->screen, t); return; @@ -142,7 +146,7 @@ uicb_tag_set_with_name(Uicb cmd) struct tag *t; TAILQ_FOREACH(t, &W->screen->tags, next) - if(!strcmp(cmd, t->name)) + if(!strcmp(cmd, t->name) && t != W->screen->seltag) { tag_screen(W->screen, t); return; @@ -173,6 +177,17 @@ uicb_tag_prev(Uicb cmd) tag_screen(W->screen, TAILQ_LAST(&W->screen->tags, tsub)); } +void +uicb_tag_client(Uicb cmd) +{ + struct tag *t; + int id = ATOI(cmd); + + if((t = tag_gb_id(W->screen, id))) + tag_client(t, W->client); +} + + static void tag_remove(struct tag *t) { diff --git a/src/tag.h b/src/tag.h index 20a62b3..345b98a 100644 --- a/src/tag.h +++ b/src/tag.h @@ -29,5 +29,7 @@ void uicb_tag_set(Uicb cmd); void uicb_tag_set_with_name(Uicb cmd); void uicb_tag_next(Uicb cmd); void uicb_tag_prev(Uicb cmd); +void uicb_tag_client(Uicb cmd); + #endif /* TAG_H */ diff --git a/src/wmfs.c b/src/wmfs.c index 3c2a4e7..68a6001 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -195,23 +195,6 @@ wmfs_scan(void) SLIST_INIT(&W->h.client); - /* Set back selected tag */ - if(XGetWindowProperty(W->dpy, W->root, W->net_atom[wmfs_current_tag], 0, 32, - False, XA_CARDINAL, &rt, &rf, &ir, &il, - (unsigned char**)&ret) - == Success && ret) - { - struct screen *s; - - for(i = 0; i < (int)ir; ++i) - { - s = screen_gb_id(i); - tag_screen(s, tag_gb_id(s, ret[i])); - } - - XFree(ret); - } - if(XQueryTree(W->dpy, W->root, &usl, &usl2, &w, (unsigned int*)&n)) for(i = n - 1; i != -1; --i) { @@ -257,7 +240,7 @@ wmfs_scan(void) g.w = ret[2]; g.h = ret[3]; - XFree(ret); + XFree(ret); } if(XGetWindowProperty(W->dpy, w[i], ATOM("_WMFS_TABMASTER"), 0, 32, @@ -294,6 +277,23 @@ wmfs_scan(void) if((cc = client_gb_win(c->tmp)) && cc != c) _client_tab(c, cc); + /* Set back selected tag */ + if(XGetWindowProperty(W->dpy, W->root, W->net_atom[wmfs_current_tag], 0, 32, + False, XA_CARDINAL, &rt, &rf, &ir, &il, + (unsigned char**)&ret) + == Success && ret) + { + struct screen *s; + + for(i = 0; i < (int)ir; ++i) + { + s = screen_gb_id(i); + tag_screen(s, tag_gb_id(s, ret[i])); + } + + XFree(ret); + } + XFree(w); } diff --git a/src/wmfs.h b/src/wmfs.h index 556236a..a7ccff7 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -134,6 +134,7 @@ struct tag struct screen *screen; struct client *sel; struct client *prevsel; + struct tag *prev; char *name; int id; Flags flags; @@ -144,7 +145,7 @@ struct tag struct client { - struct tag *tag; + struct tag *tag, *prevtag; struct screen *screen; struct barwin *titlebar; struct geo geo, wgeo, tgeo, ttgeo, rgeo, *tbgeo;