From f98e123bfccf2ededa1cd22dbf88bedc5e4a2ccf Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 3 Jul 2012 13:49:03 +0000 Subject: re-implement atom handing; makes for a normalized and more consistent separation between cwm and ewmh. seen by a few. --- xutil.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 167 insertions(+), 39 deletions(-) (limited to 'xutil.c') diff --git a/xutil.c b/xutil.c index 030584b..7f0c4c4 100644 --- a/xutil.c +++ b/xutil.c @@ -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 -- cgit 1.4.1