summary refs log tree commit diff
path: root/xutil.c
diff options
context:
space:
mode:
authorokan <okan>2012-07-03 13:49:03 +0000
committerokan <okan>2012-07-03 13:49:03 +0000
commitf98e123bfccf2ededa1cd22dbf88bedc5e4a2ccf (patch)
tree358597219d1cfc691fad23f2062db1e613bb5e5c /xutil.c
parent956c47dbeb5bf55913340d80bd0f4423a422a1e8 (diff)
downloadcwm-f98e123bfccf2ededa1cd22dbf88bedc5e4a2ccf.tar.gz
cwm-f98e123bfccf2ededa1cd22dbf88bedc5e4a2ccf.tar.xz
cwm-f98e123bfccf2ededa1cd22dbf88bedc5e4a2ccf.zip
re-implement atom handing; makes for a normalized and more consistent
separation between cwm and ewmh.  seen by a few.
Diffstat (limited to 'xutil.c')
-rw-r--r--xutil.c206
1 files changed, 167 insertions, 39 deletions
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