aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calmwm.h76
-rw-r--r--client.c48
-rw-r--r--group.c57
-rw-r--r--screen.c24
-rw-r--r--xevents.c4
-rw-r--r--xutil.c208
6 files changed, 253 insertions, 164 deletions
diff --git a/calmwm.h b/calmwm.h
index e8f340f..4c6c90f 100644
--- a/calmwm.h
+++ b/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: 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_ */
diff --git a/client.c b/client.c
index 89495c3..7dbe076 100644
--- a/client.c
+++ b/client.c
@@ -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) &&
diff --git a/group.c b/group.c
index ba84956..0119cd2 100644
--- a/group.c
+++ b/group.c
@@ -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);
}
diff --git a/screen.c b/screen.c
index d33ed53..815acb5 100644
--- a/screen.c
+++ b/screen.c
@@ -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);
}
diff --git a/xevents.c b/xevents.c
index 73e5df0..56a200d 100644
--- a/xevents.c
+++ b/xevents.c
@@ -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);
}
}
diff --git a/xutil.c b/xutil.c
index e6d97bb..51eba6b 100644
--- a/xutil.c
+++ b/xutil.c
@@ -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