From 871c9f24ba413a7c528ddff2d5c4c8f1601364f3 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 21 Aug 2015 15:52:49 +0000 Subject: Bring group and client cycle closer together. --- group.c | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'group.c') diff --git a/group.c b/group.c index 1bf2fd7..bbcd6cf 100644 --- a/group.c +++ b/group.c @@ -32,6 +32,8 @@ #include "calmwm.h" +static struct group_ctx *group_next(struct group_ctx *); +static struct group_ctx *group_prev(struct group_ctx *); static void group_assign(struct group_ctx *, struct client_ctx *); static void group_restack(struct group_ctx *); static void group_setactive(struct group_ctx *); @@ -255,36 +257,28 @@ group_only(struct screen_ctx *sc, int idx) } } -/* - * Cycle through active groups. If none exist, then just stay put. - */ void group_cycle(struct screen_ctx *sc, int flags) { - struct group_ctx *gc, *showgroup = NULL; + struct group_ctx *newgc, *oldgc, *showgroup = NULL; - if (((gc = sc->group_active)) == NULL) - errx(1, "group_cycle: no active group"); + oldgc = sc->group_active; + newgc = oldgc; for (;;) { - gc = (flags & CWM_RCYCLE) ? TAILQ_PREV(gc, group_ctx_q, - entry) : TAILQ_NEXT(gc, entry); - if (gc == NULL) - gc = (flags & CWM_RCYCLE) ? TAILQ_LAST(&sc->groupq, - group_ctx_q) : TAILQ_FIRST(&sc->groupq); - if (gc == sc->group_active) + newgc = (flags & CWM_RCYCLE) ? group_prev(newgc) : + group_next(newgc); + + if (newgc == oldgc) break; - if (!group_holds_only_sticky(gc) && showgroup == NULL) - showgroup = gc; - else if (!group_holds_only_hidden(gc)) - group_hide(gc); + if (!group_holds_only_sticky(newgc) && showgroup == NULL) + showgroup = newgc; + else if (!group_holds_only_hidden(newgc)) + group_hide(newgc); } - if (showgroup == NULL) - return; - - group_hide(sc->group_active); + group_hide(oldgc); if (group_holds_only_hidden(showgroup)) group_show(showgroup); @@ -292,6 +286,26 @@ group_cycle(struct screen_ctx *sc, int flags) group_setactive(showgroup); } +static struct group_ctx * +group_next(struct group_ctx *gc) +{ + struct screen_ctx *sc = gc->sc; + struct group_ctx *newgc; + + return(((newgc = TAILQ_NEXT(gc, entry)) != NULL) ? + newgc : TAILQ_FIRST(&sc->groupq)); +} + +static struct group_ctx * +group_prev(struct group_ctx *gc) +{ + struct screen_ctx *sc = gc->sc; + struct group_ctx *newgc; + + return(((newgc = TAILQ_PREV(gc, group_ctx_q, entry)) != NULL) ? + newgc : TAILQ_LAST(&sc->groupq, group_ctx_q)); +} + void group_alltoggle(struct screen_ctx *sc) { -- cgit 1.4.1 From b224945446083ec061cea8ae41ee98190f7a4185 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 23 Aug 2015 17:31:20 +0000 Subject: Move CLIENT_STICKY logic from client hide/unhide to group hide/unhide; rationale being that clients should be able to hide/unhide independently of group switching. --- client.c | 6 ------ group.c | 12 ++++++++---- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'group.c') diff --git a/client.c b/client.c index 7faf0ef..6b3ab11 100644 --- a/client.c +++ b/client.c @@ -493,9 +493,6 @@ client_ptrsave(struct client_ctx *cc) void client_hide(struct client_ctx *cc) { - if (cc->flags & CLIENT_STICKY) - return; - XUnmapWindow(X_Dpy, cc->win); cc->flags &= ~CLIENT_ACTIVE; @@ -509,9 +506,6 @@ client_hide(struct client_ctx *cc) void client_unhide(struct client_ctx *cc) { - if (cc->flags & CLIENT_STICKY) - return; - XMapRaised(X_Dpy, cc->win); cc->flags &= ~CLIENT_HIDDEN; diff --git a/group.c b/group.c index bbcd6cf..c2d4b36 100644 --- a/group.c +++ b/group.c @@ -64,8 +64,10 @@ group_hide(struct group_ctx *gc) screen_updatestackingorder(gc->sc); - TAILQ_FOREACH(cc, &gc->clientq, group_entry) - client_hide(cc); + TAILQ_FOREACH(cc, &gc->clientq, group_entry) { + if (!(cc->flags & CLIENT_STICKY)) + client_hide(cc); + } } void @@ -73,8 +75,10 @@ group_show(struct group_ctx *gc) { struct client_ctx *cc; - TAILQ_FOREACH(cc, &gc->clientq, group_entry) - client_unhide(cc); + TAILQ_FOREACH(cc, &gc->clientq, group_entry) { + if (!(cc->flags & CLIENT_STICKY)) + client_unhide(cc); + } group_restack(gc); group_setactive(gc); -- cgit 1.4.1 From 96262a6b0cc6dbf5d82fcac45b81cbc376c2a0ef Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 25 Aug 2015 18:29:10 +0000 Subject: Split out sticky mode checks and the restoring of a client's group and _NET_WM_DESKTOP from the config-based auto-grouping; no (intentional) behavior changes. Needed for further work in cleaning up this area. --- calmwm.h | 4 +++- client.c | 14 +++++++++--- group.c | 77 +++++++++++++++++++++++++++++++++++++--------------------------- 3 files changed, 59 insertions(+), 36 deletions(-) (limited to 'group.c') diff --git a/calmwm.h b/calmwm.h index f1b110b..08631ad 100644 --- a/calmwm.h +++ b/calmwm.h @@ -426,7 +426,8 @@ void client_warp(struct client_ctx *); void client_wm_hints(struct client_ctx *); void group_alltoggle(struct screen_ctx *); -void group_autogroup(struct client_ctx *); +void group_assign(struct group_ctx *, struct client_ctx *); +int group_autogroup(struct client_ctx *); void group_cycle(struct screen_ctx *, int); void group_hide(struct group_ctx *); void group_hidetoggle(struct screen_ctx *, int); @@ -435,6 +436,7 @@ int group_holds_only_sticky(struct group_ctx *); void group_init(struct screen_ctx *, int); void group_movetogroup(struct client_ctx *, int); void group_only(struct screen_ctx *, int); +int group_restore(struct client_ctx *); void group_show(struct group_ctx *); void group_toggle_membership_enter(struct client_ctx *); void group_toggle_membership_leave(struct client_ctx *); diff --git a/client.c b/client.c index 3a3e66e..ff492de 100644 --- a/client.c +++ b/client.c @@ -120,9 +120,17 @@ client_init(Window win, struct screen_ctx *sc) else client_unhide(cc); - if (mapped) - group_autogroup(cc); - + if (mapped) { + if (group_restore(cc)) + goto out; + if (group_autogroup(cc)) + goto out; + if (Conf.flags & CONF_STICKY_GROUPS) + group_assign(sc->group_active, cc); + else + group_assign(NULL, cc); + } +out: XSync(X_Dpy, False); XUngrabServer(X_Dpy); diff --git a/group.c b/group.c index c2d4b36..fa7d8c9 100644 --- a/group.c +++ b/group.c @@ -34,7 +34,6 @@ static struct group_ctx *group_next(struct group_ctx *); static struct group_ctx *group_prev(struct group_ctx *); -static void group_assign(struct group_ctx *, struct client_ctx *); static void group_restack(struct group_ctx *); static void group_setactive(struct group_ctx *); @@ -43,7 +42,7 @@ const char *num_to_name[] = { "seven", "eight", "nine" }; -static void +void group_assign(struct group_ctx *gc, struct client_ctx *cc) { if (cc->group != NULL) @@ -324,51 +323,65 @@ group_alltoggle(struct screen_ctx *sc) sc->hideall = !sc->hideall; } -void -group_autogroup(struct client_ctx *cc) +int +group_restore(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - struct autogroupwin *aw; struct group_ctx *gc; - int num = -2, both_match = 0; + int num = -1; long *grpnum; - if (cc->ch.res_class == NULL || cc->ch.res_name == NULL) - return; + if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 1L, + (unsigned char **)&grpnum) <= 0) + return(0); - if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], - XA_CARDINAL, 1, (unsigned char **)&grpnum) > 0) { - num = *grpnum; - if (num > CALMWM_NGROUPS || num < -1) - num = CALMWM_NGROUPS - 1; - XFree(grpnum); - } else { - TAILQ_FOREACH(aw, &Conf.autogroupq, entry) { - if (strcmp(aw->class, cc->ch.res_class) == 0) { - if ((aw->name != NULL) && - (strcmp(aw->name, cc->ch.res_name) == 0)) { - num = aw->num; - both_match = 1; - } else if (aw->name == NULL && !both_match) - num = aw->num; - } - } - } + num = MIN(*grpnum, (CALMWM_NGROUPS - 1)); + XFree(grpnum); if ((num == -1) || (num == 0)) { group_assign(NULL, cc); - return; + return(1); } - TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == num) { group_assign(gc, cc); - return; + return(1); } } + return(0); +} - if (Conf.flags & CONF_STICKY_GROUPS) - group_assign(sc->group_active, cc); - else +int +group_autogroup(struct client_ctx *cc) +{ + struct screen_ctx *sc = cc->sc; + struct autogroupwin *aw; + struct group_ctx *gc; + int num = -1, both_match = 0; + + if (cc->ch.res_class == NULL || cc->ch.res_name == NULL) + return(0); + + TAILQ_FOREACH(aw, &Conf.autogroupq, entry) { + if (strcmp(aw->class, cc->ch.res_class) == 0) { + if ((aw->name != NULL) && + (strcmp(aw->name, cc->ch.res_name) == 0)) { + num = aw->num; + both_match = 1; + } else if (aw->name == NULL && !both_match) + num = aw->num; + } + } + + if (num == 0) { group_assign(NULL, cc); + return(1); + } + TAILQ_FOREACH(gc, &sc->groupq, entry) { + if (gc->num == num) { + group_assign(gc, cc); + return(1); + } + } + return(0); } -- cgit 1.4.1 From cb60a4b917a4e72cd579f1f7bc8d863be00498bb Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 25 Aug 2015 19:49:19 +0000 Subject: Allowing sending a valid 'nogroup' (0) group_ctx to group_assign() (since we init all groups), though assigning the client's group to NULL for 'sticky'; use this simplification in a few places (others to follow). --- group.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'group.c') diff --git a/group.c b/group.c index fa7d8c9..30a6f53 100644 --- a/group.c +++ b/group.c @@ -48,6 +48,9 @@ group_assign(struct group_ctx *gc, struct client_ctx *cc) if (cc->group != NULL) TAILQ_REMOVE(&cc->group->clientq, cc, group_entry); + if ((gc != NULL) && (gc->num == 0)) + gc = NULL; + cc->group = gc; if (cc->group != NULL) @@ -129,6 +132,8 @@ group_init(struct screen_ctx *sc, int num) gc->num = num; TAILQ_INIT(&gc->clientq); + fprintf(stderr, "%d: %s\n", gc->num, gc->name); + TAILQ_INSERT_TAIL(&sc->groupq, gc, entry); if (num == 1) @@ -338,7 +343,7 @@ group_restore(struct client_ctx *cc) num = MIN(*grpnum, (CALMWM_NGROUPS - 1)); XFree(grpnum); - if ((num == -1) || (num == 0)) { + if (num == -1) { group_assign(NULL, cc); return(1); } @@ -373,10 +378,6 @@ group_autogroup(struct client_ctx *cc) } } - if (num == 0) { - group_assign(NULL, cc); - return(1); - } TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == num) { group_assign(gc, cc); -- cgit 1.4.1 From 871ed39ccf6b6ab7385c87f849a7c9bcff130792 Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 25 Aug 2015 19:52:02 +0000 Subject: oops; remove left over debug print --- group.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'group.c') diff --git a/group.c b/group.c index 30a6f53..0857437 100644 --- a/group.c +++ b/group.c @@ -132,8 +132,6 @@ group_init(struct screen_ctx *sc, int num) gc->num = num; TAILQ_INIT(&gc->clientq); - fprintf(stderr, "%d: %s\n", gc->num, gc->name); - TAILQ_INSERT_TAIL(&sc->groupq, gc, entry); if (num == 1) -- cgit 1.4.1 From 6d53091429e074e0d5bd504a9001016106d2d1ac Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 25 Aug 2015 20:35:49 +0000 Subject: Further simplify _NET_WM_DESKTOP handling using new group_assign(). --- group.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'group.c') diff --git a/group.c b/group.c index 0857437..5482d70 100644 --- a/group.c +++ b/group.c @@ -331,20 +331,17 @@ group_restore(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; struct group_ctx *gc; - int num = -1; + int num; long *grpnum; if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 1L, (unsigned char **)&grpnum) <= 0) return(0); - num = MIN(*grpnum, (CALMWM_NGROUPS - 1)); + num = (*grpnum == -1) ? 0 : *grpnum; + num = MIN(num, (CALMWM_NGROUPS - 1)); XFree(grpnum); - if (num == -1) { - group_assign(NULL, cc); - return(1); - } TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == num) { group_assign(gc, cc); -- cgit 1.4.1 From 5391659629a7fa75b7447e824e56e179c10ca642 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 27 Aug 2015 17:43:44 +0000 Subject: Re-add lost chunk in group_cycle from r1.113. --- group.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'group.c') diff --git a/group.c b/group.c index 5482d70..3cb5e79 100644 --- a/group.c +++ b/group.c @@ -284,6 +284,9 @@ group_cycle(struct screen_ctx *sc, int flags) group_hide(newgc); } + if (showgroup == NULL) + return; + group_hide(oldgc); if (group_holds_only_hidden(showgroup)) -- cgit 1.4.1 From 28d4001ecaf57a722ec418f8b8b955242402e5a2 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 27 Aug 2015 18:53:14 +0000 Subject: Mechanical change: group->gc --- calmwm.h | 2 +- client.c | 14 +++++++------- group.c | 12 ++++++------ search.c | 2 +- xutil.c | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'group.c') diff --git a/calmwm.h b/calmwm.h index 08631ad..039dc36 100644 --- a/calmwm.h +++ b/calmwm.h @@ -147,6 +147,7 @@ struct client_ctx { TAILQ_ENTRY(client_ctx) entry; TAILQ_ENTRY(client_ctx) group_entry; struct screen_ctx *sc; + struct group_ctx *gc; Window win; Colormap colormap; unsigned int bwidth; /* border width */ @@ -198,7 +199,6 @@ struct client_ctx { char *name; char *label; char *matchname; - struct group_ctx *group; XClassHint ch; XWMHints *wmh; }; diff --git a/client.c b/client.c index 396ba70..54eced1 100644 --- a/client.c +++ b/client.c @@ -163,8 +163,8 @@ client_delete(struct client_ctx *cc) xu_ewmh_net_client_list(sc); xu_ewmh_net_client_list_stacking(sc); - if (cc->group != NULL) - TAILQ_REMOVE(&cc->group->clientq, cc, group_entry); + if (cc->gc != NULL) + TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry); if (cc == client_current()) client_none(sc); @@ -682,7 +682,7 @@ client_cycle(struct screen_ctx *sc, int flags) /* Only cycle visible and non-ignored windows. */ if ((newcc->flags & (CLIENT_HIDDEN | CLIENT_IGNORE)) || ((flags & CWM_INGROUP) && - (newcc->group != oldcc->group))) + (newcc->gc != oldcc->gc))) again = 1; /* Is oldcc the only non-hidden window? */ @@ -915,8 +915,8 @@ client_transient(struct client_ctx *cc) Window trans; if (XGetTransientForHint(X_Dpy, cc->win, &trans)) { - if ((tc = client_find(trans)) != NULL && tc->group) { - group_movetogroup(cc, tc->group->num); + if ((tc = client_find(trans)) != NULL && tc->gc) { + group_movetogroup(cc, tc->gc->num); if (tc->flags & CLIENT_IGNORE) cc->flags |= CLIENT_IGNORE; } @@ -961,7 +961,7 @@ void client_htile(struct client_ctx *cc) { struct client_ctx *ci; - struct group_ctx *gc = cc->group; + struct group_ctx *gc = cc->gc; struct screen_ctx *sc = cc->sc; struct geom area; int i, n, mh, x, h, w; @@ -1020,7 +1020,7 @@ void client_vtile(struct client_ctx *cc) { struct client_ctx *ci; - struct group_ctx *gc = cc->group; + struct group_ctx *gc = cc->gc; struct screen_ctx *sc = cc->sc; struct geom area; int i, n, mw, y, h, w; diff --git a/group.c b/group.c index 3cb5e79..c455bcd 100644 --- a/group.c +++ b/group.c @@ -45,15 +45,15 @@ const char *num_to_name[] = { void group_assign(struct group_ctx *gc, struct client_ctx *cc) { - if (cc->group != NULL) - TAILQ_REMOVE(&cc->group->clientq, cc, group_entry); + if (cc->gc != NULL) + TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry); if ((gc != NULL) && (gc->num == 0)) gc = NULL; - cc->group = gc; + cc->gc = gc; - if (cc->group != NULL) + if (cc->gc != NULL) TAILQ_INSERT_TAIL(&gc->clientq, cc, group_entry); xu_ewmh_net_wm_desktop(cc); @@ -162,7 +162,7 @@ group_movetogroup(struct client_ctx *cc, int idx) break; } - if (cc->group == gc) + if (cc->gc == gc) return; if (group_holds_only_hidden(gc)) client_hide(cc); @@ -175,7 +175,7 @@ group_toggle_membership_enter(struct client_ctx *cc) struct screen_ctx *sc = cc->sc; struct group_ctx *gc = sc->group_active; - if (gc == cc->group) { + if (gc == cc->gc) { group_assign(NULL, cc); cc->flags |= CLIENT_UNGROUP; } else { diff --git a/search.c b/search.c index 3192bff..aa409e0 100644 --- a/search.c +++ b/search.c @@ -156,7 +156,7 @@ search_print_client(struct menu *mi, int list) cc->matchname = cc->name; (void)snprintf(mi->print, sizeof(mi->print), "(%d) %c[%s] %s", - (cc->group) ? cc->group->num : 0, flag, + (cc->gc) ? cc->gc->num : 0, flag, (cc->label) ? cc->label : "", cc->matchname); } diff --git a/xutil.c b/xutil.c index f61aeef..a831794 100644 --- a/xutil.c +++ b/xutil.c @@ -362,8 +362,8 @@ xu_ewmh_net_wm_desktop(struct client_ctx *cc) { long num = 0xffffffff; - if (cc->group) - num = cc->group->num; + if (cc->gc) + num = cc->gc->num; XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&num, 1); -- cgit 1.4.1