diff options
-rw-r--r-- | calmwm.h | 76 | ||||
-rw-r--r-- | client.c | 48 | ||||
-rw-r--r-- | group.c | 57 | ||||
-rw-r--r-- | screen.c | 24 | ||||
-rw-r--r-- | xevents.c | 4 | ||||
-rw-r--r-- | xutil.c | 208 |
6 files changed, 253 insertions, 164 deletions
@@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $OpenBSD: calmwm.h,v 1.146 2012/05/16 01:17:14 okan Exp $ + * $OpenBSD: calmwm.h,v 1.147 2012/07/03 13:49:03 okan Exp $ */ #ifndef _CALMWM_H_ @@ -466,6 +466,19 @@ void xu_setstate(struct client_ctx *, int); 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_workarea(struct screen_ctx *); +void xu_ewmh_net_client_list(struct screen_ctx *); +void xu_ewmh_net_active_window(struct screen_ctx *, Window); +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_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 *, unsigned char *, int); + +void xu_ewmh_net_wm_desktop(struct client_ctx *); + void u_exec(char *); void u_spawn(char *); @@ -490,34 +503,37 @@ extern struct conf Conf; extern int HasXinerama, HasRandr, Randr_ev; -#define WM_STATE cwm_atoms[0] -#define WM_DELETE_WINDOW cwm_atoms[1] -#define WM_TAKE_FOCUS cwm_atoms[2] -#define WM_PROTOCOLS cwm_atoms[3] -#define _MOTIF_WM_HINTS cwm_atoms[4] -#define UTF8_STRING cwm_atoms[5] -/* - * please make all hints below this point netwm hints, starting with - * _NET_SUPPORTED. If you change other hints make sure you update - * CWM_NETWM_START - */ -#define _NET_SUPPORTED cwm_atoms[6] -#define _NET_SUPPORTING_WM_CHECK cwm_atoms[7] -#define _NET_WM_NAME cwm_atoms[8] -#define _NET_ACTIVE_WINDOW cwm_atoms[9] -#define _NET_CLIENT_LIST cwm_atoms[10] -#define _NET_NUMBER_OF_DESKTOPS cwm_atoms[11] -#define _NET_CURRENT_DESKTOP cwm_atoms[12] -#define _NET_DESKTOP_VIEWPORT cwm_atoms[13] -#define _NET_DESKTOP_GEOMETRY cwm_atoms[14] -#define _NET_VIRTUAL_ROOTS cwm_atoms[15] -#define _NET_SHOWING_DESKTOP cwm_atoms[16] -#define _NET_DESKTOP_NAMES cwm_atoms[17] -#define _NET_WM_DESKTOP cwm_atoms[18] -#define _NET_WORKAREA cwm_atoms[19] -#define CWM_NO_ATOMS 20 -#define CWM_NETWM_START 6 - -extern Atom cwm_atoms[CWM_NO_ATOMS]; +enum { + WM_STATE, + WM_DELETE_WINDOW, + WM_TAKE_FOCUS, + WM_PROTOCOLS, + _MOTIF_WM_HINTS, + UTF8_STRING, + CWMH_NITEMS +}; +enum { + _NET_SUPPORTED, + _NET_SUPPORTING_WM_CHECK, + _NET_ACTIVE_WINDOW, + _NET_CLIENT_LIST, + _NET_NUMBER_OF_DESKTOPS, + _NET_CURRENT_DESKTOP, + _NET_DESKTOP_VIEWPORT, + _NET_DESKTOP_GEOMETRY, + _NET_VIRTUAL_ROOTS, + _NET_SHOWING_DESKTOP, + _NET_DESKTOP_NAMES, + _NET_WORKAREA, + _NET_WM_NAME, + _NET_WM_DESKTOP, + EWMH_NITEMS +}; +struct atom_ctx { + char *name; + Atom atom; +}; +extern struct atom_ctx cwmh[CWMH_NITEMS]; +extern struct atom_ctx ewmh[EWMH_NITEMS]; #endif /* _CALMWM_H_ */ @@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $OpenBSD: client.c,v 1.94 2012/05/16 01:09:17 okan Exp $ + * $OpenBSD: client.c,v 1.95 2012/07/03 13:49:03 okan Exp $ */ #include <sys/param.h> @@ -126,9 +126,8 @@ client_new(Window win, struct screen_ctx *sc, int mapped) TAILQ_INSERT_TAIL(&sc->mruq, cc, mru_entry); TAILQ_INSERT_TAIL(&Clientq, cc, entry); - /* append to the client list */ - XChangeProperty(X_Dpy, sc->rootwin, _NET_CLIENT_LIST, XA_WINDOW, 32, - PropModeAppend, (unsigned char *)&cc->win, 1); + + xu_ewmh_net_client_list(sc); client_gethints(cc); client_update(cc); @@ -143,10 +142,7 @@ void client_delete(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - struct client_ctx *tcc; struct winname *wn; - Window *winlist; - int i, j; group_client_delete(cc); @@ -159,23 +155,8 @@ client_delete(struct client_ctx *cc) TAILQ_REMOVE(&sc->mruq, cc, mru_entry); TAILQ_REMOVE(&Clientq, cc, entry); - /* - * Sadly we can't remove just one entry from a property, so we must - * redo the whole thing from scratch. this is the stupid way, the other - * way incurs many roundtrips to the server. - */ - i = j = 0; - TAILQ_FOREACH(tcc, &Clientq, entry) - i++; - if (i > 0) { - winlist = xmalloc(i * sizeof(*winlist)); - TAILQ_FOREACH(tcc, &Clientq, entry) - winlist[j++] = tcc->win; - XChangeProperty(X_Dpy, sc->rootwin, _NET_CLIENT_LIST, - XA_WINDOW, 32, PropModeReplace, - (unsigned char *)winlist, i); - xfree(winlist); - } + + xu_ewmh_net_client_list(sc); if (_curcc == cc) client_none(sc); @@ -236,9 +217,7 @@ client_setactive(struct client_ctx *cc, int fg) if (fg && _curcc != cc) { client_setactive(NULL, 0); _curcc = cc; - XChangeProperty(X_Dpy, sc->rootwin, _NET_ACTIVE_WINDOW, - XA_WINDOW, 32, PropModeReplace, - (unsigned char *)&cc->win, 1); + xu_ewmh_net_active_window(sc, cc->win); } cc->active = fg; @@ -253,8 +232,8 @@ client_none(struct screen_ctx *sc) { Window none = None; - XChangeProperty(X_Dpy, sc->rootwin, _NET_ACTIVE_WINDOW, - XA_WINDOW, 32, PropModeReplace, (unsigned char *)&none, 1); + xu_ewmh_net_active_window(sc, none); + _curcc = NULL; } @@ -545,9 +524,9 @@ client_update(struct client_ctx *cc) return; for (i = 0; i < n; i++) - if (p[i] == WM_DELETE_WINDOW) + if (p[i] == cwmh[WM_DELETE_WINDOW].atom) cc->xproto |= CLIENT_PROTO_DELETE; - else if (p[i] == WM_TAKE_FOCUS) + else if (p[i] == cwmh[WM_TAKE_FOCUS].atom) cc->xproto |= CLIENT_PROTO_TAKEFOCUS; XFree(p); @@ -557,7 +536,8 @@ void client_send_delete(struct client_ctx *cc) { if (cc->xproto & CLIENT_PROTO_DELETE) - xu_sendmsg(cc->win, WM_PROTOCOLS, WM_DELETE_WINDOW); + xu_sendmsg(cc->win, + cwmh[WM_PROTOCOLS].atom, cwmh[WM_DELETE_WINDOW].atom); else XKillClient(X_Dpy, cc->win); } @@ -568,7 +548,7 @@ client_setname(struct client_ctx *cc) struct winname *wn; char *newname; - if (!xu_getstrprop(cc->win, _NET_WM_NAME, &newname)) + if (!xu_getstrprop(cc->win, ewmh[_NET_WM_NAME].atom, &newname)) if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname)) newname = emptystring; @@ -868,7 +848,7 @@ client_gethints(struct client_ctx *cc) cc->app_class = xch.res_class; } - if (xu_getprop(cc->win, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, + if (xu_getprop(cc->win, cwmh[_MOTIF_WM_HINTS].atom, _MOTIF_WM_HINTS, PROP_MWM_HINTS_ELEMENTS, (u_char **)&mwmh) == MWM_NUMHINTS) if (mwmh->flags & MWM_HINTS_DECORATIONS && !(mwmh->decorations & MWM_DECOR_ALL) && @@ -16,7 +16,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $OpenBSD: group.c,v 1.57 2012/05/16 21:57:21 okan Exp $ + * $OpenBSD: group.c,v 1.58 2012/07/03 13:49:03 okan Exp $ */ #include <sys/param.h> @@ -48,38 +48,31 @@ const char *shortcut_to_name[] = { static void group_add(struct group_ctx *gc, struct client_ctx *cc) { - long no; if (cc == NULL || gc == NULL) errx(1, "group_add: a ctx is NULL"); - no = gc->shortcut - 1; - if (cc->group == gc) return; if (cc->group != NULL) TAILQ_REMOVE(&cc->group->clients, cc, group_entry); - XChangeProperty(X_Dpy, cc->win, _NET_WM_DESKTOP, XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)&no, 1); - TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry); cc->group = gc; + + xu_ewmh_net_wm_desktop(cc); } static void group_remove(struct client_ctx *cc) { - long no = 0xffffffff; - if (cc == NULL || cc->group == NULL) errx(1, "group_remove: a ctx is NULL"); - XChangeProperty(X_Dpy, cc->win, _NET_WM_DESKTOP, XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)&no, 1); - TAILQ_REMOVE(&cc->group->clients, cc, group_entry); cc->group = NULL; + + xu_ewmh_net_wm_desktop(cc); } static void @@ -146,8 +139,6 @@ void group_init(struct screen_ctx *sc) { int i; - long viewports[2] = {0, 0}; - long ndesks = CALMWM_NGROUPS, zero = 0; TAILQ_INIT(&sc->groupq); sc->group_hideall = 0; @@ -164,23 +155,11 @@ group_init(struct screen_ctx *sc) TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry); } - /* we don't support large desktops, so this is always (0, 0) */ - XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_VIEWPORT, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2); - XChangeProperty(X_Dpy, sc->rootwin, _NET_NUMBER_OF_DESKTOPS, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1); - /* - * we don't use virtual roots, so make sure it's not there from a - * previous wm. - */ - XDeleteProperty(X_Dpy, sc->rootwin, _NET_VIRTUAL_ROOTS); - /* - * We don't really have a ``showing desktop'' mode, so this is zero - * always. XXX Note that when we hide all groups, or when all groups - * are hidden we could technically set this later on. - */ - XChangeProperty(X_Dpy, sc->rootwin, _NET_SHOWING_DESKTOP, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1); + xu_ewmh_net_wm_desktop_viewport(sc); + xu_ewmh_net_wm_number_of_desktops(sc); + xu_ewmh_net_showing_desktop(sc); + xu_ewmh_net_virtual_roots(sc); + group_setactive(sc, 0); } @@ -209,8 +188,8 @@ static void group_setactive(struct screen_ctx *sc, long idx) { sc->group_active = &sc->groups[idx]; - XChangeProperty(X_Dpy, sc->rootwin, _NET_CURRENT_DESKTOP, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1); + + xu_ewmh_net_current_desktop(sc, idx); } void @@ -439,8 +418,8 @@ group_autogroup(struct client_ctx *cc) if (cc->app_class == NULL || cc->app_name == NULL) return; - if (xu_getprop(cc->win, _NET_WM_DESKTOP, XA_CARDINAL, - 1, (unsigned char **)&grpno) > 0) { + if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP].atom, + XA_CARDINAL, 1, (unsigned char **)&grpno) > 0) { if (*grpno == 0xffffffff) no = 0; else if (*grpno > CALMWM_NGROUPS || *grpno < 0) @@ -483,8 +462,9 @@ group_update_names(struct screen_ctx *sc) int format_ret, i = 0, nstrings = 0, n, setnames = 0; unsigned long bytes_after, num_ret; - if (XGetWindowProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES, 0, - 0xffffff, False, UTF8_STRING, &type_ret, &format_ret, + if (XGetWindowProperty(X_Dpy, sc->rootwin, + ewmh[_NET_DESKTOP_NAMES].atom, 0, 0xffffff, False, + cwmh[UTF8_STRING].atom, &type_ret, &format_ret, &num_ret, &bytes_after, &prop_ret) == Success && prop_ret != NULL && format_ret == 8) { /* failure, just set defaults */ @@ -545,6 +525,5 @@ group_set_names(struct screen_ctx *sc) q += slen; } - XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES, - UTF8_STRING, 8, PropModeReplace, p, len); + xu_ewmh_net_desktop_names(sc, p, len); } @@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $OpenBSD: screen.c,v 1.28 2011/05/11 13:53:51 okan Exp $ + * $OpenBSD: screen.c,v 1.29 2012/07/03 13:49:03 okan Exp $ */ #include <sys/param.h> @@ -111,23 +111,9 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y) void screen_update_geometry(struct screen_ctx *sc, int width, int height) { - long geom[2], workareas[CALMWM_NGROUPS][4]; - int i; - - sc->xmax = geom[0] = width; - sc->ymax = geom[1] = height; - XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_GEOMETRY, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2); - - /* x, y, width, height. */ - for (i = 0; i < CALMWM_NGROUPS; i++) { - workareas[i][0] = sc->gap.left; - workareas[i][1] = sc->gap.top; - workareas[i][2] = width - (sc->gap.left + sc->gap.right); - workareas[i][3] = height - (sc->gap.top + sc->gap.bottom); - } + sc->xmax = width; + sc->ymax = height; - XChangeProperty(X_Dpy, sc->rootwin, _NET_WORKAREA, - XA_CARDINAL, 32, PropModeReplace, - (unsigned char *)workareas, CALMWM_NGROUPS * 4); + xu_ewmh_net_desktop_geometry(sc); + xu_ewmh_net_workarea(sc); } @@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $OpenBSD: xevents.c,v 1.60 2012/05/16 21:57:21 okan Exp $ + * $OpenBSD: xevents.c,v 1.61 2012/07/03 13:49:03 okan Exp $ */ /* @@ -207,7 +207,7 @@ xev_handle_propertynotify(XEvent *ee) goto test; return; test: - if (e->atom == _NET_DESKTOP_NAMES) + if (e->atom == ewmh[_NET_DESKTOP_NAMES].atom) group_update_names(sc); } } @@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $OpenBSD: xutil.c,v 1.40 2012/05/16 01:17:14 okan Exp $ + * $OpenBSD: xutil.c,v 1.41 2012/07/03 13:49:03 okan Exp $ */ #include <sys/param.h> @@ -207,7 +207,8 @@ xu_getstate(struct client_ctx *cc, int *state) { long *p = NULL; - if (xu_getprop(cc->win, WM_STATE, WM_STATE, 2L, (u_char **)&p) <= 0) + if (xu_getprop(cc->win, cwmh[WM_STATE].atom, WM_STATE, 2L, + (u_char **)&p) <= 0) return (-1); *state = (int)*p; @@ -225,67 +226,194 @@ xu_setstate(struct client_ctx *cc, int state) dat[1] = None; cc->state = state; - XChangeProperty(X_Dpy, cc->win, WM_STATE, WM_STATE, 32, + XChangeProperty(X_Dpy, cc->win, + cwmh[WM_STATE].atom, WM_STATE, 32, PropModeReplace, (unsigned char *)dat, 2); } -Atom cwm_atoms[CWM_NO_ATOMS]; -char *atoms[CWM_NO_ATOMS] = { - "WM_STATE", - "WM_DELETE_WINDOW", - "WM_TAKE_FOCUS", - "WM_PROTOCOLS", - "_MOTIF_WM_HINTS", - "UTF8_STRING", - "_NET_SUPPORTED", - "_NET_SUPPORTING_WM_CHECK", - "_NET_WM_NAME", - "_NET_ACTIVE_WINDOW", - "_NET_CLIENT_LIST", - "_NET_NUMBER_OF_DESKTOPS", - "_NET_CURRENT_DESKTOP", - "_NET_DESKTOP_VIEWPORT", - "_NET_DESKTOP_GEOMETRY", - "_NET_VIRTUAL_ROOTS", - "_NET_SHOWING_DESKTOP", - "_NET_DESKTOP_NAMES", - "_NET_WM_DESKTOP", - "_NET_WORKAREA", +struct atom_ctx cwmh[CWMH_NITEMS] = { + {"WM_STATE", None}, + {"WM_DELETE_WINDOW", None}, + {"WM_TAKE_FOCUS", None}, + {"WM_PROTOCOLS", None}, + {"_MOTIF_WM_HINTS", None}, + {"UTF8_STRING", None}, +}; +struct atom_ctx ewmh[EWMH_NITEMS] = { + {"_NET_SUPPORTED", None}, + {"_NET_SUPPORTING_WM_CHECK", None}, + {"_NET_ACTIVE_WINDOW", None}, + {"_NET_CLIENT_LIST", None}, + {"_NET_NUMBER_OF_DESKTOPS", None}, + {"_NET_CURRENT_DESKTOP", None}, + {"_NET_DESKTOP_VIEWPORT", None}, + {"_NET_DESKTOP_GEOMETRY", None}, + {"_NET_VIRTUAL_ROOTS", None}, + {"_NET_SHOWING_DESKTOP", None}, + {"_NET_DESKTOP_NAMES", None}, + {"_NET_WORKAREA", None}, + {"_NET_WM_NAME", None}, + {"_NET_WM_DESKTOP", None}, }; void xu_getatoms(void) { - XInternAtoms(X_Dpy, atoms, CWM_NO_ATOMS, False, cwm_atoms); + int i; + + for (i = 0; i < nitems(cwmh); i++) + cwmh[i].atom = XInternAtom(X_Dpy, cwmh[i].name, False); + for (i = 0; i < nitems(ewmh); i++) + ewmh[i].atom = XInternAtom(X_Dpy, ewmh[i].name, False); } +/* Root Window Properties */ void xu_ewmh_net_supported(struct screen_ctx *sc) { - XChangeProperty(X_Dpy, sc->rootwin, _NET_SUPPORTED, XA_ATOM, 32, - PropModeReplace, (unsigned char *)&_NET_SUPPORTED, - CWM_NO_ATOMS - CWM_NETWM_START); + Atom atom[EWMH_NITEMS]; + int i; + + for (i = 0; i < nitems(ewmh); i++) + atom[i] = ewmh[i].atom; + + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTED].atom, + XA_ATOM, 32, PropModeReplace, (unsigned char *)atom, EWMH_NITEMS); } -/* - * The netwm spec says that to prove that the hint is not stale, one - * must provide _NET_SUPPORTING_WM_CHECK containing a window created by - * the root window. The property must be set on the root window and the - * window itself. This child window also must have _NET_WM_NAME set with - * the window manager name. - */ void xu_ewmh_net_supported_wm_check(struct screen_ctx *sc) { Window w; w = XCreateSimpleWindow(X_Dpy, sc->rootwin, -1, -1, 1, 1, 0, 0, 0); - XChangeProperty(X_Dpy, sc->rootwin, _NET_SUPPORTING_WM_CHECK, + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTING_WM_CHECK].atom, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); - XChangeProperty(X_Dpy, w, _NET_SUPPORTING_WM_CHECK, + XChangeProperty(X_Dpy, w, ewmh[_NET_SUPPORTING_WM_CHECK].atom, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); - XChangeProperty(X_Dpy, w, _NET_WM_NAME, UTF8_STRING, - 8, PropModeReplace, WMNAME, strlen(WMNAME)); + XChangeProperty(X_Dpy, w, ewmh[_NET_WM_NAME].atom, + XA_WM_NAME, 8, PropModeReplace, WMNAME, strlen(WMNAME)); +} + +void +xu_ewmh_net_desktop_geometry(struct screen_ctx *sc) +{ + long geom[2] = { sc->xmax, sc->ymax }; + + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_GEOMETRY].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2); +} + +void +xu_ewmh_net_workarea(struct screen_ctx *sc) +{ + long workareas[CALMWM_NGROUPS][4]; + int i; + + for (i = 0; i < CALMWM_NGROUPS; i++) { + workareas[i][0] = sc->gap.left; + workareas[i][1] = sc->gap.top; + workareas[i][2] = sc->xmax - (sc->gap.left + sc->gap.right); + workareas[i][3] = sc->ymax - (sc->gap.top + sc->gap.bottom); + } + + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_WORKAREA].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)workareas, + CALMWM_NGROUPS * 4); +} + +void +xu_ewmh_net_client_list(struct screen_ctx *sc) +{ + struct client_ctx *cc; + Window *winlist; + int i = 0, j = 0; + + TAILQ_FOREACH(cc, &Clientq, entry) + i++; + if (i == 0) + return; + + winlist = xmalloc(i * sizeof(*winlist)); + TAILQ_FOREACH(cc, &Clientq, entry) + winlist[j++] = cc->win; + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CLIENT_LIST].atom, + XA_WINDOW, 32, PropModeReplace, (unsigned char *)winlist, i); + xfree(winlist); +} + +void +xu_ewmh_net_active_window(struct screen_ctx *sc, Window w) +{ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_ACTIVE_WINDOW].atom, + XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); +} + +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].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2); +} + +void +xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *sc) +{ + long ndesks = CALMWM_NGROUPS; + + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_NUMBER_OF_DESKTOPS].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1); +} + +void +xu_ewmh_net_showing_desktop(struct screen_ctx *sc) +{ + long zero = 0; + + /* We don't support `showing desktop' mode, so this is zero. + * Note that when we hide all groups, or when all groups are + * hidden we could technically set this later on. + */ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SHOWING_DESKTOP].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1); +} + +void +xu_ewmh_net_virtual_roots(struct screen_ctx *sc) +{ + /* We don't support virtual roots, so delete if set by previous wm. */ + XDeleteProperty(X_Dpy, sc->rootwin, ewmh[_NET_VIRTUAL_ROOTS].atom); +} + +void +xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx) +{ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CURRENT_DESKTOP].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1); +} + +void +xu_ewmh_net_desktop_names(struct screen_ctx *sc, unsigned char *data, int n) +{ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES].atom, + cwmh[UTF8_STRING].atom, 8, PropModeReplace, data, n); +} + +/* Application Window Properties */ +void +xu_ewmh_net_wm_desktop(struct client_ctx *cc) +{ + struct group_ctx *gc = cc->group; + long no = 0xffffffff; + + if (gc) + no = gc->shortcut - 1; + + XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1); } unsigned long |