/* 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 */
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);
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);
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"
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);
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)
{
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);
}
}
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
drw_setscheme(drw, scheme[SchemeNorm]);
- sw = TEXTW(stext) - lrpad / 2; /* no right padding so status text hugs the corner */
- drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2 - 2, stext, 0);
+ sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+ drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
}
for (c = m->clients; c; c = c->next) {
if (c->mon != selmon)
selmon = c->mon;
if (c->isurgent)
- clearurgent(c);
+ seturgent(c, 0);
detachstack(c);
attachstack(c);
grabbuttons(c, 1);
void
setup(void)
{
+ int i;
XSetWindowAttributes wa;
+ Atom utf8string;
/* clean up any zombies immediately */
sigchld(0);
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);
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);
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);
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)
{