From cd4be1c17a537cc398520140c547370d1061b841 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 25 Feb 2019 18:07:48 +0000 Subject: Add a configtest flag (-n). based on a diff from Sascha Paunovic. --- calmwm.c | 16 ++++++++++++---- cwm.1 | 5 ++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/calmwm.c b/calmwm.c index 875b0ca..510bd33 100644 --- a/calmwm.c +++ b/calmwm.c @@ -55,7 +55,7 @@ main(int argc, char **argv) { char *display_name = NULL; char *fallback; - int ch, xfd; + int ch, xfd, nflag = 0; struct pollfd pfd[1]; if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) @@ -66,7 +66,7 @@ main(int argc, char **argv) fallback = u_argv(argv); Conf.wm_argv = u_argv(argv); - while ((ch = getopt(argc, argv, "c:d:v")) != -1) { + while ((ch = getopt(argc, argv, "c:d:nv")) != -1) { switch (ch) { case 'c': free(Conf.conf_file); @@ -75,6 +75,9 @@ main(int argc, char **argv) case 'd': display_name = optarg; break; + case 'n': + nflag = 1; + break; case 'v': Conf.debug++; break; @@ -90,8 +93,13 @@ main(int argc, char **argv) if (signal(SIGHUP, sighdlr) == SIG_ERR) err(1, "signal"); - if (parse_config(Conf.conf_file, &Conf) == -1) + if (parse_config(Conf.conf_file, &Conf) == -1) { warnx("error parsing config file"); + if (nflag) + return 1; + } + if (nflag) + return 0; xfd = x_init(display_name); cwm_status = CWM_RUNNING; @@ -219,7 +227,7 @@ usage(void) { extern char *__progname; - (void)fprintf(stderr, "usage: %s [-v] [-c file] [-d display]\n", + (void)fprintf(stderr, "usage: %s [-nv] [-c file] [-d display]\n", __progname); exit(1); } diff --git a/cwm.1 b/cwm.1 index a603100..7a3f49f 100644 --- a/cwm.1 +++ b/cwm.1 @@ -23,7 +23,7 @@ .Sh SYNOPSIS .\" For a program: program [-abc] file ... .Nm cwm -.Op Fl v +.Op Fl nv .Op Fl c Ar file .Op Fl d Ar display .Sh DESCRIPTION @@ -48,6 +48,9 @@ however, will continue to process the rest of the configuration file. .It Fl d Ar display Specify the display to use. +.It Fl n +Configtest mode. +Only check the configuration file for validity. .It Fl v Verbose mode. Multiple -- cgit 1.4.1 From 8cd6d1154c6e5198403270a66fffb8a4f0c56cf6 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 28 Feb 2019 13:11:53 +0000 Subject: Selectively hide and show clients based on state; merge client_unhide() and client_show(). --- calmwm.h | 1 - client.c | 17 ++++------------- group.c | 8 +++++--- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/calmwm.h b/calmwm.h index 15dd247..cbd4a83 100644 --- a/calmwm.h +++ b/calmwm.h @@ -435,7 +435,6 @@ void client_toggle_skip_taskbar(struct client_ctx *); void client_toggle_sticky(struct client_ctx *); void client_toggle_vmaximize(struct client_ctx *); void client_transient(struct client_ctx *); -void client_unhide(struct client_ctx *); void client_urgency(struct client_ctx *); void client_vtile(struct client_ctx *); void client_wm_hints(struct client_ctx *); diff --git a/client.c b/client.c index 46c70c1..19c2ab4 100644 --- a/client.c +++ b/client.c @@ -128,7 +128,7 @@ client_init(Window win, struct screen_ctx *sc, int active) if (client_get_wm_state(cc) == IconicState) client_hide(cc); else - client_unhide(cc); + client_show(cc); if (mapped) { if (cc->gc) { @@ -527,25 +527,16 @@ client_hide(struct client_ctx *cc) { XUnmapWindow(X_Dpy, cc->win); - if (cc->flags & CLIENT_ACTIVE) + if (cc->flags & CLIENT_ACTIVE) { + cc->flags &= ~CLIENT_ACTIVE; xu_ewmh_net_active_window(cc->sc, None); - - cc->flags &= ~CLIENT_ACTIVE; + } cc->flags |= CLIENT_HIDDEN; client_set_wm_state(cc, IconicState); } void client_show(struct client_ctx *cc) -{ - if (cc->flags & CLIENT_HIDDEN) - client_unhide(cc); - else - client_raise(cc); -} - -void -client_unhide(struct client_ctx *cc) { XMapRaised(X_Dpy, cc->win); diff --git a/group.c b/group.c index 30fe718..666186b 100644 --- a/group.c +++ b/group.c @@ -67,7 +67,8 @@ group_hide(struct group_ctx *gc) screen_updatestackingorder(gc->sc); TAILQ_FOREACH(cc, &gc->clientq, group_entry) { - if (!(cc->flags & CLIENT_STICKY)) + if (!(cc->flags & CLIENT_STICKY) && + !(cc->flags & CLIENT_HIDDEN)) client_hide(cc); } } @@ -78,8 +79,9 @@ group_show(struct group_ctx *gc) struct client_ctx *cc; TAILQ_FOREACH(cc, &gc->clientq, group_entry) { - if (!(cc->flags & CLIENT_STICKY)) - client_unhide(cc); + if (!(cc->flags & CLIENT_STICKY) && + (cc->flags & CLIENT_HIDDEN)) + client_show(cc); } group_restack(gc); -- cgit 1.4.1 From 880b5cda3f36e0135632d6670717e9a964caf0ec Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 28 Feb 2019 23:20:52 +0000 Subject: Ensure we don't action on the last group when the requested one is not found. --- group.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/group.c b/group.c index 666186b..b6ca7d5 100644 --- a/group.c +++ b/group.c @@ -160,15 +160,14 @@ group_movetogroup(struct client_ctx *cc, int idx) return; TAILQ_FOREACH(gc, &sc->groupq, entry) { - if (gc->num == idx) - break; + if (gc->num == idx) { + if (cc->gc == gc) + return; + if (gc->num != 0 && group_holds_only_hidden(gc)) + client_hide(cc); + group_assign(gc, cc); + } } - - if (cc->gc == gc) - return; - if (gc->num != 0 && group_holds_only_hidden(gc)) - client_hide(cc); - group_assign(gc, cc); } void @@ -221,17 +220,16 @@ group_hidetoggle(struct screen_ctx *sc, int idx) return; TAILQ_FOREACH(gc, &sc->groupq, entry) { - if (gc->num == idx) - break; - } - - if (group_holds_only_hidden(gc)) - group_show(gc); - else { - group_hide(gc); - /* make clients stick to empty group */ - if (TAILQ_EMPTY(&gc->clientq)) - group_setactive(gc); + if (gc->num == idx) { + if (group_holds_only_hidden(gc)) + group_show(gc); + else { + group_hide(gc); + /* make clients stick to empty group */ + if (TAILQ_EMPTY(&gc->clientq)) + group_setactive(gc); + } + } } } -- cgit 1.4.1 From ae231f67d0ac54fb6281831c10972cc2f1f37acf Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 28 Feb 2019 23:26:12 +0000 Subject: Move the group index (desktop number) check to the only 2 callers that require checking due to ewmh. --- group.c | 12 ------------ xevents.c | 8 ++++++-- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/group.c b/group.c index b6ca7d5..0dc54ff 100644 --- a/group.c +++ b/group.c @@ -156,9 +156,6 @@ group_movetogroup(struct client_ctx *cc, int idx) struct screen_ctx *sc = cc->sc; struct group_ctx *gc; - if (idx < 0 || idx >= Conf.ngroups) - return; - TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == idx) { if (cc->gc == gc) @@ -216,9 +213,6 @@ group_hidetoggle(struct screen_ctx *sc, int idx) { struct group_ctx *gc; - if (idx < 0 || idx >= Conf.ngroups) - return; - TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == idx) { if (group_holds_only_hidden(gc)) @@ -238,9 +232,6 @@ group_only(struct screen_ctx *sc, int idx) { struct group_ctx *gc; - if (idx < 0 || idx >= Conf.ngroups) - return; - TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == idx) group_show(gc); @@ -255,9 +246,6 @@ group_close(struct screen_ctx *sc, int idx) struct group_ctx *gc; struct client_ctx *cc; - if (idx < 0 || idx >= Conf.ngroups) - return; - TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == idx) { TAILQ_FOREACH(cc, &gc->clientq, group_entry) diff --git a/xevents.c b/xevents.c index 8fd65ff..2ef236d 100644 --- a/xevents.c +++ b/xevents.c @@ -408,7 +408,9 @@ xev_handle_clientmessage(XEvent *ee) if (e->data.l[0] == (unsigned long)-1) group_movetogroup(cc, 0); else - group_movetogroup(cc, e->data.l[0]); + if (e->data.l[0] >= 0 && + e->data.l[0] < Conf.ngroups) + group_movetogroup(cc, e->data.l[0]); } } else if (e->message_type == ewmh[_NET_WM_STATE]) { if ((cc = client_find(e->window)) != NULL) { @@ -417,7 +419,9 @@ xev_handle_clientmessage(XEvent *ee) } } else if (e->message_type == ewmh[_NET_CURRENT_DESKTOP]) { if ((sc = screen_find(e->window)) != NULL) { - group_only(sc, e->data.l[0]); + if (e->data.l[0] >= 0 && + e->data.l[0] < Conf.ngroups) + group_only(sc, e->data.l[0]); } } } -- cgit 1.4.1 From 9d252184582d96dd916bc97675d6a35a18921140 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 1 Mar 2019 14:32:01 +0000 Subject: Tie group number and name together during config. --- calmwm.h | 3 ++- conf.c | 28 +++++++++++++++++++++++++++- group.c | 9 ++------- screen.c | 5 +---- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/calmwm.h b/calmwm.h index cbd4a83..b6fa48f 100644 --- a/calmwm.h +++ b/calmwm.h @@ -447,7 +447,7 @@ void group_hide(struct group_ctx *); void group_hidetoggle(struct screen_ctx *, int); int group_holds_only_hidden(struct group_ctx *); int group_holds_only_sticky(struct group_ctx *); -void group_init(struct screen_ctx *, int); +void group_init(struct screen_ctx *, int, const char *); void group_movetogroup(struct client_ctx *, int); void group_only(struct screen_ctx *, int); void group_close(struct screen_ctx *, int); @@ -555,6 +555,7 @@ void conf_grab_mouse(Window); void conf_init(struct conf *); void conf_ignore(struct conf *, const char *); void conf_screen(struct screen_ctx *); +void conf_group(struct screen_ctx *); void xev_process(void); diff --git a/conf.c b/conf.c index e54f96a..d6b0dd1 100644 --- a/conf.c +++ b/conf.c @@ -36,6 +36,21 @@ static const char *conf_bind_getmask(const char *, unsigned int *); static void conf_unbind_key(struct conf *, struct bind_ctx *); static void conf_unbind_mouse(struct conf *, struct bind_ctx *); +static const struct { + int num; + const char *name; +} group_binds[] = { + { 0, "nogroup" }, + { 1, "one" }, + { 2, "two" }, + { 3, "three" }, + { 4, "four" }, + { 5, "five" }, + { 6, "six" }, + { 7, "seven" }, + { 8, "eight" }, + { 9, "nine" }, +}; static int cursor_binds[] = { XC_left_ptr, /* CF_NORMAL */ XC_fleur, /* CF_MOVE */ @@ -266,7 +281,7 @@ conf_init(struct conf *c) c->bwidth = 1; c->mamount = 1; c->snapdist = 0; - c->ngroups = 10; + c->ngroups = 0; c->nameqlen = 5; TAILQ_INIT(&c->ignoreq); @@ -502,6 +517,17 @@ conf_screen(struct screen_ctx *sc) conf_grab_kbd(sc->rootwin); } +void +conf_group(struct screen_ctx *sc) +{ + unsigned int i; + + for (i = 0; i < nitems(group_binds); i++) { + group_init(sc, group_binds[i].num, group_binds[i].name); + Conf.ngroups++; + } +} + static const char * conf_bind_getmask(const char *name, unsigned int *mask) { diff --git a/group.c b/group.c index 0dc54ff..eee916f 100644 --- a/group.c +++ b/group.c @@ -37,11 +37,6 @@ static struct group_ctx *group_prev(struct group_ctx *); static void group_restack(struct group_ctx *); static void group_setactive(struct group_ctx *); -const char *num_to_name[] = { - "nogroup", "one", "two", "three", "four", "five", "six", - "seven", "eight", "nine" -}; - void group_assign(struct group_ctx *gc, struct client_ctx *cc) { @@ -124,13 +119,13 @@ group_restack(struct group_ctx *gc) } void -group_init(struct screen_ctx *sc, int num) +group_init(struct screen_ctx *sc, int num, const char *name) { struct group_ctx *gc; gc = xmalloc(sizeof(*gc)); gc->sc = sc; - gc->name = xstrdup(num_to_name[num]); + gc->name = xstrdup(name); gc->num = num; TAILQ_INIT(&gc->clientq); diff --git a/screen.c b/screen.c index 845a323..ffe1e0c 100644 --- a/screen.c +++ b/screen.c @@ -40,7 +40,6 @@ screen_init(int which) Window *wins, w0, w1, active = None; XSetWindowAttributes rootattr; unsigned int nwins, w; - int i; sc = xmalloc(sizeof(*sc)); @@ -61,9 +60,7 @@ screen_init(int which) xu_ewmh_net_supported_wm_check(sc); screen_update_geometry(sc); - - for (i = 0; i < Conf.ngroups; i++) - group_init(sc, i); + conf_group(sc); xu_ewmh_net_desktop_names(sc); xu_ewmh_net_wm_desktop_viewport(sc); -- cgit 1.4.1 From 0c0551b8bffd9a978247a9c6b98e84a9bdd6f76c Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 4 Mar 2019 13:33:39 +0000 Subject: simplify xftcolor config --- conf.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/conf.c b/conf.c index d6b0dd1..d600728 100644 --- a/conf.c +++ b/conf.c @@ -493,11 +493,8 @@ conf_screen(struct screen_ctx *sc) warnx("XftColorAllocValue: %s", Conf.color[i]); break; } - if (XftColorAllocName(X_Dpy, sc->visual, sc->colormap, - Conf.color[i], &xc)) { - sc->xftcolor[i] = xc; - XftColorFree(X_Dpy, sc->visual, sc->colormap, &xc); - } else { + if (!XftColorAllocName(X_Dpy, sc->visual, sc->colormap, + Conf.color[i], &sc->xftcolor[i])) { warnx("XftColorAllocName: %s", Conf.color[i]); XftColorAllocName(X_Dpy, sc->visual, sc->colormap, color_binds[i], &sc->xftcolor[i]); -- cgit 1.4.1 From fda68a40de36baebe1c27b91a49c7ee062555103 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 4 Mar 2019 14:36:02 +0000 Subject: _NET_WORKAREA needs ngroups, so screen_update_geometry() needs to come after conf_group(). --- screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/screen.c b/screen.c index ffe1e0c..f70c02e 100644 --- a/screen.c +++ b/screen.c @@ -59,8 +59,8 @@ screen_init(int which) xu_ewmh_net_supported(sc); xu_ewmh_net_supported_wm_check(sc); - screen_update_geometry(sc); conf_group(sc); + screen_update_geometry(sc); xu_ewmh_net_desktop_names(sc); xu_ewmh_net_wm_desktop_viewport(sc); -- cgit 1.4.1 From 9d5b0e5d22fca1b6fb37a8df906bdad0317238c9 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 4 Mar 2019 14:48:59 +0000 Subject: fix a few misplaced (and misnamed) ewmh root window functions --- calmwm.h | 4 ++-- screen.c | 4 ++-- xutil.c | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/calmwm.h b/calmwm.h index b6fa48f..32b7341 100644 --- a/calmwm.h +++ b/calmwm.h @@ -568,13 +568,13 @@ void xu_xorcolor(XftColor, XftColor, XftColor *); void xu_ewmh_net_supported(struct screen_ctx *); void xu_ewmh_net_supported_wm_check(struct screen_ctx *); void xu_ewmh_net_desktop_geometry(struct screen_ctx *); +void xu_ewmh_net_desktop_viewport(struct screen_ctx *); void xu_ewmh_net_workarea(struct screen_ctx *); void xu_ewmh_net_client_list(struct screen_ctx *); void xu_ewmh_net_client_list_stacking(struct screen_ctx *); void xu_ewmh_net_active_window(struct screen_ctx *, Window); Window xu_ewmh_get_net_active_window(struct screen_ctx *); -void xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *); -void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *); +void xu_ewmh_net_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 *); diff --git a/screen.c b/screen.c index f70c02e..a449219 100644 --- a/screen.c +++ b/screen.c @@ -63,8 +63,7 @@ screen_init(int which) screen_update_geometry(sc); xu_ewmh_net_desktop_names(sc); - xu_ewmh_net_wm_desktop_viewport(sc); - xu_ewmh_net_wm_number_of_desktops(sc); + xu_ewmh_net_number_of_desktops(sc); xu_ewmh_net_showing_desktop(sc); xu_ewmh_net_virtual_roots(sc); active = xu_ewmh_get_net_active_window(sc); @@ -214,6 +213,7 @@ screen_update_geometry(struct screen_ctx *sc) } xu_ewmh_net_desktop_geometry(sc); + xu_ewmh_net_desktop_viewport(sc); xu_ewmh_net_workarea(sc); } diff --git a/xutil.c b/xutil.c index 7fd3115..d0b5111 100644 --- a/xutil.c +++ b/xutil.c @@ -128,6 +128,16 @@ xu_ewmh_net_desktop_geometry(struct screen_ctx *sc) XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2); } +void +xu_ewmh_net_desktop_viewport(struct screen_ctx *sc) +{ + long viewports[2] = {0, 0}; + + /* We don't support large desktops, so this is (0, 0). */ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_VIEWPORT], + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2); +} + void xu_ewmh_net_workarea(struct screen_ctx *sc) { @@ -212,17 +222,7 @@ xu_ewmh_get_net_active_window(struct screen_ctx *sc) } void -xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *sc) -{ - long viewports[2] = {0, 0}; - - /* We don't support large desktops, so this is (0, 0). */ - XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_VIEWPORT], - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2); -} - -void -xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *sc) +xu_ewmh_net_number_of_desktops(struct screen_ctx *sc) { long ndesks = Conf.ngroups; -- cgit 1.4.1 From 0bda8f76067b737f34c11ef094b349c0c12fe118 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 4 Mar 2019 19:28:17 +0000 Subject: Separate out the menu window from the client resize/move geom window; in each case, create and destroy on-demand. Isolate more menu specific code. --- calmwm.c | 2 -- calmwm.h | 15 ++++++------ conf.c | 10 -------- kbfunc.c | 19 +++++++-------- menu.c | 82 +++++++++++++++++++++++++--------------------------------------- screen.c | 45 +++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 80 deletions(-) diff --git a/calmwm.c b/calmwm.c index 510bd33..b1c23ed 100644 --- a/calmwm.c +++ b/calmwm.c @@ -165,8 +165,6 @@ x_teardown(void) DefaultColormap(X_Dpy, sc->which), &sc->xftcolor[i]); XftFontClose(X_Dpy, sc->xftfont); - XftDrawDestroy(sc->menu.xftdraw); - XDestroyWindow(X_Dpy, sc->menu.win); XUngrabKey(X_Dpy, AnyKey, AnyModifier, sc->rootwin); } XUngrabPointer(X_Dpy, CurrentTime); diff --git a/calmwm.h b/calmwm.h index 32b7341..939f946 100644 --- a/calmwm.h +++ b/calmwm.h @@ -47,9 +47,6 @@ #define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) #define MOUSEMASK (BUTTONMASK | PointerMotionMask) -#define MENUMASK (MOUSEMASK | ButtonMotionMask | KeyPressMask | \ - ExposureMask) -#define MENUGRABMASK (MOUSEMASK | ButtonMotionMask | StructureNotifyMask) #define IGNOREMODMASK (LockMask | Mod2Mask | 0x2000) /* direction/amount */ @@ -229,7 +226,7 @@ struct screen_ctx { struct { Window win; XftDraw *xftdraw; - } menu; + } prop; XftColor xftcolor[CWM_COLOR_NITEMS]; XftFont *xftfont; }; @@ -484,6 +481,12 @@ void screen_init(int); void screen_update_geometry(struct screen_ctx *); void screen_updatestackingorder(struct screen_ctx *); void screen_assert_clients_within(struct screen_ctx *); +void screen_prop_win_create(struct screen_ctx *, Window); +void screen_prop_win_destroy(struct screen_ctx *); +void screen_prop_win_draw(struct screen_ctx *, + const char *, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); void kbfunc_cwm_status(void *, struct cargs *); void kbfunc_ptrmove(void *, struct cargs *); @@ -522,10 +525,6 @@ void kbfunc_exec_cmd(void *, struct cargs *); void kbfunc_exec_lock(void *, struct cargs *); void kbfunc_exec_term(void *, struct cargs *); -void menu_windraw(struct screen_ctx *, Window, - const char *, ...) - __attribute__((__format__ (printf, 3, 4))) - __attribute__((__nonnull__ (3))); struct menu *menu_filter(struct screen_ctx *, struct menu_q *, const char *, const char *, int, void (*)(struct menu_q *, struct menu_q *, char *), diff --git a/conf.c b/conf.c index d600728..30c803e 100644 --- a/conf.c +++ b/conf.c @@ -501,16 +501,6 @@ conf_screen(struct screen_ctx *sc) } } - sc->menu.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1, - Conf.bwidth, - sc->xftcolor[CWM_COLOR_MENU_FG].pixel, - sc->xftcolor[CWM_COLOR_MENU_BG].pixel); - - sc->menu.xftdraw = XftDrawCreate(X_Dpy, sc->menu.win, - sc->visual, sc->colormap); - if (sc->menu.xftdraw == NULL) - errx(1, "%s: XftDrawCreate", __func__); - conf_grab_kbd(sc->rootwin); } diff --git a/kbfunc.c b/kbfunc.c index 35b9b22..1858a42 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -166,8 +166,8 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs) CurrentTime) != GrabSuccess) return; - menu_windraw(sc, cc->win, "%4d, %-4d", cc->geom.x, cc->geom.y); - + screen_prop_win_create(sc, cc->win); + screen_prop_win_draw(sc, "%+5d%+5d", cc->geom.x, cc->geom.y); while (move) { XMaskEvent(X_Dpy, MOUSEMASK, &ev); switch (ev.type) { @@ -190,8 +190,8 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs) cc->geom.y + cc->geom.h + (cc->bwidth * 2), area.y, area.y + area.h, sc->snapdist); client_move(cc); - menu_windraw(sc, cc->win, - "%4d, %-4d", cc->geom.x, cc->geom.y); + screen_prop_win_draw(sc, + "%+5d%+5d", cc->geom.x, cc->geom.y); break; case ButtonRelease: move = 0; @@ -200,8 +200,7 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs) } if (ltime) client_move(cc); - XUnmapWindow(X_Dpy, sc->menu.win); - XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0); + screen_prop_win_destroy(sc); XUngrabPointer(X_Dpy, CurrentTime); } @@ -255,7 +254,8 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs) CurrentTime) != GrabSuccess) return; - menu_windraw(sc, cc->win, "%4d x %-4d", cc->dim.w, cc->dim.h); + screen_prop_win_create(sc, cc->win); + screen_prop_win_draw(sc, "%4d x %-4d", cc->dim.w, cc->dim.h); while (resize) { XMaskEvent(X_Dpy, MOUSEMASK, &ev); switch (ev.type) { @@ -269,7 +269,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs) cc->geom.h = ev.xmotion.y; client_applysizehints(cc); client_resize(cc, 1); - menu_windraw(sc, cc->win, + screen_prop_win_draw(sc, "%4d x %-4d", cc->dim.w, cc->dim.h); break; case ButtonRelease: @@ -279,8 +279,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs) } if (ltime) client_resize(cc, 1); - XUnmapWindow(X_Dpy, sc->menu.win); - XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0); + screen_prop_win_destroy(sc); XUngrabPointer(X_Dpy, CurrentTime); /* Make sure the pointer stays within the window. */ diff --git a/menu.c b/menu.c index d06c529..d0d3802 100644 --- a/menu.c +++ b/menu.c @@ -37,6 +37,10 @@ #define PROMPT_SCHAR "\xc2\xbb" #define PROMPT_ECHAR "\xc2\xab" +#define MENUMASK (MOUSEMASK | ButtonMotionMask | KeyPressMask | \ + ExposureMask) +#define MENUGRABMASK (MOUSEMASK | ButtonMotionMask | StructureNotifyMask) + enum ctltype { CTL_NONE = -1, CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN, @@ -45,6 +49,9 @@ enum ctltype { struct menu_ctx { struct screen_ctx *sc; + Window win; + XftDraw *xftdraw; + struct geom geom; char searchstr[MENU_MAXENTRY + 1]; char dispstr[MENU_MAXENTRY*2 + 1]; char promptstr[MENU_MAXENTRY + 1]; @@ -55,7 +62,6 @@ struct menu_ctx { int entry; int num; int flags; - struct geom geom; void (*match)(struct menu_q *, struct menu_q *, char *); void (*print)(struct menu *, int); }; @@ -108,27 +114,34 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt, else mc.searchstr[0] = '\0'; - XSelectInput(X_Dpy, sc->menu.win, MENUMASK); - XMapRaised(X_Dpy, sc->menu.win); + mc.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1, + Conf.bwidth, + sc->xftcolor[CWM_COLOR_MENU_FG].pixel, + sc->xftcolor[CWM_COLOR_MENU_BG].pixel); + mc.xftdraw = XftDrawCreate(X_Dpy, mc.win, + sc->visual, sc->colormap); - if (XGrabPointer(X_Dpy, sc->menu.win, False, MENUGRABMASK, + XSelectInput(X_Dpy, mc.win, MENUMASK); + XMapRaised(X_Dpy, mc.win); + + if (XGrabPointer(X_Dpy, mc.win, False, MENUGRABMASK, GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_QUESTION], CurrentTime) != GrabSuccess) { - XUnmapWindow(X_Dpy, sc->menu.win); - return(NULL); + XftDrawDestroy(mc.xftdraw); + XDestroyWindow(X_Dpy, mc.win); } XGetInputFocus(X_Dpy, &focuswin, &focusrevert); - XSetInputFocus(X_Dpy, sc->menu.win, RevertToPointerRoot, CurrentTime); + XSetInputFocus(X_Dpy, mc.win, RevertToPointerRoot, CurrentTime); /* make sure keybindings don't remove keys from the menu stream */ - XGrabKeyboard(X_Dpy, sc->menu.win, True, + XGrabKeyboard(X_Dpy, mc.win, True, GrabModeAsync, GrabModeAsync, CurrentTime); for (;;) { mc.changed = 0; - XWindowEvent(X_Dpy, sc->menu.win, MENUMASK, &e); + XWindowEvent(X_Dpy, mc.win, MENUMASK, &e); switch (e.type) { case KeyPress: @@ -159,16 +172,16 @@ out: mi = NULL; } - XSelectInput(X_Dpy, sc->menu.win, NoEventMask); + XftDrawDestroy(mc.xftdraw); + XDestroyWindow(X_Dpy, mc.win); + XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime); /* restore if user didn't move */ xu_ptr_getpos(sc->rootwin, &xcur, &ycur); if (xcur == mc.geom.x && ycur == mc.geom.y) xu_ptr_setpos(sc->rootwin, xsave, ysave); - XUngrabPointer(X_Dpy, CurrentTime); - XMoveResizeWindow(X_Dpy, sc->menu.win, 0, 0, 1, 1); - XUnmapWindow(X_Dpy, sc->menu.win); + XUngrabPointer(X_Dpy, CurrentTime); XUngrabKeyboard(X_Dpy, CurrentTime); return(mi); @@ -378,12 +391,12 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq) if (mc->geom.x != xsave || mc->geom.y != ysave) xu_ptr_setpos(sc->rootwin, mc->geom.x, mc->geom.y); - XClearWindow(X_Dpy, sc->menu.win); - XMoveResizeWindow(X_Dpy, sc->menu.win, mc->geom.x, mc->geom.y, + XClearWindow(X_Dpy, mc->win); + XMoveResizeWindow(X_Dpy, mc->win, mc->geom.x, mc->geom.y, mc->geom.w, mc->geom.h); n = 1; - XftDrawStringUtf8(sc->menu.xftdraw, + XftDrawStringUtf8(mc->xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont, 0, sc->xftfont->ascent, (const FcChar8*)mc->dispstr, strlen(mc->dispstr)); @@ -395,7 +408,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq) if (mc->geom.y + y > area.h) break; - XftDrawStringUtf8(sc->menu.xftdraw, + XftDrawStringUtf8(mc->xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont, 0, y, (const FcChar8*)mi->print, strlen(mi->print)); @@ -420,11 +433,11 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq, return; color = (active) ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG; - XftDrawRect(sc->menu.xftdraw, &sc->xftcolor[color], 0, + XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0, (sc->xftfont->height + 1) * entry, mc->geom.w, (sc->xftfont->height + 1) + sc->xftfont->descent); color = (active) ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT; - XftDrawStringUtf8(sc->menu.xftdraw, + XftDrawStringUtf8(mc->xftdraw, &sc->xftcolor[color], sc->xftfont, 0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1, (const FcChar8*)mi->print, strlen(mi->print)); @@ -604,34 +617,3 @@ menuq_clear(struct menu_q *mq) free(mi); } } - -void -menu_windraw(struct screen_ctx *sc, Window win, const char *fmt, ...) -{ - va_list ap; - int i; - char *text; - XGlyphInfo extents; - - va_start(ap, fmt); - i = vasprintf(&text, fmt, ap); - va_end(ap); - - if (i < 0 || text == NULL) - err(1, "vasprintf"); - - XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text, - strlen(text), &extents); - - XReparentWindow(X_Dpy, sc->menu.win, win, 0, 0); - XMoveResizeWindow(X_Dpy, sc->menu.win, 0, 0, - extents.xOff, sc->xftfont->height); - XMapWindow(X_Dpy, sc->menu.win); - XClearWindow(X_Dpy, sc->menu.win); - - XftDrawStringUtf8(sc->menu.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT], - sc->xftfont, 0, sc->xftfont->ascent + 1, - (const FcChar8*)text, strlen(text)); - - free(text); -} diff --git a/screen.c b/screen.c index a449219..eb84a17 100644 --- a/screen.c +++ b/screen.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -250,3 +251,47 @@ screen_assert_clients_within(struct screen_ctx *sc) } } } + +void +screen_prop_win_create(struct screen_ctx *sc, Window win) +{ + sc->prop.win = XCreateSimpleWindow(X_Dpy, win, 0, 0, 1, 1, 0, + sc->xftcolor[CWM_COLOR_MENU_BG].pixel, + sc->xftcolor[CWM_COLOR_MENU_BG].pixel); + sc->prop.xftdraw = XftDrawCreate(X_Dpy, sc->prop.win, + sc->visual, sc->colormap); + + XMapWindow(X_Dpy, sc->prop.win); +} + +void +screen_prop_win_destroy(struct screen_ctx *sc) +{ + XftDrawDestroy(sc->prop.xftdraw); + XDestroyWindow(X_Dpy, sc->prop.win); +} + +void +screen_prop_win_draw(struct screen_ctx *sc, const char *fmt, ...) +{ + va_list ap; + int i; + char *text; + XGlyphInfo extents; + + va_start(ap, fmt); + i = vasprintf(&text, fmt, ap); + va_end(ap); + if (i < 0 || text == NULL) + err(1, "vasprintf"); + + XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text, + strlen(text), &extents); + XResizeWindow(X_Dpy, sc->prop.win, extents.xOff, sc->xftfont->height); + XClearWindow(X_Dpy, sc->prop.win); + XftDrawStringUtf8(sc->prop.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT], + sc->xftfont, 0, sc->xftfont->ascent + 1, + (const FcChar8*)text, strlen(text)); + + free(text); +} -- cgit 1.4.1 From 9efa6c8c85780c3d5604d0686c943627765dd1a5 Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 6 Mar 2019 13:32:19 +0000 Subject: same thing as screen_find() --- xevents.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/xevents.c b/xevents.c index 2ef236d..6c73b62 100644 --- a/xevents.c +++ b/xevents.c @@ -206,13 +206,9 @@ xev_handle_propertynotify(XEvent *ee) /* do nothing */ break; } - } else { - TAILQ_FOREACH(sc, &Screenq, entry) { - if (sc->rootwin == e->window) { - if (e->atom == ewmh[_NET_DESKTOP_NAMES]) - xu_ewmh_net_desktop_names(sc); - } - } + } else if ((sc = screen_find(e->window)) != NULL) { + if (e->atom == ewmh[_NET_DESKTOP_NAMES]) + xu_ewmh_net_desktop_names(sc); } } -- cgit 1.4.1 From b26202724a342b596692b5e9b1f47c7c491a1934 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 7 Mar 2019 12:54:21 +0000 Subject: shuffle deck chairs: rename group actions to match intent for clarity --- calmwm.h | 6 +++--- conf.c | 2 +- group.c | 34 +++++++++++++++++----------------- kbfunc.c | 18 +++++++++--------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/calmwm.h b/calmwm.h index 939f946..14ef4f4 100644 --- a/calmwm.h +++ b/calmwm.h @@ -436,12 +436,10 @@ void client_urgency(struct client_ctx *); void client_vtile(struct client_ctx *); void client_wm_hints(struct client_ctx *); -void group_alltoggle(struct screen_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); int group_holds_only_hidden(struct group_ctx *); int group_holds_only_sticky(struct group_ctx *); void group_init(struct screen_ctx *, int, const char *); @@ -450,6 +448,8 @@ void group_only(struct screen_ctx *, int); void group_close(struct screen_ctx *, int); int group_restore(struct client_ctx *); void group_show(struct group_ctx *); +void group_toggle(struct screen_ctx *, int); +void group_toggle_all(struct screen_ctx *); void group_toggle_membership(struct client_ctx *); void group_update_names(struct screen_ctx *); @@ -513,7 +513,7 @@ void kbfunc_group_toggle(void *, struct cargs *); void kbfunc_group_only(void *, struct cargs *); void kbfunc_group_close(void *, struct cargs *); void kbfunc_group_cycle(void *, struct cargs *); -void kbfunc_group_alltoggle(void *, struct cargs *); +void kbfunc_group_toggle_all(void *, struct cargs *); void kbfunc_menu_client(void *, struct cargs *); void kbfunc_menu_cmd(void *, struct cargs *); void kbfunc_menu_group(void *, struct cargs *); diff --git a/conf.c b/conf.c index 30c803e..d25e00f 100644 --- a/conf.c +++ b/conf.c @@ -139,7 +139,7 @@ static const struct { { FUNC_SC(group-cycle, group_cycle, (CWM_CYCLE_FORWARD)) }, { FUNC_SC(group-rcycle, group_cycle, (CWM_CYCLE_REVERSE)) }, - { FUNC_SC(group-toggle-all, group_alltoggle, 0) }, + { FUNC_SC(group-toggle-all, group_toggle_all, 0) }, { FUNC_SC(group-toggle-1, group_toggle, 1) }, { FUNC_SC(group-toggle-2, group_toggle, 2) }, { FUNC_SC(group-toggle-3, group_toggle, 3) }, diff --git a/group.c b/group.c index eee916f..c1788eb 100644 --- a/group.c +++ b/group.c @@ -204,7 +204,20 @@ group_holds_only_hidden(struct group_ctx *gc) } void -group_hidetoggle(struct screen_ctx *sc, int idx) +group_only(struct screen_ctx *sc, int idx) +{ + struct group_ctx *gc; + + TAILQ_FOREACH(gc, &sc->groupq, entry) { + if (gc->num == idx) + group_show(gc); + else + group_hide(gc); + } +} + +void +group_toggle(struct screen_ctx *sc, int idx) { struct group_ctx *gc; @@ -223,16 +236,17 @@ group_hidetoggle(struct screen_ctx *sc, int idx) } void -group_only(struct screen_ctx *sc, int idx) +group_toggle_all(struct screen_ctx *sc) { struct group_ctx *gc; TAILQ_FOREACH(gc, &sc->groupq, entry) { - if (gc->num == idx) + if (sc->hideall) group_show(gc); else group_hide(gc); } + sc->hideall = !sc->hideall; } void @@ -301,20 +315,6 @@ group_prev(struct group_ctx *gc) newgc : TAILQ_LAST(&sc->groupq, group_q)); } -void -group_alltoggle(struct screen_ctx *sc) -{ - struct group_ctx *gc; - - TAILQ_FOREACH(gc, &sc->groupq, entry) { - if (sc->hideall) - group_show(gc); - else - group_hide(gc); - } - sc->hideall = !sc->hideall; -} - int group_restore(struct client_ctx *cc) { diff --git a/kbfunc.c b/kbfunc.c index 1858a42..5f6d54e 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -427,16 +427,22 @@ kbfunc_client_movetogroup(void *ctx, struct cargs *cargs) group_movetogroup(ctx, cargs->flag); } +void +kbfunc_group_only(void *ctx, struct cargs *cargs) +{ + group_only(ctx, cargs->flag); +} + void kbfunc_group_toggle(void *ctx, struct cargs *cargs) { - group_hidetoggle(ctx, cargs->flag); + group_toggle(ctx, cargs->flag); } void -kbfunc_group_only(void *ctx, struct cargs *cargs) +kbfunc_group_toggle_all(void *ctx, struct cargs *cargs) { - group_only(ctx, cargs->flag); + group_toggle_all(ctx); } void @@ -451,12 +457,6 @@ kbfunc_group_cycle(void *ctx, struct cargs *cargs) group_cycle(ctx, cargs->flag); } -void -kbfunc_group_alltoggle(void *ctx, struct cargs *cargs) -{ - group_alltoggle(ctx); -} - void kbfunc_menu_client(void *ctx, struct cargs *cargs) { -- cgit 1.4.1 From aa79351d2e85e04add3ad684f15528f2efcba46a Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 7 Mar 2019 13:14:41 +0000 Subject: gc clientq inside groups, instead use the better maintained one per-screen --- calmwm.h | 2 -- client.c | 19 ++++++++++++------- group.c | 47 ++++++++++++++++++++++++++++------------------- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/calmwm.h b/calmwm.h index 14ef4f4..089a9a2 100644 --- a/calmwm.h +++ b/calmwm.h @@ -121,7 +121,6 @@ TAILQ_HEAD(ignore_q, winname); struct client_ctx { TAILQ_ENTRY(client_ctx) entry; - TAILQ_ENTRY(client_ctx) group_entry; struct screen_ctx *sc; struct group_ctx *gc; Window win; @@ -187,7 +186,6 @@ struct group_ctx { struct screen_ctx *sc; char *name; int num; - struct client_q clientq; }; TAILQ_HEAD(group_q, group_ctx); diff --git a/client.c b/client.c index 19c2ab4..ed98504 100644 --- a/client.c +++ b/client.c @@ -183,9 +183,6 @@ client_remove(struct client_ctx *cc) if (cc->flags & CLIENT_ACTIVE) xu_ewmh_net_active_window(sc, None); - if (cc->gc != NULL) - TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry); - while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) { TAILQ_REMOVE(&cc->nameq, wn, entry); free(wn->name); @@ -976,7 +973,9 @@ client_htile(struct client_ctx *cc) cc->geom.x + cc->geom.w / 2, cc->geom.y + cc->geom.h / 2, CWM_GAP); - TAILQ_FOREACH(ci, &gc->clientq, group_entry) { + TAILQ_FOREACH(ci, &sc->clientq, entry) { + if (ci->gc != cc->gc) + continue; if (ci->flags & CLIENT_HIDDEN || ci->flags & CLIENT_IGNORE || (ci == cc) || ci->geom.x < area.x || @@ -1005,7 +1004,9 @@ client_htile(struct client_ctx *cc) x = area.x; w = area.w / n; h = area.h - mh; - TAILQ_FOREACH(ci, &gc->clientq, group_entry) { + TAILQ_FOREACH(ci, &sc->clientq, entry) { + if (ci->gc != cc->gc) + continue; if (ci->flags & CLIENT_HIDDEN || ci->flags & CLIENT_IGNORE || (ci == cc) || ci->geom.x < area.x || @@ -1044,7 +1045,9 @@ client_vtile(struct client_ctx *cc) cc->geom.x + cc->geom.w / 2, cc->geom.y + cc->geom.h / 2, CWM_GAP); - TAILQ_FOREACH(ci, &gc->clientq, group_entry) { + TAILQ_FOREACH(ci, &sc->clientq, entry) { + if (ci->gc != cc->gc) + continue; if (ci->flags & CLIENT_HIDDEN || ci->flags & CLIENT_IGNORE || (ci == cc) || ci->geom.x < area.x || @@ -1073,7 +1076,9 @@ client_vtile(struct client_ctx *cc) y = area.y; h = area.h / n; w = area.w - mw; - TAILQ_FOREACH(ci, &gc->clientq, group_entry) { + TAILQ_FOREACH(ci, &sc->clientq, entry) { + if (ci->gc != cc->gc) + continue; if (ci->flags & CLIENT_HIDDEN || ci->flags & CLIENT_IGNORE || (ci == cc) || ci->geom.x < area.x || diff --git a/group.c b/group.c index c1788eb..cf9022c 100644 --- a/group.c +++ b/group.c @@ -40,28 +40,25 @@ static void group_setactive(struct group_ctx *); void group_assign(struct group_ctx *gc, struct client_ctx *cc) { - if (cc->gc != NULL) - TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry); - if ((gc != NULL) && (gc->num == 0)) gc = NULL; cc->gc = gc; - if (cc->gc != NULL) - TAILQ_INSERT_TAIL(&gc->clientq, cc, group_entry); - xu_ewmh_net_wm_desktop(cc); } void group_hide(struct group_ctx *gc) { + struct screen_ctx *sc = gc->sc; struct client_ctx *cc; screen_updatestackingorder(gc->sc); - TAILQ_FOREACH(cc, &gc->clientq, group_entry) { + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; if (!(cc->flags & CLIENT_STICKY) && !(cc->flags & CLIENT_HIDDEN)) client_hide(cc); @@ -71,9 +68,12 @@ group_hide(struct group_ctx *gc) void group_show(struct group_ctx *gc) { + struct screen_ctx *sc = gc->sc; struct client_ctx *cc; - TAILQ_FOREACH(cc, &gc->clientq, group_entry) { + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; if (!(cc->flags & CLIENT_STICKY) && (cc->flags & CLIENT_HIDDEN)) client_show(cc); @@ -86,19 +86,24 @@ group_show(struct group_ctx *gc) static void group_restack(struct group_ctx *gc) { + struct screen_ctx *sc = gc->sc; struct client_ctx *cc; Window *winlist; int i, lastempty = -1; int nwins = 0, highstack = 0; - TAILQ_FOREACH(cc, &gc->clientq, group_entry) { + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; if (cc->stackingorder > highstack) highstack = cc->stackingorder; } winlist = xreallocarray(NULL, (highstack + 1), sizeof(*winlist)); /* Invert the stacking order for XRestackWindows(). */ - TAILQ_FOREACH(cc, &gc->clientq, group_entry) { + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; winlist[highstack - cc->stackingorder] = cc->win; nwins++; } @@ -127,7 +132,6 @@ group_init(struct screen_ctx *sc, int num, const char *name) gc->sc = sc; gc->name = xstrdup(name); gc->num = num; - TAILQ_INIT(&gc->clientq); TAILQ_INSERT_TAIL(&sc->groupq, gc, entry); @@ -182,9 +186,12 @@ group_toggle_membership(struct client_ctx *cc) int group_holds_only_sticky(struct group_ctx *gc) { + struct screen_ctx *sc = gc->sc; struct client_ctx *cc; - TAILQ_FOREACH(cc, &gc->clientq, group_entry) { + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; if (!(cc->flags & CLIENT_STICKY)) return(0); } @@ -194,9 +201,12 @@ group_holds_only_sticky(struct group_ctx *gc) int group_holds_only_hidden(struct group_ctx *gc) { + struct screen_ctx *sc = gc->sc; struct client_ctx *cc; - TAILQ_FOREACH(cc, &gc->clientq, group_entry) { + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; if (!(cc->flags & (CLIENT_HIDDEN | CLIENT_STICKY))) return(0); } @@ -225,12 +235,8 @@ group_toggle(struct screen_ctx *sc, int idx) if (gc->num == idx) { if (group_holds_only_hidden(gc)) group_show(gc); - else { + else group_hide(gc); - /* make clients stick to empty group */ - if (TAILQ_EMPTY(&gc->clientq)) - group_setactive(gc); - } } } } @@ -257,8 +263,11 @@ group_close(struct screen_ctx *sc, int idx) TAILQ_FOREACH(gc, &sc->groupq, entry) { if (gc->num == idx) { - TAILQ_FOREACH(cc, &gc->clientq, group_entry) + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; client_close(cc); + } } } } -- cgit 1.4.1 From 823566a65309c047695f5f2b22a93e8f43a54396 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 7 Mar 2019 13:24:10 +0000 Subject: zip extra lines --- group.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/group.c b/group.c index cf9022c..bdec108 100644 --- a/group.c +++ b/group.c @@ -78,7 +78,6 @@ group_show(struct group_ctx *gc) (cc->flags & CLIENT_HIDDEN)) client_show(cc); } - group_restack(gc); group_setactive(gc); } @@ -132,7 +131,6 @@ group_init(struct screen_ctx *sc, int num, const char *name) gc->sc = sc; gc->name = xstrdup(name); gc->num = num; - TAILQ_INSERT_TAIL(&sc->groupq, gc, entry); if (num == 1) @@ -172,14 +170,13 @@ group_toggle_membership(struct client_ctx *cc) struct screen_ctx *sc = cc->sc; struct group_ctx *gc = sc->group_active; - if (gc == cc->gc) { + if (cc->gc == gc) { group_assign(NULL, cc); cc->flags |= CLIENT_UNGROUP; } else { group_assign(gc, cc); cc->flags |= CLIENT_GROUP; } - client_draw_border(cc); } @@ -292,7 +289,6 @@ group_cycle(struct screen_ctx *sc, int flags) else if (!group_holds_only_hidden(newgc)) group_hide(newgc); } - if (showgroup == NULL) return; -- cgit 1.4.1 From 01be5b4e4a04e5f454d0e685c71c8023c7c0b731 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 7 Mar 2019 13:24:44 +0000 Subject: check cc->gc directly --- client.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client.c b/client.c index ed98504..94f295a 100644 --- a/client.c +++ b/client.c @@ -960,12 +960,11 @@ void client_htile(struct client_ctx *cc) { struct client_ctx *ci; - struct group_ctx *gc = cc->gc; struct screen_ctx *sc = cc->sc; struct geom area; int i, n, mh, x, w, h; - if (!gc) + if (!cc->gc) return; i = n = 0; @@ -1032,12 +1031,11 @@ void client_vtile(struct client_ctx *cc) { struct client_ctx *ci; - struct group_ctx *gc = cc->gc; struct screen_ctx *sc = cc->sc; struct geom area; int i, n, mw, y, w, h; - if (!gc) + if (!cc->gc) return; i = n = 0; -- cgit 1.4.1 From 7c45b87622c069a176359df3c632086540a7fe3f Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 7 Mar 2019 14:28:17 +0000 Subject: Teach client_current() to use a screen to find the current client instead of iterating over all (fallback if no screen provided for now). Initially convert trivial uses of client_current(). --- calmwm.h | 2 +- client.c | 17 ++++++++++++----- kbfunc.c | 2 +- xevents.c | 10 +++++----- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/calmwm.h b/calmwm.h index 089a9a2..00f42be 100644 --- a/calmwm.h +++ b/calmwm.h @@ -394,7 +394,7 @@ __dead void usage(void); void client_applysizehints(struct client_ctx *); void client_config(struct client_ctx *); -struct client_ctx *client_current(void); +struct client_ctx *client_current(struct screen_ctx *); void client_cycle(struct screen_ctx *, int); void client_remove(struct client_ctx *); void client_draw_border(struct client_ctx *); diff --git a/client.c b/client.c index 94f295a..0187f4e 100644 --- a/client.c +++ b/client.c @@ -218,7 +218,7 @@ client_setactive(struct client_ctx *cc) if (cc->flags & CLIENT_WM_TAKE_FOCUS) client_msg(cc, cwmh[WM_TAKE_FOCUS], Last_Event_Time); - if ((oldcc = client_current()) != NULL) { + if ((oldcc = client_current(sc)) != NULL) { oldcc->flags &= ~CLIENT_ACTIVE; client_draw_border(oldcc); } @@ -235,16 +235,23 @@ client_setactive(struct client_ctx *cc) } struct client_ctx * -client_current(void) +client_current(struct screen_ctx *sc) { - struct screen_ctx *sc; + struct screen_ctx *_sc; struct client_ctx *cc; - TAILQ_FOREACH(sc, &Screenq, entry) { + if (sc) { TAILQ_FOREACH(cc, &sc->clientq, entry) { if (cc->flags & CLIENT_ACTIVE) return(cc); } + } else { + TAILQ_FOREACH(_sc, &Screenq, entry) { + TAILQ_FOREACH(cc, &_sc->clientq, entry) { + if (cc->flags & CLIENT_ACTIVE) + return(cc); + } + } } return(NULL); } @@ -679,7 +686,7 @@ client_cycle(struct screen_ctx *sc, int flags) return; prevcc = TAILQ_FIRST(&sc->clientq); - oldcc = client_current(); + oldcc = client_current(sc); if (oldcc == NULL) oldcc = (flags & CWM_CYCLE_REVERSE) ? TAILQ_LAST(&sc->clientq, client_q) : diff --git a/kbfunc.c b/kbfunc.c index 5f6d54e..03a5d79 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -470,7 +470,7 @@ kbfunc_menu_client(void *ctx, struct cargs *cargs) if (cargs->xev == CWM_XEV_BTN) mflags |= CWM_MENU_LIST; - old_cc = client_current(); + old_cc = client_current(sc); TAILQ_INIT(&menuq); TAILQ_FOREACH(cc, &sc->clientq, entry) { diff --git a/xevents.c b/xevents.c index 6c73b62..8bbd525 100644 --- a/xevents.c +++ b/xevents.c @@ -79,7 +79,7 @@ xev_handle_maprequest(XEvent *ee) LOG_DEBUG3("window: 0x%lx", e->window); - if ((old_cc = client_current()) != NULL) + if ((old_cc = client_current(NULL)) != NULL) client_ptrsave(old_cc); if ((cc = client_find(e->window)) == NULL) @@ -249,7 +249,7 @@ xev_handle_buttonpress(XEvent *ee) switch (mb->context) { case CWM_CONTEXT_CC: if (((cc = client_find(e->window)) == NULL) && - (cc = client_current()) == NULL) + (cc = client_current(NULL)) == NULL) return; (*mb->callback)(cc, mb->cargs); break; @@ -318,7 +318,7 @@ xev_handle_keypress(XEvent *ee) switch (kb->context) { case CWM_CONTEXT_CC: if (((cc = client_find(e->window)) == NULL) && - (cc = client_current()) == NULL) + (cc = client_current(NULL)) == NULL) return; (*kb->callback)(cc, kb->cargs); break; @@ -353,7 +353,7 @@ xev_handle_keyrelease(XEvent *ee) keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0); for (i = 0; i < nitems(modkeys); i++) { if (keysym == modkeys[i]) { - if ((cc = client_current()) != NULL) { + if ((cc = client_current(NULL)) != NULL) { if (sc->cycling) { sc->cycling = 0; client_mtf(cc); @@ -389,7 +389,7 @@ xev_handle_clientmessage(XEvent *ee) } } else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) { if ((cc = client_find(e->window)) != NULL) { - if ((old_cc = client_current()) != NULL) + if ((old_cc = client_current(NULL)) != NULL) client_ptrsave(old_cc); client_show(cc); client_ptrwarp(cc); -- cgit 1.4.1 From 2a3c2b5231e42691580c6ad90d82980e84cd5302 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 8 Mar 2019 13:17:26 +0000 Subject: add parans for readibility --- xevents.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xevents.c b/xevents.c index 8bbd525..cdbfdfc 100644 --- a/xevents.c +++ b/xevents.c @@ -249,7 +249,7 @@ xev_handle_buttonpress(XEvent *ee) switch (mb->context) { case CWM_CONTEXT_CC: if (((cc = client_find(e->window)) == NULL) && - (cc = client_current(NULL)) == NULL) + ((cc = client_current(NULL)) == NULL)) return; (*mb->callback)(cc, mb->cargs); break; @@ -318,7 +318,7 @@ xev_handle_keypress(XEvent *ee) switch (kb->context) { case CWM_CONTEXT_CC: if (((cc = client_find(e->window)) == NULL) && - (cc = client_current(NULL)) == NULL) + ((cc = client_current(NULL)) == NULL)) return; (*kb->callback)(cc, kb->cargs); break; @@ -479,9 +479,9 @@ xev_process(void) while (XPending(X_Dpy)) { XNextEvent(X_Dpy, &e); - if (e.type - Conf.xrandr_event_base == RRScreenChangeNotify) + if ((e.type - Conf.xrandr_event_base) == RRScreenChangeNotify) xev_handle_randr(&e); - else if (e.type < LASTEvent && xev_handlers[e.type] != NULL) + else if ((e.type < LASTEvent) && (xev_handlers[e.type] != NULL)) (*xev_handlers[e.type])(&e); } } -- cgit 1.4.1 From bf43b6241405dffa02ae15bf4ec1d55f84ea52aa Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 8 Mar 2019 14:48:02 +0000 Subject: [keypress event] turns out we've been checking the wrong window for a matching client thus always falling back to client_current(); while the current client is problaby right in most cases, use event's subwindow (not window) to find the client. Bail early if this event came to us from a screen we don't manage. This is result of us grabing all keybindings off the root window instead of selectively. --- xevents.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/xevents.c b/xevents.c index cdbfdfc..bbf8722 100644 --- a/xevents.c +++ b/xevents.c @@ -292,7 +292,11 @@ xev_handle_keypress(XEvent *ee) KeySym keysym, skeysym; unsigned int modshift; - LOG_DEBUG3("window: 0x%lx", e->window); + LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx ", + e->root, e->window, e->subwindow); + + if ((sc = screen_find(e->root)) == NULL) + return; keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0); skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1); @@ -311,20 +315,17 @@ xev_handle_keypress(XEvent *ee) if (kb->press.keysym == ((modshift == 0) ? keysym : skeysym)) break; } - if (kb == NULL) return; kb->cargs->xev = CWM_XEV_KEY; switch (kb->context) { case CWM_CONTEXT_CC: - if (((cc = client_find(e->window)) == NULL) && - ((cc = client_current(NULL)) == NULL)) + if (((cc = client_find(e->subwindow)) == NULL) && + ((cc = client_current(sc)) == NULL)) return; (*kb->callback)(cc, kb->cargs); break; case CWM_CONTEXT_SC: - if ((sc = screen_find(e->window)) == NULL) - return; (*kb->callback)(sc, kb->cargs); break; case CWM_CONTEXT_NONE: -- cgit 1.4.1 From eab4b7e4b5f026d6859d92a18e1630197bd602e0 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 8 Mar 2019 15:04:39 +0000 Subject: extend verbose logging for key/button events --- xevents.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/xevents.c b/xevents.c index bbf8722..cb2cfee 100644 --- a/xevents.c +++ b/xevents.c @@ -234,7 +234,8 @@ xev_handle_buttonpress(XEvent *ee) struct screen_ctx *sc; struct bind_ctx *mb; - LOG_DEBUG3("window: 0x%lx", e->window); + LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx", + e->root, e->window, e->subwindow); e->state &= ~IGNOREMODMASK; @@ -272,7 +273,8 @@ xev_handle_buttonrelease(XEvent *ee) XButtonEvent *e = &ee->xbutton; struct client_ctx *cc; - LOG_DEBUG3("window: 0x%lx", ee->xbutton.window); + LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx", + e->root, e->window, e->subwindow); if ((cc = client_find(e->window)) != NULL) { if (cc->flags & (CLIENT_ACTIVE | CLIENT_HIGHLIGHT)) { @@ -292,7 +294,7 @@ xev_handle_keypress(XEvent *ee) KeySym keysym, skeysym; unsigned int modshift; - LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx ", + LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx", e->root, e->window, e->subwindow); if ((sc = screen_find(e->root)) == NULL) @@ -346,7 +348,8 @@ xev_handle_keyrelease(XEvent *ee) KeySym keysym; unsigned int i; - LOG_DEBUG3("window: 0x%lx", e->window); + LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx", + e->root, e->window, e->subwindow); if ((sc = screen_find(e->root)) == NULL) return; -- cgit 1.4.1 From 4470a247c8d30f0c7acdc44905feecd0ed3edf10 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 8 Mar 2019 17:40:43 +0000 Subject: Similar to keypress event, fetch the screen from the event root window in the buttonpress handler; bail if we don't manage the screen. Allows us to find the current client based on the screen/event root. --- xevents.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/xevents.c b/xevents.c index cb2cfee..c35e87a 100644 --- a/xevents.c +++ b/xevents.c @@ -237,28 +237,26 @@ xev_handle_buttonpress(XEvent *ee) LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx", e->root, e->window, e->subwindow); + if ((sc = screen_find(e->root)) == NULL) + return; + e->state &= ~IGNOREMODMASK; TAILQ_FOREACH(mb, &Conf.mousebindq, entry) { if (e->button == mb->press.button && e->state == mb->modmask) break; } - if (mb == NULL) return; mb->cargs->xev = CWM_XEV_BTN; switch (mb->context) { case CWM_CONTEXT_CC: if (((cc = client_find(e->window)) == NULL) && - ((cc = client_current(NULL)) == NULL)) + ((cc = client_current(sc)) == NULL)) return; (*mb->callback)(cc, mb->cargs); break; case CWM_CONTEXT_SC: - if (e->window != e->root) - return; - if ((sc = screen_find(e->window)) == NULL) - return; (*mb->callback)(sc, mb->cargs); break; case CWM_CONTEXT_NONE: -- cgit 1.4.1 From 5071baa2aad12f8de2c9591fdf753ff4edec5df7 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 8 Mar 2019 20:33:30 +0000 Subject: Print window id in hex; while here, remove unnecessary newline. --- screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/screen.c b/screen.c index eb84a17..d81a134 100644 --- a/screen.c +++ b/screen.c @@ -103,7 +103,7 @@ screen_find(Window win) if (sc->rootwin == win) return(sc); } - warnx("%s: failure win 0x%lu\n", __func__, win); + warnx("%s: failure win 0x%lx", __func__, win); return(NULL); } -- cgit 1.4.1 From 5bc2098c6f9f1e95462e43adcd2922d7730c0b60 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 10 Mar 2019 20:38:28 +0000 Subject: Find the managed screen from the parent window for client_current(). --- xevents.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/xevents.c b/xevents.c index c35e87a..15f7e10 100644 --- a/xevents.c +++ b/xevents.c @@ -75,11 +75,15 @@ static void xev_handle_maprequest(XEvent *ee) { XMapRequestEvent *e = &ee->xmaprequest; - struct client_ctx *cc = NULL, *old_cc; + struct screen_ctx *sc; + struct client_ctx *cc, *old_cc; - LOG_DEBUG3("window: 0x%lx", e->window); + LOG_DEBUG3("parent: 0x%lx window: 0x%lx", e->parent, e->window); + + if ((sc = screen_find(e->parent)) == NULL) + return; - if ((old_cc = client_current(NULL)) != NULL) + if ((old_cc = client_current(sc)) != NULL) client_ptrsave(old_cc); if ((cc = client_find(e->window)) == NULL) @@ -355,7 +359,7 @@ xev_handle_keyrelease(XEvent *ee) keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0); for (i = 0; i < nitems(modkeys); i++) { if (keysym == modkeys[i]) { - if ((cc = client_current(NULL)) != NULL) { + if ((cc = client_current(sc)) != NULL) { if (sc->cycling) { sc->cycling = 0; client_mtf(cc); -- cgit 1.4.1 From e55c0d48fab32daba096b61d0b63b2fcbfa49ed7 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 10 Mar 2019 22:53:11 +0000 Subject: use screen_find() for xrandr crtc changes --- xevents.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/xevents.c b/xevents.c index 15f7e10..c5a2aad 100644 --- a/xevents.c +++ b/xevents.c @@ -431,20 +431,17 @@ xev_handle_clientmessage(XEvent *ee) static void xev_handle_randr(XEvent *ee) { - XRRScreenChangeNotifyEvent *rev = (XRRScreenChangeNotifyEvent *)ee; + XRRScreenChangeNotifyEvent *e = (XRRScreenChangeNotifyEvent *)ee; struct screen_ctx *sc; - int i; - LOG_DEBUG3("new size: %d/%d", rev->width, rev->height); + LOG_DEBUG3("size: %d/%d", e->width, e->height); - i = XRRRootToScreen(X_Dpy, rev->root); - TAILQ_FOREACH(sc, &Screenq, entry) { - if (sc->which == i) { - XRRUpdateConfiguration(ee); - screen_update_geometry(sc); - screen_assert_clients_within(sc); - } - } + if ((sc = screen_find(e->root)) == NULL) + return; + + XRRUpdateConfiguration(ee); + screen_update_geometry(sc); + screen_assert_clients_within(sc); } /* -- cgit 1.4.1 From 9a7528f5b99bd234f724aa229cbf75fb6a813282 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 11 Mar 2019 15:25:46 +0000 Subject: Check the atom type on propertynotify before iterating. --- xevents.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xevents.c b/xevents.c index c5a2aad..4dfef72 100644 --- a/xevents.c +++ b/xevents.c @@ -210,9 +210,11 @@ xev_handle_propertynotify(XEvent *ee) /* do nothing */ break; } - } else if ((sc = screen_find(e->window)) != NULL) { - if (e->atom == ewmh[_NET_DESKTOP_NAMES]) - xu_ewmh_net_desktop_names(sc); + } else { + if (e->atom == ewmh[_NET_DESKTOP_NAMES]) { + if ((sc = screen_find(e->window)) != NULL) + xu_ewmh_net_desktop_names(sc); + } } } -- cgit 1.4.1