diff --git a/calmwm.c b/calmwm.c index c809695..4111d95 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; @@ -159,8 +167,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); @@ -221,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/calmwm.h b/calmwm.h index 01b560a..d15f39d 100644 --- a/calmwm.h +++ b/calmwm.h @@ -68,9 +68,6 @@ size_t strlcpy(char *, const char *, size_t); #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 */ @@ -145,7 +142,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; @@ -211,7 +207,6 @@ struct group_ctx { struct screen_ctx *sc; char *name; int num; - struct client_q clientq; }; TAILQ_HEAD(group_q, group_ctx); @@ -250,7 +245,7 @@ struct screen_ctx { struct { Window win; XftDraw *xftdraw; - } menu; + } prop; XftColor xftcolor[CWM_COLOR_NITEMS]; XftFont *xftfont; }; @@ -420,7 +415,7 @@ 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 *); @@ -456,25 +451,24 @@ 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 *); -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); +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); 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 *); @@ -506,6 +500,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 *); @@ -532,7 +532,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 *); @@ -544,10 +544,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 *), @@ -577,6 +573,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); @@ -589,13 +586,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/client.c b/client.c index d7d34c4..39df4d3 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) { @@ -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); @@ -221,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); } @@ -238,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); } @@ -527,25 +531,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); @@ -691,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) : @@ -972,12 +967,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; @@ -985,7 +979,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 || @@ -1014,7 +1010,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 || @@ -1040,12 +1038,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; @@ -1053,7 +1050,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 || @@ -1082,7 +1081,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/conf.c b/conf.c index 22d4fc5..e42c18f 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 */ @@ -124,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) }, @@ -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); @@ -478,30 +493,28 @@ 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]); } } - 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); } +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/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 diff --git a/group.c b/group.c index 3088ae7..164ef44 100644 --- a/group.c +++ b/group.c @@ -37,37 +37,30 @@ 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) { - 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) { - if (!(cc->flags & CLIENT_STICKY)) + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; + if (!(cc->flags & CLIENT_STICKY) && + !(cc->flags & CLIENT_HIDDEN)) client_hide(cc); } } @@ -75,13 +68,16 @@ 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) { - if (!(cc->flags & CLIENT_STICKY)) - client_unhide(cc); + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; + if (!(cc->flags & CLIENT_STICKY) && + (cc->flags & CLIENT_HIDDEN)) + client_show(cc); } - group_restack(gc); group_setactive(gc); } @@ -89,19 +85,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++; } @@ -122,16 +123,14 @@ 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); - TAILQ_INSERT_TAIL(&sc->groupq, gc, entry); if (num == 1) @@ -154,19 +153,15 @@ 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) - 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 @@ -175,23 +170,25 @@ 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); } 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); } @@ -201,46 +198,23 @@ 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); } return(1); } -void -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) - 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); - } -} - void 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); @@ -249,19 +223,48 @@ group_only(struct screen_ctx *sc, int idx) } } +void +group_toggle(struct screen_ctx *sc, int idx) +{ + struct group_ctx *gc; + + TAILQ_FOREACH(gc, &sc->groupq, entry) { + if (gc->num == idx) { + if (group_holds_only_hidden(gc)) + group_show(gc); + else + group_hide(gc); + } + } +} + +void +group_toggle_all(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; +} + void 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) + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->gc != gc) + continue; client_close(cc); + } } } } @@ -286,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; @@ -318,20 +320,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 3da28c3..bb5ac37 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -169,8 +169,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) { @@ -193,8 +193,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; @@ -203,8 +203,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); } @@ -258,7 +257,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) { @@ -272,7 +272,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: @@ -282,8 +282,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. */ @@ -431,18 +430,24 @@ kbfunc_client_movetogroup(void *ctx, struct cargs *cargs) group_movetogroup(ctx, cargs->flag); } -void -kbfunc_group_toggle(void *ctx, struct cargs *cargs) -{ - group_hidetoggle(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_toggle(ctx, cargs->flag); +} + +void +kbfunc_group_toggle_all(void *ctx, struct cargs *cargs) +{ + group_toggle_all(ctx); +} + void kbfunc_group_close(void *ctx, struct cargs *cargs) { @@ -455,12 +460,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) { @@ -474,7 +473,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/menu.c b/menu.c index c7d2c93..2d6ba27 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 2c0b8c1..7565703 100644 --- a/screen.c +++ b/screen.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,6 @@ screen_init(int which) Window *wins, w0, w1, active = None; XSetWindowAttributes rootattr; unsigned int nwins, w; - int i; sc = xmalloc(sizeof(*sc)); @@ -60,14 +60,11 @@ screen_init(int which) xu_ewmh_net_supported(sc); xu_ewmh_net_supported_wm_check(sc); + conf_group(sc); screen_update_geometry(sc); - for (i = 0; i < Conf.ngroups; i++) - group_init(sc, i); - 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); @@ -106,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); } @@ -217,6 +214,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); } @@ -253,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); +} diff --git a/xevents.c b/xevents.c index 8b29315..c8d85d4 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 ((old_cc = client_current()) != NULL) + if ((sc = screen_find(e->parent)) == NULL) + return; + + if ((old_cc = client_current(sc)) != NULL) client_ptrsave(old_cc); if ((cc = client_find(e->window)) == NULL) @@ -207,11 +211,9 @@ xev_handle_propertynotify(XEvent *ee) 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); - } + if (e->atom == ewmh[_NET_DESKTOP_NAMES]) { + if ((sc = screen_find(e->window)) != NULL) + xu_ewmh_net_desktop_names(sc); } } } @@ -238,7 +240,11 @@ 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); + + if ((sc = screen_find(e->root)) == NULL) + return; e->state &= ~IGNOREMODMASK; @@ -246,22 +252,17 @@ xev_handle_buttonpress(XEvent *ee) 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) + ((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: @@ -276,7 +277,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)) { @@ -296,7 +298,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); @@ -315,20 +321,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) + 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: @@ -349,7 +352,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; @@ -357,7 +361,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(sc)) != NULL) { if (sc->cycling) { sc->cycling = 0; client_mtf(cc); @@ -393,7 +397,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); @@ -408,7 +412,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 +423,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]); } } } @@ -425,20 +433,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); } /* @@ -479,9 +484,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); } } diff --git a/xutil.c b/xutil.c index 1b604c7..5445357 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;