applied Markus' tagset purge of alternative view on _NET_ACTIVE_WINDOW event
[dwm.git] / dwm.c
diff --git a/dwm.c b/dwm.c
index dbff59b..d27cb67 100644 (file)
--- a/dwm.c
+++ b/dwm.c
@@ -60,8 +60,8 @@
 
 /* enums */
 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */
-enum { NetSupported, NetWMName, NetWMState,
+enum { SchemeNorm, SchemeSel }; /* color schemes */
+enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
        NetWMFullscreen, NetActiveWindow, NetWMWindowType,
        NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
@@ -153,7 +153,6 @@ static void buttonpress(XEvent *e);
 static void checkotherwm(void);
 static void cleanup(void);
 static void cleanupmon(Monitor *mon);
-static void clearurgent(Client *c);
 static void clientmessage(XEvent *e);
 static void configure(Client *c);
 static void configurenotify(XEvent *e);
@@ -204,6 +203,7 @@ static void setfullscreen(Client *c, int fullscreen);
 static void setlayout(const Arg *arg);
 static void setmfact(const Arg *arg);
 static void setup(void);
+static void seturgent(Client *c, int urg);
 static void showhide(Client *c);
 static void sigchld(int unused);
 static void spawn(const Arg *arg);
@@ -263,11 +263,11 @@ static void (*handler[LASTEvent]) (XEvent *) = {
 static Atom wmatom[WMLast], netatom[NetLast];
 static int running = 1;
 static Cur *cursor[CurLast];
-static Scm scheme[SchemeLast];
+static Scm *scheme;
 static Display *dpy;
 static Drw *drw;
 static Monitor *mons, *selmon;
-static Window root;
+static Window root, wmcheckwin;
 
 /* configuration, allows nested code to access above variables */
 #include "config.h"
@@ -483,8 +483,9 @@ cleanup(void)
                cleanupmon(mons);
        for (i = 0; i < CurLast; i++)
                drw_cur_free(drw, cursor[i]);
-       for (i = 0; i < SchemeLast; i++)
+       for (i = 0; i < LENGTH(colors); i++)
                free(scheme[i]);
+       XDestroyWindow(dpy, wmcheckwin);
        drw_free(drw);
        XSync(dpy, False);
        XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
@@ -507,19 +508,6 @@ cleanupmon(Monitor *mon)
        free(mon);
 }
 
-void
-clearurgent(Client *c)
-{
-       XWMHints *wmh;
-
-       c->isurgent = 0;
-       if (!(wmh = XGetWMHints(dpy, c->win)))
-               return;
-       wmh->flags &= ~XUrgencyHint;
-       XSetWMHints(dpy, c->win, wmh);
-       XFree(wmh);
-}
-
 void
 clientmessage(XEvent *e)
 {
@@ -533,11 +521,8 @@ clientmessage(XEvent *e)
                        setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD    */
                                      || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
        } else if (cme->message_type == netatom[NetActiveWindow]) {
-               if (!ISVISIBLE(c)) {
-                       c->mon->seltags ^= 1;
-                       c->mon->tagset[c->mon->seltags] = c->tags;
-               }
-               pop(c);
+               if (c != selmon->sel && !c->isurgent)
+                       seturgent(c, 1);
        }
 }
 
@@ -805,7 +790,7 @@ focus(Client *c)
                if (c->mon != selmon)
                        selmon = c->mon;
                if (c->isurgent)
-                       clearurgent(c);
+                       seturgent(c, 0);
                detachstack(c);
                attachstack(c);
                grabbuttons(c, 1);
@@ -1549,7 +1534,9 @@ setmfact(const Arg *arg)
 void
 setup(void)
 {
+       int i;
        XSetWindowAttributes wa;
+       Atom utf8string;
 
        /* clean up any zombies immediately */
        sigchld(0);
@@ -1566,6 +1553,7 @@ setup(void)
        bh = drw->fonts->h + 2;
        updategeom();
        /* init atoms */
+       utf8string = XInternAtom(dpy, "UTF8_STRING", False);
        wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
        wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
        wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
@@ -1574,6 +1562,7 @@ setup(void)
        netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
        netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
        netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
+       netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
        netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
        netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
        netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
@@ -1583,11 +1572,20 @@ setup(void)
        cursor[CurResize] = drw_cur_create(drw, XC_sizing);
        cursor[CurMove] = drw_cur_create(drw, XC_fleur);
        /* init appearance */
-       scheme[SchemeNorm] = drw_scm_create(drw, colors[SchemeNorm], 3);
-       scheme[SchemeSel] = drw_scm_create(drw, colors[SchemeSel], 3);
+       scheme = ecalloc(LENGTH(colors), sizeof(Scm));
+       for (i = 0; i < LENGTH(colors); i++)
+               scheme[i] = drw_scm_create(drw, colors[i], 3);
        /* init bars */
        updatebars();
        updatestatus();
+       /* supporting window for NetWMCheck */
+       wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
+       XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
+               PropModeReplace, (unsigned char *) &wmcheckwin, 1);
+       XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8,
+               PropModeReplace, (unsigned char *) "dwm", 4);
+       XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
+               PropModeReplace, (unsigned char *) &wmcheckwin, 1);
        /* EWMH support per view */
        XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
                        PropModeReplace, (unsigned char *) netatom, NetLast);
@@ -1602,6 +1600,20 @@ setup(void)
        focus(NULL);
 }
 
+
+void
+seturgent(Client *c, int urg)
+{
+       XWMHints *wmh;
+
+       c->isurgent = urg;
+       if (!(wmh = XGetWMHints(dpy, c->win)))
+               return;
+       wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint);
+       XSetWMHints(dpy, c->win, wmh);
+       XFree(wmh);
+}
+
 void
 showhide(Client *c)
 {