From 11920071711238fdfcaf89feb35ab1bf68160347 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 18 Aug 2014 13:57:57 +0000 Subject: Get rid of nhidden in group_ctx; it actually never reported correctly since nhidden wasn't incremented nor decremeted in all the right places, thus confusing matters. We don't need to carry a count around, so just use a local variable in the one place we need one to supply XRestackWindows(). --- calmwm.h | 1 - group.c | 12 +++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/calmwm.h b/calmwm.h index be0a08c..bc4833c 100644 --- a/calmwm.h +++ b/calmwm.h @@ -205,7 +205,6 @@ struct group_ctx { struct client_ctx_q clients; int shortcut; int hidden; - int nhidden; int highstack; }; TAILQ_HEAD(group_ctx_q, group_ctx); diff --git a/group.c b/group.c index 8552055..c4af66f 100644 --- a/group.c +++ b/group.c @@ -68,15 +68,13 @@ group_hide(struct screen_ctx *sc, struct group_ctx *gc) screen_updatestackingorder(sc); - gc->nhidden = 0; gc->highstack = 0; TAILQ_FOREACH(cc, &gc->clients, group_entry) { client_hide(cc); - gc->nhidden++; if (cc->stackingorder > gc->highstack) gc->highstack = cc->stackingorder; } - gc->hidden = 1; /* XXX: equivalent to gc->nhidden > 0 */ + gc->hidden = 1; } static void @@ -85,6 +83,7 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) struct client_ctx *cc; Window *winlist; int i, lastempty = -1; + int nwins = 0; gc->highstack = 0; TAILQ_FOREACH(cc, &gc->clients, group_entry) { @@ -100,6 +99,7 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) TAILQ_FOREACH(cc, &gc->clients, group_entry) { winlist[gc->highstack - cc->stackingorder] = cc->win; client_unhide(cc); + nwins++; } /* Un-sparseify */ @@ -113,7 +113,7 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) } } - XRestackWindows(X_Dpy, winlist, gc->nhidden); + XRestackWindows(X_Dpy, winlist, nwins); free(winlist); gc->hidden = 0; @@ -177,10 +177,8 @@ group_movetogroup(struct client_ctx *cc, int idx) gc = &sc->groups[idx]; if (cc->group == gc) return; - if (gc->hidden) { + if (gc->hidden) client_hide(cc); - gc->nhidden++; - } group_assign(gc, cc); } -- cgit 1.4.1 From 01cca3c114a6a4b82892c7c6f34b00dd898a5900 Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 19 Aug 2014 12:47:51 +0000 Subject: Pull highstack from group_ctx (and useless calculations of); in the one place that we use highstack, replace that usage with a local variable (for now until stacking is done properly). --- calmwm.h | 1 - group.c | 25 +++++++++---------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/calmwm.h b/calmwm.h index bc4833c..f06a2fb 100644 --- a/calmwm.h +++ b/calmwm.h @@ -205,7 +205,6 @@ struct group_ctx { struct client_ctx_q clients; int shortcut; int hidden; - int highstack; }; TAILQ_HEAD(group_ctx_q, group_ctx); diff --git a/group.c b/group.c index c4af66f..647b3d1 100644 --- a/group.c +++ b/group.c @@ -68,12 +68,9 @@ group_hide(struct screen_ctx *sc, struct group_ctx *gc) screen_updatestackingorder(sc); - gc->highstack = 0; - TAILQ_FOREACH(cc, &gc->clients, group_entry) { + TAILQ_FOREACH(cc, &gc->clients, group_entry) client_hide(cc); - if (cc->stackingorder > gc->highstack) - gc->highstack = cc->stackingorder; - } + gc->hidden = 1; } @@ -83,27 +80,23 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) struct client_ctx *cc; Window *winlist; int i, lastempty = -1; - int nwins = 0; + int nwins = 0, highstack = 0; - gc->highstack = 0; TAILQ_FOREACH(cc, &gc->clients, group_entry) { - if (cc->stackingorder > gc->highstack) - gc->highstack = cc->stackingorder; + if (cc->stackingorder > highstack) + highstack = cc->stackingorder; } - winlist = xcalloc((gc->highstack + 1), sizeof(*winlist)); + winlist = xcalloc((highstack + 1), sizeof(*winlist)); - /* - * Invert the stacking order as XRestackWindows() expects them - * top-to-bottom. - */ + /* Invert the stacking order for XRestackWindows(). */ TAILQ_FOREACH(cc, &gc->clients, group_entry) { - winlist[gc->highstack - cc->stackingorder] = cc->win; + winlist[highstack - cc->stackingorder] = cc->win; client_unhide(cc); nwins++; } /* Un-sparseify */ - for (i = 0; i <= gc->highstack; i++) { + for (i = 0; i <= highstack; i++) { if (!winlist[i] && lastempty == -1) lastempty = i; else if (winlist[i] && lastempty != -1) { -- cgit 1.4.1 From 6c835fd5854bab5de651757ba987b660ceb492a1 Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 19 Aug 2014 18:39:41 +0000 Subject: Remove unnecessary memset since reload was replaced with restart; from Kent Spillner. --- conf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/conf.c b/conf.c index 8a2854c..528cdf2 100644 --- a/conf.c +++ b/conf.c @@ -250,8 +250,6 @@ conf_init(struct conf *c) { unsigned int i; - (void)memset(c, 0, sizeof(*c)); - c->bwidth = CONF_BWIDTH; c->mamount = CONF_MAMOUNT; c->snapdist = CONF_SNAPDIST; -- cgit 1.4.1 From 5d22b261a61ae114cf969e3687571a4cc08c4044 Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 20 Aug 2014 12:33:12 +0000 Subject: fix a misleading comment and function name --- group.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/group.c b/group.c index 647b3d1..008118b 100644 --- a/group.c +++ b/group.c @@ -35,7 +35,7 @@ static void group_assign(struct group_ctx *, struct client_ctx *); static void group_hide(struct screen_ctx *, struct group_ctx *); static void group_show(struct screen_ctx *, struct group_ctx *); -static void group_fix_hidden_state(struct group_ctx *); +static void group_set_hidden_state(struct group_ctx *); static void group_setactive(struct screen_ctx *, long); static void group_set_names(struct screen_ctx *); @@ -147,7 +147,7 @@ group_set_state(struct screen_ctx *sc) struct group_ctx *gc; TAILQ_FOREACH(gc, &sc->groupq, entry) - group_fix_hidden_state(gc); + group_set_hidden_state(gc); } static void @@ -203,10 +203,10 @@ group_sticky_toggle_exit(struct client_ctx *cc) } /* - * if group_hidetoggle would produce no effect, toggle the group's hidden state + * If all clients in a group are hidden, then set the group state as hidden. */ static void -group_fix_hidden_state(struct group_ctx *gc) +group_set_hidden_state(struct group_ctx *gc) { struct client_ctx *cc; int same = 0; @@ -229,7 +229,7 @@ group_hidetoggle(struct screen_ctx *sc, int idx) errx(1, "group_hidetoggle: index out of range (%d)", idx); gc = &sc->groups[idx]; - group_fix_hidden_state(gc); + group_set_hidden_state(gc); if (gc->hidden) group_show(sc, gc); -- cgit 1.4.1 From 7f4547153815a2851b158fab11de1ea6d96dba76 Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 20 Aug 2014 12:35:39 +0000 Subject: whitespace --- screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/screen.c b/screen.c index 993e4fc..2a38831 100644 --- a/screen.c +++ b/screen.c @@ -105,7 +105,7 @@ screen_updatestackingorder(struct screen_ctx *sc) if ((cc = client_find(wins[i])) == NULL || cc->flags & CLIENT_HIDDEN) continue; - + cc->stackingorder = s++; } XFree(wins); -- cgit 1.4.1 From 30da2211ddbc39036e98ae951ea53d9a1793c376 Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 20 Aug 2014 13:42:27 +0000 Subject: Split off group window restacking. --- group.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/group.c b/group.c index 008118b..5eefea8 100644 --- a/group.c +++ b/group.c @@ -35,6 +35,7 @@ static void group_assign(struct group_ctx *, struct client_ctx *); static void group_hide(struct screen_ctx *, struct group_ctx *); static void group_show(struct screen_ctx *, struct group_ctx *); +static void group_restack(struct screen_ctx *, struct group_ctx *); static void group_set_hidden_state(struct group_ctx *); static void group_setactive(struct screen_ctx *, long); static void group_set_names(struct screen_ctx *); @@ -76,6 +77,20 @@ group_hide(struct screen_ctx *sc, struct group_ctx *gc) static void group_show(struct screen_ctx *sc, struct group_ctx *gc) +{ + struct client_ctx *cc; + + TAILQ_FOREACH(cc, &gc->clients, group_entry) + client_unhide(cc); + + gc->hidden = 0; + + group_restack(sc, gc); + group_setactive(sc, gc->shortcut); +} + +static void +group_restack(struct screen_ctx *sc, struct group_ctx *gc) { struct client_ctx *cc; Window *winlist; @@ -91,7 +106,6 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) /* Invert the stacking order for XRestackWindows(). */ TAILQ_FOREACH(cc, &gc->clients, group_entry) { winlist[highstack - cc->stackingorder] = cc->win; - client_unhide(cc); nwins++; } @@ -108,9 +122,6 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) XRestackWindows(X_Dpy, winlist, nwins); free(winlist); - - gc->hidden = 0; - group_setactive(sc, gc->shortcut); } void -- cgit 1.4.1 From b31b09dfc26b4b17c025d7196b8b5a4a26f599df Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 20 Aug 2014 15:15:29 +0000 Subject: Purely mechanical; unify 'num', 'no' and 'shortcut'. --- calmwm.h | 2 +- client.c | 2 +- conf.c | 4 ++-- group.c | 38 +++++++++++++++++++------------------- mousefunc.c | 3 +-- screen.c | 6 +++--- search.c | 2 +- xutil.c | 4 ++-- 8 files changed, 30 insertions(+), 31 deletions(-) diff --git a/calmwm.h b/calmwm.h index f06a2fb..a2693aa 100644 --- a/calmwm.h +++ b/calmwm.h @@ -203,7 +203,7 @@ TAILQ_HEAD(cycle_entry_q, client_ctx); struct group_ctx { TAILQ_ENTRY(group_ctx) entry; struct client_ctx_q clients; - int shortcut; + int num; int hidden; }; TAILQ_HEAD(group_ctx_q, group_ctx); diff --git a/client.c b/client.c index 6fa7c1b..bacfb51 100644 --- a/client.c +++ b/client.c @@ -869,7 +869,7 @@ client_transient(struct client_ctx *cc) if (XGetTransientForHint(X_Dpy, cc->win, &trans)) { if ((tc = client_find(trans)) && tc->group) { - group_movetogroup(cc, tc->group->shortcut); + group_movetogroup(cc, tc->group->num); if (tc->flags & CLIENT_IGNORE) cc->flags |= CLIENT_IGNORE; } diff --git a/conf.c b/conf.c index 528cdf2..c6eb24f 100644 --- a/conf.c +++ b/conf.c @@ -78,7 +78,7 @@ conf_cmd_remove(struct conf *c, const char *name) } } void -conf_autogroup(struct conf *c, int no, const char *val) +conf_autogroup(struct conf *c, int num, const char *val) { struct autogroupwin *aw; char *p; @@ -93,7 +93,7 @@ conf_autogroup(struct conf *c, int no, const char *val) aw->name = xstrdup(val); aw->class = xstrdup(p); } - aw->num = no; + aw->num = num; TAILQ_INSERT_TAIL(&c->autogroupq, aw, entry); } diff --git a/group.c b/group.c index 5eefea8..ef93de3 100644 --- a/group.c +++ b/group.c @@ -40,7 +40,7 @@ static void group_set_hidden_state(struct group_ctx *); static void group_setactive(struct screen_ctx *, long); static void group_set_names(struct screen_ctx *); -const char *shortcut_to_name[] = { +const char *num_to_name[] = { "nogroup", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; @@ -86,7 +86,7 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) gc->hidden = 0; group_restack(sc, gc); - group_setactive(sc, gc->shortcut); + group_setactive(sc, gc->num); } static void @@ -140,7 +140,7 @@ group_init(struct screen_ctx *sc) for (i = 0; i < CALMWM_NGROUPS; i++) { TAILQ_INIT(&sc->groups[i].clients); sc->groups[i].hidden = 0; - sc->groups[i].shortcut = i; + sc->groups[i].num = i; TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry); } @@ -261,7 +261,7 @@ group_only(struct screen_ctx *sc, int idx) errx(1, "group_only: index out of range (%d)", idx); TAILQ_FOREACH(gc, &sc->groupq, entry) { - if (gc->shortcut == idx) + if (gc->num == idx) group_show(sc, gc); else group_hide(sc, gc); @@ -302,7 +302,7 @@ group_cycle(struct screen_ctx *sc, int flags) if (showgroup->hidden) group_show(sc, showgroup); else - group_setactive(sc, showgroup->shortcut); + group_setactive(sc, showgroup->num); } void @@ -319,7 +319,7 @@ group_menu(struct screen_ctx *sc) continue; menuq_add(&menuq, gc, gc->hidden ? "%d: [%s]" : "%d: %s", - gc->shortcut, sc->group_names[gc->shortcut]); + gc->num, sc->group_names[gc->num]); } if (TAILQ_EMPTY(&menuq)) @@ -354,36 +354,36 @@ group_autogroup(struct client_ctx *cc) struct screen_ctx *sc = cc->sc; struct autogroupwin *aw; struct group_ctx *gc; - int no = -1, both_match = 0; - long *grpno; + int num = -1, both_match = 0; + 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, 1, (unsigned char **)&grpno) > 0) { - if (*grpno == -1) - no = 0; - else if (*grpno > CALMWM_NGROUPS || *grpno < 0) - no = CALMWM_NGROUPS - 1; + XA_CARDINAL, 1, (unsigned char **)&grpnum) > 0) { + if (*grpnum == -1) + num = 0; + else if (*grpnum > CALMWM_NGROUPS || *grpnum < 0) + num = CALMWM_NGROUPS - 1; else - no = *grpno; - XFree(grpno); + num = *grpnum; + 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)) { - no = aw->num; + num = aw->num; both_match = 1; } else if (aw->name == NULL && !both_match) - no = aw->num; + num = aw->num; } } } TAILQ_FOREACH(gc, &sc->groupq, entry) { - if (gc->shortcut == no) { + if (gc->num == num) { group_assign(gc, cc); return; } @@ -427,7 +427,7 @@ group_update_names(struct screen_ctx *sc) setnames = 1; i = 0; while (n < CALMWM_NGROUPS) - strings[n++] = xstrdup(shortcut_to_name[i++]); + strings[n++] = xstrdup(num_to_name[i++]); } if (prop_ret != NULL) diff --git a/mousefunc.c b/mousefunc.c index e2b5766..d6373cb 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -202,8 +202,7 @@ mousefunc_menu_unhide(struct client_ctx *cc, union arg *arg) if (wname == NULL) continue; - menuq_add(&menuq, cc, "(%d) %s", - cc->group->shortcut, wname); + menuq_add(&menuq, cc, "(%d) %s", cc->group->num, wname); } if (TAILQ_EMPTY(&menuq)) diff --git a/screen.c b/screen.c index 2a38831..0621065 100644 --- a/screen.c +++ b/screen.c @@ -142,7 +142,7 @@ screen_update_geometry(struct screen_ctx *sc) { XineramaScreenInfo *info = NULL; struct region_ctx *region; - int info_no = 0, i; + int info_num = 0, i; sc->view.x = 0; sc->view.y = 0; @@ -156,13 +156,13 @@ screen_update_geometry(struct screen_ctx *sc) /* RandR event may have a CTRC added or removed. */ if (XineramaIsActive(X_Dpy)) - info = XineramaQueryScreens(X_Dpy, &info_no); + info = XineramaQueryScreens(X_Dpy, &info_num); while ((region = TAILQ_FIRST(&sc->regionq)) != NULL) { TAILQ_REMOVE(&sc->regionq, region, entry); free(region); } - for (i = 0; i < info_no; i++) { + for (i = 0; i < info_num; i++) { region = xmalloc(sizeof(*region)); region->num = i; region->area.x = info[i].x_org; diff --git a/search.c b/search.c index 1e43d20..fd1210e 100644 --- a/search.c +++ b/search.c @@ -143,7 +143,7 @@ search_print_client(struct menu *mi, int list) cc->matchname = cc->name; (void)snprintf(mi->print, sizeof(mi->print), "(%d) %c%s", - cc->group->shortcut, flag, cc->matchname); + cc->group->num, flag, cc->matchname); if (!list && cc->matchname != cc->name && strlen(mi->print) < sizeof(mi->print) - 1) { diff --git a/xutil.c b/xutil.c index 8fdc3ad..3c4d004 100644 --- a/xutil.c +++ b/xutil.c @@ -291,10 +291,10 @@ xu_ewmh_net_desktop_names(struct screen_ctx *sc, char *data, int n) void xu_ewmh_net_wm_desktop(struct client_ctx *cc) { - long no = cc->group->shortcut; + long num = cc->group->num; XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP], - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1); + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&num, 1); } Atom * -- cgit 1.4.1 From fe533fdc8edb2584b40a8bad9f00b8258529854f Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 22 Aug 2014 19:04:00 +0000 Subject: Fix nogroup regression, where nogroup became an actual group - the symantics between cwm groups and ewmh got in the way. Ensure a client that wants to be in nogroup stays in nogroup (thus stays in view), even when (re)reading NET_WM_DESKTOP. Paritially reverts patchset 644 (2014-02-07 13:09 PST) which deals with a NULL cc->group. All to be revisited when NET_WM_STATE_STICKY hits cwm. Reported by many; testing and ok phessler. --- group.c | 23 +++++++++++------------ mousefunc.c | 3 ++- search.c | 2 +- xutil.c | 5 ++++- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/group.c b/group.c index ef93de3..16e274d 100644 --- a/group.c +++ b/group.c @@ -48,17 +48,14 @@ const char *num_to_name[] = { static void group_assign(struct group_ctx *gc, struct client_ctx *cc) { - if (gc == NULL) - gc = TAILQ_FIRST(&cc->sc->groupq); - if (cc->group == gc) - return; - if (cc->group != NULL) TAILQ_REMOVE(&cc->group->clients, cc, group_entry); - TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry); cc->group = gc; + if (cc->group != NULL) + TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry); + xu_ewmh_net_wm_desktop(cc); } @@ -354,7 +351,7 @@ 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; + int num = -2, both_match = 0; long *grpnum; if (cc->ch.res_class == NULL || cc->ch.res_name == NULL) @@ -362,12 +359,9 @@ group_autogroup(struct client_ctx *cc) if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 1, (unsigned char **)&grpnum) > 0) { - if (*grpnum == -1) - num = 0; - else if (*grpnum > CALMWM_NGROUPS || *grpnum < 0) + num = *grpnum; + if (num > CALMWM_NGROUPS || num < -1) num = CALMWM_NGROUPS - 1; - else - num = *grpnum; XFree(grpnum); } else { TAILQ_FOREACH(aw, &Conf.autogroupq, entry) { @@ -382,6 +376,11 @@ group_autogroup(struct client_ctx *cc) } } + if ((num == -1) || (num == 0)) { + group_assign(NULL, cc); + return; + } + TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == num) { group_assign(gc, cc); diff --git a/mousefunc.c b/mousefunc.c index d6373cb..295d3a1 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -202,7 +202,8 @@ mousefunc_menu_unhide(struct client_ctx *cc, union arg *arg) if (wname == NULL) continue; - menuq_add(&menuq, cc, "(%d) %s", cc->group->num, wname); + menuq_add(&menuq, cc, "(%d) %s", + cc->group ? cc->group->num : 0, wname); } if (TAILQ_EMPTY(&menuq)) diff --git a/search.c b/search.c index fd1210e..4b4f457 100644 --- a/search.c +++ b/search.c @@ -143,7 +143,7 @@ search_print_client(struct menu *mi, int list) cc->matchname = cc->name; (void)snprintf(mi->print, sizeof(mi->print), "(%d) %c%s", - cc->group->num, flag, cc->matchname); + cc->group ? cc->group->num : 0, flag, cc->matchname); if (!list && cc->matchname != cc->name && strlen(mi->print) < sizeof(mi->print) - 1) { diff --git a/xutil.c b/xutil.c index 3c4d004..847b148 100644 --- a/xutil.c +++ b/xutil.c @@ -291,7 +291,10 @@ xu_ewmh_net_desktop_names(struct screen_ctx *sc, char *data, int n) void xu_ewmh_net_wm_desktop(struct client_ctx *cc) { - long num = cc->group->num; + long num = 0xffffffff; + + if (cc->group) + num = cc->group->num; XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&num, 1); -- cgit 1.4.1 From 9f36d4af355facd1307989d203fa4f5a780007a1 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 24 Aug 2014 15:37:45 +0000 Subject: gc->hidden has never consistently kept track of a group's state; group_show() and group_hide() are not the only ways a group can change state - if all clients in a group are either hidden or unhidden, then that group's state should change, as well as the various EWMH ways. Instead of trying to keep track in a wide variety of places, simply query the clients in a group before needing to take action based on the group's state. Solves long standing confusion of when a group is hidden or not. --- calmwm.h | 2 -- group.c | 47 ++++++++++++++++++----------------------------- screen.c | 1 - 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/calmwm.h b/calmwm.h index a2693aa..2f55d44 100644 --- a/calmwm.h +++ b/calmwm.h @@ -204,7 +204,6 @@ struct group_ctx { TAILQ_ENTRY(group_ctx) entry; struct client_ctx_q clients; int num; - int hidden; }; TAILQ_HEAD(group_ctx_q, group_ctx); @@ -413,7 +412,6 @@ void group_init(struct screen_ctx *); void group_menu(struct screen_ctx *); void group_movetogroup(struct client_ctx *, int); void group_only(struct screen_ctx *, int); -void group_set_state(struct screen_ctx *); void group_sticky(struct client_ctx *); void group_sticky_toggle_enter(struct client_ctx *); void group_sticky_toggle_exit(struct client_ctx *); diff --git a/group.c b/group.c index 16e274d..1290621 100644 --- a/group.c +++ b/group.c @@ -36,7 +36,7 @@ static void group_assign(struct group_ctx *, struct client_ctx *); static void group_hide(struct screen_ctx *, struct group_ctx *); static void group_show(struct screen_ctx *, struct group_ctx *); static void group_restack(struct screen_ctx *, struct group_ctx *); -static void group_set_hidden_state(struct group_ctx *); +static int group_hidden_state(struct group_ctx *); static void group_setactive(struct screen_ctx *, long); static void group_set_names(struct screen_ctx *); @@ -68,8 +68,6 @@ group_hide(struct screen_ctx *sc, struct group_ctx *gc) TAILQ_FOREACH(cc, &gc->clients, group_entry) client_hide(cc); - - gc->hidden = 1; } static void @@ -80,8 +78,6 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) TAILQ_FOREACH(cc, &gc->clients, group_entry) client_unhide(cc); - gc->hidden = 0; - group_restack(sc, gc); group_setactive(sc, gc->num); } @@ -136,7 +132,6 @@ group_init(struct screen_ctx *sc) for (i = 0; i < CALMWM_NGROUPS; i++) { TAILQ_INIT(&sc->groups[i].clients); - sc->groups[i].hidden = 0; sc->groups[i].num = i; TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry); } @@ -149,15 +144,6 @@ group_init(struct screen_ctx *sc) group_setactive(sc, 1); } -void -group_set_state(struct screen_ctx *sc) -{ - struct group_ctx *gc; - - TAILQ_FOREACH(gc, &sc->groupq, entry) - group_set_hidden_state(gc); -} - static void group_setactive(struct screen_ctx *sc, long idx) { @@ -176,9 +162,10 @@ group_movetogroup(struct client_ctx *cc, int idx) errx(1, "group_movetogroup: index out of range (%d)", idx); gc = &sc->groups[idx]; + if (cc->group == gc) return; - if (gc->hidden) + if (group_hidden_state(gc)) client_hide(cc); group_assign(gc, cc); } @@ -211,21 +198,23 @@ group_sticky_toggle_exit(struct client_ctx *cc) } /* - * If all clients in a group are hidden, then set the group state as hidden. + * If all clients in a group are hidden, then the group state is hidden. */ -static void -group_set_hidden_state(struct group_ctx *gc) +static int +group_hidden_state(struct group_ctx *gc) { struct client_ctx *cc; - int same = 0; + int hidden = 0, same = 0; TAILQ_FOREACH(cc, &gc->clients, group_entry) { - if (gc->hidden == ((cc->flags & CLIENT_HIDDEN) ? 1 : 0)) + if (hidden == ((cc->flags & CLIENT_HIDDEN) ? 1 : 0)) same++; } if (same == 0) - gc->hidden = !gc->hidden; + hidden = !hidden; + + return(hidden); } void @@ -237,9 +226,8 @@ group_hidetoggle(struct screen_ctx *sc, int idx) errx(1, "group_hidetoggle: index out of range (%d)", idx); gc = &sc->groups[idx]; - group_set_hidden_state(gc); - if (gc->hidden) + if (group_hidden_state(gc)) group_show(sc, gc); else { group_hide(sc, gc); @@ -287,7 +275,7 @@ group_cycle(struct screen_ctx *sc, int flags) if (!TAILQ_EMPTY(&gc->clients) && showgroup == NULL) showgroup = gc; - else if (!gc->hidden) + else if (!group_hidden_state(gc)) group_hide(sc, gc); } @@ -296,7 +284,7 @@ group_cycle(struct screen_ctx *sc, int flags) group_hide(sc, sc->group_active); - if (showgroup->hidden) + if (group_hidden_state(showgroup)) group_show(sc, showgroup); else group_setactive(sc, showgroup->num); @@ -314,8 +302,8 @@ group_menu(struct screen_ctx *sc) TAILQ_FOREACH(gc, &sc->groupq, entry) { if (TAILQ_EMPTY(&gc->clients)) continue; - - menuq_add(&menuq, gc, gc->hidden ? "%d: [%s]" : "%d: %s", + menuq_add(&menuq, gc, + group_hidden_state(gc) ? "%d: [%s]" : "%d: %s", gc->num, sc->group_names[gc->num]); } @@ -325,7 +313,8 @@ group_menu(struct screen_ctx *sc) mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL); if (mi != NULL && mi->ctx != NULL) { gc = (struct group_ctx *)mi->ctx; - (gc->hidden) ? group_show(sc, gc) : group_hide(sc, gc); + (group_hidden_state(gc)) ? + group_show(sc, gc) : group_hide(sc, gc); } menuq_clear(&menuq); diff --git a/screen.c b/screen.c index 0621065..2335d63 100644 --- a/screen.c +++ b/screen.c @@ -69,7 +69,6 @@ screen_init(int which) XFree(wins); } screen_updatestackingorder(sc); - group_set_state(sc); if (HasRandr) XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask); -- cgit 1.4.1 From ed164794cb3d375b24809f1f042124109ee1fbea Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 24 Aug 2014 15:49:58 +0000 Subject: Continue effort to bring keyboard and mouse functions together; merge name_to_kbfunc and name_to_mousefunc. --- conf.c | 50 ++++++++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/conf.c b/conf.c index c6eb24f..2ad6727 100644 --- a/conf.c +++ b/conf.c @@ -344,7 +344,7 @@ static const struct { void (*handler)(struct client_ctx *, union arg *); int flags; union arg argument; -} name_to_kbfunc[] = { +} name_to_func[] = { { "lower", kbfunc_client_lower, CWM_WIN, {0} }, { "raise", kbfunc_client_raise, CWM_WIN, {0} }, { "search", kbfunc_client_search, 0, {0} }, @@ -451,6 +451,15 @@ static const struct { {.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} }, { "htile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_HORIZ} }, { "vtile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_VERT} }, + { "window_lower", kbfunc_client_lower, CWM_WIN, {0} }, + { "window_raise", kbfunc_client_raise, CWM_WIN, {0} }, + { "window_hide", kbfunc_client_hide, CWM_WIN, {0} }, + { "window_move", mousefunc_client_move, CWM_WIN, {0} }, + { "window_resize", mousefunc_client_resize, CWM_WIN, {0} }, + { "window_grouptoggle", mousefunc_client_grouptoggle, CWM_WIN, {0} }, + { "menu_group", mousefunc_menu_group, 0, {0} }, + { "menu_unhide", mousefunc_menu_unhide, 0, {0} }, + { "menu_cmd", mousefunc_menu_cmd, 0, {0} }, }; static const struct { @@ -508,13 +517,13 @@ conf_bind_kbd(struct conf *c, const char *bind, const char *cmd) return (1); } - for (i = 0; i < nitems(name_to_kbfunc); i++) { - if (strcmp(name_to_kbfunc[i].tag, cmd) != 0) + for (i = 0; i < nitems(name_to_func); i++) { + if (strcmp(name_to_func[i].tag, cmd) != 0) continue; - kb->callback = name_to_kbfunc[i].handler; - kb->flags = name_to_kbfunc[i].flags; - kb->argument = name_to_kbfunc[i].argument; + kb->callback = name_to_func[i].handler; + kb->flags = name_to_func[i].flags; + kb->argument = name_to_func[i].argument; kb->argtype |= ARG_INT; TAILQ_INSERT_TAIL(&c->keybindingq, kb, entry); return (1); @@ -546,25 +555,6 @@ conf_unbind_kbd(struct conf *c, struct binding *unbind) } } -static const struct { - const char *tag; - void (*handler)(struct client_ctx *, union arg *); - int flags; - union arg argument; -} name_to_mousefunc[] = { - { "window_lower", kbfunc_client_lower, CWM_WIN, {0} }, - { "window_raise", kbfunc_client_raise, CWM_WIN, {0} }, - { "window_hide", kbfunc_client_hide, CWM_WIN, {0} }, - { "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} }, - { "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} }, - { "window_move", mousefunc_client_move, CWM_WIN, {0} }, - { "window_resize", mousefunc_client_resize, CWM_WIN, {0} }, - { "window_grouptoggle", mousefunc_client_grouptoggle, CWM_WIN, {0} }, - { "menu_group", mousefunc_menu_group, 0, {0} }, - { "menu_unhide", mousefunc_menu_unhide, 0, {0} }, - { "menu_cmd", mousefunc_menu_cmd, 0, {0} }, -}; - int conf_bind_mouse(struct conf *c, const char *bind, const char *cmd) { @@ -591,13 +581,13 @@ conf_bind_mouse(struct conf *c, const char *bind, const char *cmd) return (1); } - for (i = 0; i < nitems(name_to_mousefunc); i++) { - if (strcmp(name_to_mousefunc[i].tag, cmd) != 0) + for (i = 0; i < nitems(name_to_func); i++) { + if (strcmp(name_to_func[i].tag, cmd) != 0) continue; - mb->callback = name_to_mousefunc[i].handler; - mb->flags = name_to_mousefunc[i].flags; - mb->argument = name_to_mousefunc[i].argument; + mb->callback = name_to_func[i].handler; + mb->flags = name_to_func[i].flags; + mb->argument = name_to_func[i].argument; TAILQ_INSERT_TAIL(&c->mousebindingq, mb, entry); return (1); } -- cgit 1.4.1 From 7314a3aefd33e901cfa1bd4a48eb4e75be4c01e2 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 25 Aug 2014 12:49:19 +0000 Subject: Implement _NET_WM_STATE_STICKY, bound to CM-s by default; allows any client to 'stick' to all desktops (ewmh speak) or groups - this currently has the same affect as setting a client's group to 'nogroup', with the exception that the client can also be in a group, so when un-sticking, the client will go back to its original group/desktop. --- calmwm.h | 6 +++++- client.c | 17 +++++++++++++++++ conf.c | 3 +++ cwm.1 | 4 +++- cwmrc.5 | 4 +++- group.c | 2 ++ kbfunc.c | 6 ++++++ xutil.c | 8 ++++++++ 8 files changed, 47 insertions(+), 3 deletions(-) diff --git a/calmwm.h b/calmwm.h index 2f55d44..0cd1685 100644 --- a/calmwm.h +++ b/calmwm.h @@ -180,6 +180,7 @@ struct client_ctx { #define CLIENT_WM_TAKE_FOCUS 0x0200 #define CLIENT_URGENCY 0x0400 #define CLIENT_FULLSCREEN 0x0800 +#define CLIENT_STICKY 0x1000 #define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP) #define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) @@ -349,7 +350,8 @@ enum { _NET_WM_DESKTOP, _NET_CLOSE_WINDOW, _NET_WM_STATE, -#define _NET_WM_STATES_NITEMS 4 +#define _NET_WM_STATES_NITEMS 5 + _NET_WM_STATE_STICKY, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_FULLSCREEN, @@ -396,6 +398,7 @@ void client_set_wm_state(struct client_ctx *, long); void client_setactive(struct client_ctx *); void client_setname(struct client_ctx *); int client_snapcalc(int, int, int, int, int); +void client_sticky(struct client_ctx *); void client_transient(struct client_ctx *); void client_unhide(struct client_ctx *); void client_urgency(struct client_ctx *); @@ -464,6 +467,7 @@ void kbfunc_client_nogroup(struct client_ctx *, void kbfunc_client_raise(struct client_ctx *, union arg *); void kbfunc_client_rcycle(struct client_ctx *, union arg *); void kbfunc_client_search(struct client_ctx *, union arg *); +void kbfunc_client_sticky(struct client_ctx *, union arg *); void kbfunc_client_vmaximize(struct client_ctx *, union arg *); void kbfunc_cmdexec(struct client_ctx *, union arg *); diff --git a/client.c b/client.c index bacfb51..d8e7fc4 100644 --- a/client.c +++ b/client.c @@ -238,6 +238,17 @@ client_freeze(struct client_ctx *cc) cc->flags |= CLIENT_FREEZE; } +void +client_sticky(struct client_ctx *cc) +{ + if (cc->flags & CLIENT_STICKY) + cc->flags &= ~CLIENT_STICKY; + else + cc->flags |= CLIENT_STICKY; + + xu_ewmh_set_net_wm_state(cc); +} + void client_fullscreen(struct client_ctx *cc) { @@ -468,6 +479,9 @@ 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->active = 0; @@ -481,6 +495,9 @@ 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/conf.c b/conf.c index 2ad6727..fcae046 100644 --- a/conf.c +++ b/conf.c @@ -204,6 +204,7 @@ static const struct { { "CM-g", "grouptoggle" }, { "CM-f", "fullscreen" }, { "CM-m", "maximize" }, + { "CM-s", "sticky" }, { "CM-equal", "vmaximize" }, { "CMS-equal", "hmaximize" }, { "CMS-f", "freeze" }, @@ -389,6 +390,7 @@ static const struct { { "rcycleingroup", kbfunc_client_cycle, CWM_WIN, {.i = CWM_RCYCLE|CWM_INGROUP} }, { "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {0}}, + { "sticky", kbfunc_client_sticky, CWM_WIN, {0} }, { "fullscreen", kbfunc_client_fullscreen, CWM_WIN, {0} }, { "maximize", kbfunc_client_maximize, CWM_WIN, {0} }, { "vmaximize", kbfunc_client_vmaximize, CWM_WIN, {0} }, @@ -678,6 +680,7 @@ static char *ewmhints[] = { "_NET_WM_DESKTOP", "_NET_CLOSE_WINDOW", "_NET_WM_STATE", + "_NET_WM_STATE_STICKY", "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ", "_NET_WM_STATE_FULLSCREEN", diff --git a/cwm.1 b/cwm.1 index b3a5c3d..eb6c9e7 100644 --- a/cwm.1 +++ b/cwm.1 @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 16 2013 $ +.Dd $Mdocdate$ .Dt CWM 1 .Os .Sh NAME @@ -90,6 +90,8 @@ Cycle through active groups. Reverse cycle through active groups. .It Ic CMS-f Toggle freezing geometry of current window. +.It Ic CM-s +Toggle stickiness of current window. .It Ic CM-f Toggle full-screen mode of current window. .It Ic CM-m diff --git a/cwmrc.5 b/cwmrc.5 index bc6e9c2..a0b39d3 100644 --- a/cwmrc.5 +++ b/cwmrc.5 @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 16 2013 $ +.Dd $Mdocdate$ .Dt CWMRC 5 .Os .Sh NAME @@ -341,6 +341,8 @@ Raise current window. Label current window. .It freeze Freeze current window geometry. +.It sticky +Stick current window to all groups (same as assigning to nogroup). .It fullscreen Full-screen current window (gap + border removed). .It maximize diff --git a/group.c b/group.c index 1290621..3657fad 100644 --- a/group.c +++ b/group.c @@ -207,6 +207,8 @@ group_hidden_state(struct group_ctx *gc) int hidden = 0, same = 0; TAILQ_FOREACH(cc, &gc->clients, group_entry) { + if (cc->flags & CLIENT_STICKY) + continue; if (hidden == ((cc->flags & CLIENT_HIDDEN) ? 1 : 0)) same++; } diff --git a/kbfunc.c b/kbfunc.c index 813f8e6..241c0b4 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -432,6 +432,12 @@ kbfunc_client_movetogroup(struct client_ctx *cc, union arg *arg) group_movetogroup(cc, arg->i); } +void +kbfunc_client_sticky(struct client_ctx *cc, union arg *arg) +{ + client_sticky(cc); +} + void kbfunc_client_fullscreen(struct client_ctx *cc, union arg *arg) { diff --git a/xutil.c b/xutil.c index 847b148..b61b0ee 100644 --- a/xutil.c +++ b/xutil.c @@ -326,6 +326,9 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action, int property; void (*toggle)(struct client_ctx *); } handlers[] = { + { _NET_WM_STATE_STICKY, + CLIENT_STICKY, + client_sticky }, { _NET_WM_STATE_MAXIMIZED_VERT, CLIENT_VMAXIMIZED, client_vmaximize }, @@ -367,6 +370,8 @@ xu_ewmh_restore_net_wm_state(struct client_ctx *cc) atoms = xu_ewmh_get_net_wm_state(cc, &n); for (i = 0; i < n; i++) { + if (atoms[i] == ewmh[_NET_WM_STATE_STICKY]) + client_sticky(cc); if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ]) client_hmaximize(cc); if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT]) @@ -391,10 +396,13 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc) if (oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_HORZ] && oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_VERT] && oatoms[i] != ewmh[_NET_WM_STATE_FULLSCREEN] && + oatoms[i] != ewmh[_NET_WM_STATE_STICKY] && oatoms[i] != ewmh[_NET_WM_STATE_DEMANDS_ATTENTION]) atoms[j++] = oatoms[i]; } free(oatoms); + if (cc->flags & CLIENT_STICKY) + atoms[j++] = ewmh[_NET_WM_STATE_STICKY]; if (cc->flags & CLIENT_FULLSCREEN) atoms[j++] = ewmh[_NET_WM_STATE_FULLSCREEN]; else { -- cgit 1.4.1 From 3b99d5357667095b3b89e2c41c2cb17d07537b42 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 25 Aug 2014 14:31:22 +0000 Subject: Since the flatting out of sc->group_names is only for setting NET_DESKTOP_NAMES, merge the helper into xu_ewmh_net_desktop_names, where we actually set the property. --- calmwm.h | 3 +-- group.c | 26 ++------------------------ xutil.c | 20 ++++++++++++++++++-- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/calmwm.h b/calmwm.h index 0cd1685..203f882 100644 --- a/calmwm.h +++ b/calmwm.h @@ -545,8 +545,7 @@ void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *); void xu_ewmh_net_showing_desktop(struct screen_ctx *); void xu_ewmh_net_virtual_roots(struct screen_ctx *); void xu_ewmh_net_current_desktop(struct screen_ctx *, long); -void xu_ewmh_net_desktop_names(struct screen_ctx *, char *, - int); +void xu_ewmh_net_desktop_names(struct screen_ctx *); void xu_ewmh_net_wm_desktop(struct client_ctx *); Atom *xu_ewmh_get_net_wm_state(struct client_ctx *, int *); diff --git a/group.c b/group.c index 3657fad..e4567ee 100644 --- a/group.c +++ b/group.c @@ -38,7 +38,6 @@ static void group_show(struct screen_ctx *, struct group_ctx *); static void group_restack(struct screen_ctx *, struct group_ctx *); static int group_hidden_state(struct group_ctx *); static void group_setactive(struct screen_ctx *, long); -static void group_set_names(struct screen_ctx *); const char *num_to_name[] = { "nogroup", "one", "two", "three", "four", "five", "six", @@ -427,28 +426,7 @@ group_update_names(struct screen_ctx *sc) sc->group_names = strings; sc->group_nonames = n; - if (setnames) - group_set_names(sc); -} -static void -group_set_names(struct screen_ctx *sc) -{ - char *p, *q; - size_t len = 0, tlen, slen; - int i; - - for (i = 0; i < sc->group_nonames; i++) - len += strlen(sc->group_names[i]) + 1; - q = p = xcalloc(len, sizeof(*p)); - - tlen = len; - for (i = 0; i < sc->group_nonames; i++) { - slen = strlen(sc->group_names[i]) + 1; - (void)strlcpy(q, sc->group_names[i], tlen); - tlen -= slen; - q += slen; - } - - xu_ewmh_net_desktop_names(sc, p, len); + if (setnames) + xu_ewmh_net_desktop_names(sc); } diff --git a/xutil.c b/xutil.c index b61b0ee..cafd793 100644 --- a/xutil.c +++ b/xutil.c @@ -281,10 +281,26 @@ xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx) } void -xu_ewmh_net_desktop_names(struct screen_ctx *sc, char *data, int n) +xu_ewmh_net_desktop_names(struct screen_ctx *sc) { + char *p, *q; + size_t len = 0, tlen, slen; + int i; + + for (i = 0; i < sc->group_nonames; i++) + len += strlen(sc->group_names[i]) + 1; + q = p = xcalloc(len, sizeof(*p)); + + tlen = len; + for (i = 0; i < sc->group_nonames; i++) { + slen = strlen(sc->group_names[i]) + 1; + (void)strlcpy(q, sc->group_names[i], tlen); + tlen -= slen; + q += slen; + } + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES], - cwmh[UTF8_STRING], 8, PropModeReplace, (unsigned char *)data, n); + cwmh[UTF8_STRING], 8, PropModeReplace, (unsigned char *)p, len); } /* Application Window Properties */ -- cgit 1.4.1 From becc7f260c1230def154a98b8f80829d466aa18c Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 1 Sep 2014 18:04:58 +0000 Subject: Merge group_menu into mousefunc_menu_group. --- calmwm.h | 4 +++- group.c | 39 +++------------------------------------ mousefunc.c | 26 +++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/calmwm.h b/calmwm.h index 203f882..5099f9e 100644 --- a/calmwm.h +++ b/calmwm.h @@ -410,11 +410,13 @@ void client_wm_hints(struct client_ctx *); void group_alltoggle(struct screen_ctx *); void group_autogroup(struct client_ctx *); void group_cycle(struct screen_ctx *, int); +int group_hidden_state(struct group_ctx *); +void group_hide(struct screen_ctx *, struct group_ctx *); void group_hidetoggle(struct screen_ctx *, int); void group_init(struct screen_ctx *); -void group_menu(struct screen_ctx *); void group_movetogroup(struct client_ctx *, int); void group_only(struct screen_ctx *, int); +void group_show(struct screen_ctx *, struct group_ctx *); void group_sticky(struct client_ctx *); void group_sticky_toggle_enter(struct client_ctx *); void group_sticky_toggle_exit(struct client_ctx *); diff --git a/group.c b/group.c index e4567ee..7d08f34 100644 --- a/group.c +++ b/group.c @@ -33,10 +33,7 @@ #include "calmwm.h" static void group_assign(struct group_ctx *, struct client_ctx *); -static void group_hide(struct screen_ctx *, struct group_ctx *); -static void group_show(struct screen_ctx *, struct group_ctx *); static void group_restack(struct screen_ctx *, struct group_ctx *); -static int group_hidden_state(struct group_ctx *); static void group_setactive(struct screen_ctx *, long); const char *num_to_name[] = { @@ -58,7 +55,7 @@ group_assign(struct group_ctx *gc, struct client_ctx *cc) xu_ewmh_net_wm_desktop(cc); } -static void +void group_hide(struct screen_ctx *sc, struct group_ctx *gc) { struct client_ctx *cc; @@ -69,7 +66,7 @@ group_hide(struct screen_ctx *sc, struct group_ctx *gc) client_hide(cc); } -static void +void group_show(struct screen_ctx *sc, struct group_ctx *gc) { struct client_ctx *cc; @@ -199,7 +196,7 @@ group_sticky_toggle_exit(struct client_ctx *cc) /* * If all clients in a group are hidden, then the group state is hidden. */ -static int +int group_hidden_state(struct group_ctx *gc) { struct client_ctx *cc; @@ -291,36 +288,6 @@ group_cycle(struct screen_ctx *sc, int flags) group_setactive(sc, showgroup->num); } -void -group_menu(struct screen_ctx *sc) -{ - struct group_ctx *gc; - struct menu *mi; - struct menu_q menuq; - - TAILQ_INIT(&menuq); - - TAILQ_FOREACH(gc, &sc->groupq, entry) { - if (TAILQ_EMPTY(&gc->clients)) - continue; - menuq_add(&menuq, gc, - group_hidden_state(gc) ? "%d: [%s]" : "%d: %s", - gc->num, sc->group_names[gc->num]); - } - - if (TAILQ_EMPTY(&menuq)) - return; - - mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL); - if (mi != NULL && mi->ctx != NULL) { - gc = (struct group_ctx *)mi->ctx; - (group_hidden_state(gc)) ? - group_show(sc, gc) : group_hide(sc, gc); - } - - menuq_clear(&menuq); -} - void group_alltoggle(struct screen_ctx *sc) { diff --git a/mousefunc.c b/mousefunc.c index 295d3a1..ef96cb3 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -181,7 +181,31 @@ mousefunc_client_grouptoggle(struct client_ctx *cc, union arg *arg) void mousefunc_menu_group(struct client_ctx *cc, union arg *arg) { - group_menu(cc->sc); + struct screen_ctx *sc = cc->sc; + struct group_ctx *gc; + struct menu *mi; + struct menu_q menuq; + + TAILQ_INIT(&menuq); + TAILQ_FOREACH(gc, &sc->groupq, entry) { + if (TAILQ_EMPTY(&gc->clients)) + continue; + menuq_add(&menuq, gc, + group_hidden_state(gc) ? "%d: [%s]" : "%d: %s", + gc->num, sc->group_names[gc->num]); + } + + if (TAILQ_EMPTY(&menuq)) + return; + + mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL); + if (mi != NULL && mi->ctx != NULL) { + gc = (struct group_ctx *)mi->ctx; + (group_hidden_state(gc)) ? + group_show(sc, gc) : group_hide(sc, gc); + } + + menuq_clear(&menuq); } void -- cgit 1.4.1 From 231abb818ae3bdb8ea01a7df99d0895f38327748 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 1 Sep 2014 18:17:32 +0000 Subject: add explicit paran and drop some empty lines bringing like functions closer --- kbfunc.c | 1 - mousefunc.c | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/kbfunc.c b/kbfunc.c index 241c0b4..4cc0dc1 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -159,7 +159,6 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg) cc = (struct client_ctx *)mi->ctx; if (cc->flags & CLIENT_HIDDEN) client_unhide(cc); - if (old_cc) client_ptrsave(old_cc); client_ptrwarp(cc); diff --git a/mousefunc.c b/mousefunc.c index ef96cb3..2537059 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -194,7 +194,6 @@ mousefunc_menu_group(struct client_ctx *cc, union arg *arg) group_hidden_state(gc) ? "%d: [%s]" : "%d: %s", gc->num, sc->group_names[gc->num]); } - if (TAILQ_EMPTY(&menuq)) return; @@ -220,16 +219,15 @@ mousefunc_menu_unhide(struct client_ctx *cc, union arg *arg) old_cc = client_current(); TAILQ_INIT(&menuq); - TAILQ_FOREACH(cc, &Clientq, entry) + TAILQ_FOREACH(cc, &Clientq, entry) { if (cc->flags & CLIENT_HIDDEN) { wname = (cc->label) ? cc->label : cc->name; if (wname == NULL) continue; - menuq_add(&menuq, cc, "(%d) %s", cc->group ? cc->group->num : 0, wname); } - + } if (TAILQ_EMPTY(&menuq)) return; @@ -257,7 +255,6 @@ mousefunc_menu_cmd(struct client_ctx *cc, union arg *arg) TAILQ_INIT(&menuq); TAILQ_FOREACH(cmd, &Conf.cmdq, entry) menuq_add(&menuq, cmd, "%s", cmd->name); - if (TAILQ_EMPTY(&menuq)) return; -- cgit 1.4.1 From 87d604f119e3598ca2b0311082c89ebb67782f76 Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 2 Sep 2014 14:08:39 +0000 Subject: bring menu bits closer together --- mousefunc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mousefunc.c b/mousefunc.c index 2537059..c7b283a 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -197,8 +197,8 @@ mousefunc_menu_group(struct client_ctx *cc, union arg *arg) if (TAILQ_EMPTY(&menuq)) return; - mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL); - if (mi != NULL && mi->ctx != NULL) { + if ((mi = menu_filter(sc, &menuq, NULL, NULL, 0, + NULL, NULL)) != NULL) { gc = (struct group_ctx *)mi->ctx; (group_hidden_state(gc)) ? group_show(sc, gc) : group_hide(sc, gc); @@ -235,7 +235,6 @@ mousefunc_menu_unhide(struct client_ctx *cc, union arg *arg) NULL, NULL)) != NULL) { cc = (struct client_ctx *)mi->ctx; client_unhide(cc); - if (old_cc != NULL) client_ptrsave(old_cc); client_ptrwarp(cc); -- cgit 1.4.1 From 142f52a0aab29681a46e4ce10eb2618ee99ede95 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 6 Sep 2014 16:08:58 +0000 Subject: Rework group names: stash the group name inside the group_ctx as opposed to having to manage an array outside in screen_ctx for group names and shortcuts. Simplifies (and moves bits for) reading, and constructing data for, EWMH's _NET_DESKTOP_NAMES. --- calmwm.h | 3 +-- group.c | 54 ++---------------------------------------------------- mousefunc.c | 2 +- xevents.c | 2 +- xutil.c | 44 ++++++++++++++++++++++++++++++++++++-------- 5 files changed, 41 insertions(+), 64 deletions(-) diff --git a/calmwm.h b/calmwm.h index 5099f9e..9764a21 100644 --- a/calmwm.h +++ b/calmwm.h @@ -204,6 +204,7 @@ TAILQ_HEAD(cycle_entry_q, client_ctx); struct group_ctx { TAILQ_ENTRY(group_ctx) entry; struct client_ctx_q clients; + char *name; int num; }; TAILQ_HEAD(group_ctx_q, group_ctx); @@ -242,9 +243,7 @@ struct screen_ctx { struct group_ctx groups[CALMWM_NGROUPS]; struct group_ctx_q groupq; int group_hideall; - int group_nonames; struct group_ctx *group_active; - char **group_names; }; TAILQ_HEAD(screen_ctx_q, screen_ctx); diff --git a/group.c b/group.c index 7d08f34..d1ae4f4 100644 --- a/group.c +++ b/group.c @@ -120,18 +120,15 @@ group_init(struct screen_ctx *sc) TAILQ_INIT(&sc->groupq); sc->group_hideall = 0; - /* - * See if any group names have already been set and update the - * property with ours if they'll have changed. - */ - group_update_names(sc); for (i = 0; i < CALMWM_NGROUPS; i++) { TAILQ_INIT(&sc->groups[i].clients); + sc->groups[i].name = xstrdup(num_to_name[i]); sc->groups[i].num = i; TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry); } + xu_ewmh_net_desktop_names(sc); xu_ewmh_net_wm_desktop_viewport(sc); xu_ewmh_net_wm_number_of_desktops(sc); xu_ewmh_net_showing_desktop(sc); @@ -350,50 +347,3 @@ group_autogroup(struct client_ctx *cc) else group_assign(NULL, cc); } - -void -group_update_names(struct screen_ctx *sc) -{ - char **strings, *p; - unsigned char *prop_ret; - int i = 0, j = 0, nstrings = 0, n = 0, setnames = 0; - - if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES], - cwmh[UTF8_STRING], 0xffffff, (unsigned char **)&prop_ret)) > 0) { - prop_ret[j - 1] = '\0'; /* paranoia */ - while (i < j) { - if (prop_ret[i++] == '\0') - nstrings++; - } - } - - strings = xcalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS : - nstrings), sizeof(*strings)); - - p = (char *)prop_ret; - while (n < nstrings) { - strings[n++] = xstrdup(p); - p += strlen(p) + 1; - } - /* - * make sure we always set our defaults if nothing is there to - * replace them. - */ - if (n < CALMWM_NGROUPS) { - setnames = 1; - i = 0; - while (n < CALMWM_NGROUPS) - strings[n++] = xstrdup(num_to_name[i++]); - } - - if (prop_ret != NULL) - XFree(prop_ret); - if (sc->group_nonames != 0) - free(sc->group_names); - - sc->group_names = strings; - sc->group_nonames = n; - - if (setnames) - xu_ewmh_net_desktop_names(sc); -} diff --git a/mousefunc.c b/mousefunc.c index c7b283a..2499ae1 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -192,7 +192,7 @@ mousefunc_menu_group(struct client_ctx *cc, union arg *arg) continue; menuq_add(&menuq, gc, group_hidden_state(gc) ? "%d: [%s]" : "%d: %s", - gc->num, sc->group_names[gc->num]); + gc->num, gc->name); } if (TAILQ_EMPTY(&menuq)) return; diff --git a/xevents.c b/xevents.c index cbba674..c4facf3 100644 --- a/xevents.c +++ b/xevents.c @@ -196,7 +196,7 @@ xev_handle_propertynotify(XEvent *ee) TAILQ_FOREACH(sc, &Screenq, entry) { if (sc->rootwin == e->window) { if (e->atom == ewmh[_NET_DESKTOP_NAMES]) - group_update_names(sc); + xu_ewmh_net_desktop_names(sc); } } } diff --git a/xutil.c b/xutil.c index cafd793..8c02456 100644 --- a/xutil.c +++ b/xutil.c @@ -283,18 +283,46 @@ xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx) void xu_ewmh_net_desktop_names(struct screen_ctx *sc) { - char *p, *q; - size_t len = 0, tlen, slen; - int i; + struct group_ctx *gc; + char *p, *q; + unsigned char *prop_ret; + int i = 0, j = 0, nstrings = 0, n = 0; + size_t len = 0, tlen, slen; + + /* Let group names be overwritten if _NET_DESKTOP_NAMES is set. */ + + if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES], + cwmh[UTF8_STRING], 0xffffff, (unsigned char **)&prop_ret)) > 0) { + prop_ret[j - 1] = '\0'; /* paranoia */ + while (i < j) { + if (prop_ret[i++] == '\0') + nstrings++; + } + } + + p = (char *)prop_ret; + while (n < nstrings) { + TAILQ_FOREACH(gc, &sc->groupq, entry) { + if (gc->num == n) { + free(gc->name); + gc->name = xstrdup(p); + p += strlen(p) + 1; + break; + } + } + n++; + } + if (prop_ret != NULL) + XFree(prop_ret); - for (i = 0; i < sc->group_nonames; i++) - len += strlen(sc->group_names[i]) + 1; + TAILQ_FOREACH(gc, &sc->groupq, entry) + len += strlen(gc->name) + 1; q = p = xcalloc(len, sizeof(*p)); tlen = len; - for (i = 0; i < sc->group_nonames; i++) { - slen = strlen(sc->group_names[i]) + 1; - (void)strlcpy(q, sc->group_names[i], tlen); + TAILQ_FOREACH(gc, &sc->groupq, entry) { + slen = strlen(gc->name) + 1; + (void)strlcpy(q, gc->name, tlen); tlen -= slen; q += slen; } -- cgit 1.4.1 From 5cd4cce3a02203aaf1e85ffbe7155a782161ff5c Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 6 Sep 2014 16:14:35 +0000 Subject: Move termpath and lockpath into cmdq; side effect is that 'lock' and 'term' now show up in the application menu. --- calmwm.h | 2 -- conf.c | 30 +++++++++++------------------- kbfunc.c | 19 ++++++++++++++++--- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/calmwm.h b/calmwm.h index 9764a21..bdb60a7 100644 --- a/calmwm.h +++ b/calmwm.h @@ -294,8 +294,6 @@ struct conf { int snapdist; struct gap gap; char *color[CWM_COLOR_NITEMS]; - char termpath[MAXPATHLEN]; - char lockpath[MAXPATHLEN]; char known_hosts[MAXPATHLEN]; #define CONF_FONT "sans-serif:pixelsize=14:bold" char *font; diff --git a/conf.c b/conf.c index fcae046..bc2a4ed 100644 --- a/conf.c +++ b/conf.c @@ -41,27 +41,19 @@ conf_cmd_add(struct conf *c, const char *name, const char *path) { struct cmd *cmd; - /* "term" and "lock" have special meanings. */ - if (strcmp(name, "term") == 0) { - if (strlcpy(c->termpath, path, sizeof(c->termpath)) >= - sizeof(c->termpath)) - return (0); - } else if (strcmp(name, "lock") == 0) { - if (strlcpy(c->lockpath, path, sizeof(c->lockpath)) >= - sizeof(c->lockpath)) - return (0); - } else { - conf_cmd_remove(c, name); - - cmd = xmalloc(sizeof(*cmd)); + cmd = xmalloc(sizeof(*cmd)); - cmd->name = xstrdup(name); - if (strlcpy(cmd->path, path, sizeof(cmd->path)) >= - sizeof(cmd->path)) - return (0); - TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry); + cmd->name = xstrdup(name); + if (strlcpy(cmd->path, path, sizeof(cmd->path)) >= sizeof(cmd->path)) { + free(cmd->name); + free(cmd); + return(0); } - return (1); + + conf_cmd_remove(c, name); + + TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry); + return(1); } static void diff --git a/kbfunc.c b/kbfunc.c index 4cc0dc1..dff75dc 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -213,13 +213,21 @@ kbfunc_cmdexec(struct client_ctx *cc, union arg *arg) void kbfunc_term(struct client_ctx *cc, union arg *arg) { - u_spawn(Conf.termpath); + struct cmd *cmd; + + TAILQ_FOREACH(cmd, &Conf.cmdq, entry) + if (strcmp(cmd->name, "term") == 0) + u_spawn(cmd->path); } void kbfunc_lock(struct client_ctx *cc, union arg *arg) { - u_spawn(Conf.lockpath); + struct cmd *cmd; + + TAILQ_FOREACH(cmd, &Conf.cmdq, entry) + if (strcmp(cmd->name, "lock") == 0) + u_spawn(cmd->path); } void @@ -309,6 +317,7 @@ void kbfunc_ssh(struct client_ctx *cc, union arg *arg) { struct screen_ctx *sc = cc->sc; + struct cmd *cmdq; struct menu *mi; struct menu_q menuq; FILE *fp; @@ -323,6 +332,10 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg) return; } + TAILQ_FOREACH(cmdq, &Conf.cmdq, entry) + if (strcmp(cmdq->name, "term") == 0) + break; + TAILQ_INIT(&menuq); lbuf = NULL; @@ -356,7 +369,7 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg) if (mi->text[0] == '\0') goto out; l = snprintf(cmd, sizeof(cmd), "%s -T '[ssh] %s' -e ssh %s", - Conf.termpath, mi->text, mi->text); + cmdq->path, mi->text, mi->text); if (l != -1 && l < sizeof(cmd)) u_spawn(cmd); } -- cgit 1.4.1 From 140f8b9eba06dfd416ae1503130da374867dd8d8 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 6 Sep 2014 16:18:08 +0000 Subject: style nit --- menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/menu.c b/menu.c index 5ed51d2..2b28c14 100644 --- a/menu.c +++ b/menu.c @@ -260,7 +260,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq, * even if dummy is zero, we need to return something. */ if ((mi = TAILQ_FIRST(resultq)) == NULL) { - mi = xmalloc(sizeof *mi); + mi = xmalloc(sizeof(*mi)); (void)strlcpy(mi->text, mc->searchstr, sizeof(mi->text)); mi->dummy = 1; @@ -302,7 +302,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq, mc->list = !mc->list; break; case CTL_ABORT: - mi = xmalloc(sizeof *mi); + mi = xmalloc(sizeof(*mi)); mi->text[0] = '\0'; mi->dummy = 1; mi->abort = 1; -- cgit 1.4.1 From 977992626a092487f4d5df364729693ad2be0131 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 6 Sep 2014 16:24:32 +0000 Subject: generic sighandler --- calmwm.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/calmwm.c b/calmwm.c index 3656b48..90844a5 100644 --- a/calmwm.c +++ b/calmwm.c @@ -48,7 +48,7 @@ struct conf Conf; const char *homedir; volatile sig_atomic_t cwm_status; -static void sigchld_cb(int); +static void sighdlr(int); static int x_errorhandler(Display *, XErrorEvent *); static void x_init(const char *); static void x_restart(char **); @@ -84,7 +84,7 @@ main(int argc, char **argv) argc -= optind; argv += optind; - if (signal(SIGCHLD, sigchld_cb) == SIG_ERR) + if (signal(SIGCHLD, sighdlr) == SIG_ERR) err(1, "signal"); if ((homedir = getenv("HOME")) == NULL || *homedir == '\0') { @@ -205,16 +205,19 @@ x_errorhandler(Display *dpy, XErrorEvent *e) } static void -sigchld_cb(int which) +sighdlr(int sig) { pid_t pid; - int save_errno = errno; - int status; - - /* Collect dead children. */ - while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || - (pid < 0 && errno == EINTR)) - ; + int save_errno = errno, status; + + switch (sig) { + case SIGCHLD: + /* Collect dead children. */ + while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0 || + (pid < 0 && errno == EINTR)) + ; + break; + } errno = save_errno; } -- cgit 1.4.1 From f7af0ebd7267cdfd4e7b9c12bb910992f1a094e5 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 6 Sep 2014 18:50:43 +0000 Subject: Few style nits; extend 'path' to MAXPATHLEN. --- kbfunc.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/kbfunc.c b/kbfunc.c index dff75dc..81133b2 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -215,9 +215,10 @@ kbfunc_term(struct client_ctx *cc, union arg *arg) { struct cmd *cmd; - TAILQ_FOREACH(cmd, &Conf.cmdq, entry) + TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { if (strcmp(cmd->name, "term") == 0) u_spawn(cmd->path); + } } void @@ -225,9 +226,10 @@ kbfunc_lock(struct client_ctx *cc, union arg *arg) { struct cmd *cmd; - TAILQ_FOREACH(cmd, &Conf.cmdq, entry) + TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { if (strcmp(cmd->name, "lock") == 0) u_spawn(cmd->path); + } } void @@ -317,13 +319,13 @@ void kbfunc_ssh(struct client_ctx *cc, union arg *arg) { struct screen_ctx *sc = cc->sc; - struct cmd *cmdq; + struct cmd *cmd; struct menu *mi; struct menu_q menuq; FILE *fp; char *buf, *lbuf, *p; char hostbuf[MAXHOSTNAMELEN]; - char cmd[256]; + char path[MAXPATHLEN]; int l; size_t len; @@ -332,9 +334,10 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg) return; } - TAILQ_FOREACH(cmdq, &Conf.cmdq, entry) - if (strcmp(cmdq->name, "term") == 0) + TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { + if (strcmp(cmd->name, "term") == 0) break; + } TAILQ_INIT(&menuq); @@ -368,10 +371,10 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg) search_match_exec, NULL)) != NULL) { if (mi->text[0] == '\0') goto out; - l = snprintf(cmd, sizeof(cmd), "%s -T '[ssh] %s' -e ssh %s", - cmdq->path, mi->text, mi->text); - if (l != -1 && l < sizeof(cmd)) - u_spawn(cmd); + l = snprintf(path, sizeof(path), "%s -T '[ssh] %s' -e ssh %s", + cmd->path, mi->text, mi->text); + if (l != -1 && l < sizeof(path)) + u_spawn(path); } out: if (mi != NULL && mi->dummy) -- cgit 1.4.1