dwm

my fork of dwm
Index Commits Files Refs README LICENSE
commit 1e20a0f78a580ebf4ad521d0e074125bb0a7d4b8
parent 96f9855248545d6e6da1aeece04e44a1f7246ccb
Author: Anselm R Garbe <anselm@garbe.us>
Date:   Tue, 12 Apr 2011 20:19:32 +0000

applied Brendan MacDonell's WM_TAKE_FOCUS patch, thanks Brendan!
Diffstat:
Mdwm.c | 73++++++++++++++++++++++++++++++++++++++++++-------------------------------
1 file changed, 42 insertions(+), 31 deletions(-)
diff --git a/dwm.c b/dwm.c
@@ -59,7 +59,7 @@ enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
 enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
 enum { NetSupported, NetWMName, NetWMState,
        NetWMFullscreen, NetLast };                      /* EWMH atoms */
-enum { WMProtocols, WMDelete, WMState, WMLast };        /* default atoms */
+enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
        ClkClientWin, ClkRootWin, ClkLast };             /* clicks */
 
@@ -88,7 +88,7 @@ struct Client {
     int basew, baseh, incw, inch, maxw, maxh, minw, minh;
     int bw, oldbw;
     unsigned int tags;
-    Bool isfixed, isfloating, isurgent, oldstate;
+    Bool isfixed, isfloating, isurgent, neverfocus, oldstate;
     Client *next;
     Client *snext;
     Monitor *mon;
@@ -190,7 +190,6 @@ static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
 static void grabbuttons(Client *c, Bool focused);
 static void grabkeys(void);
 static void initfont(const char *fontstr);
-static Bool isprotodel(Client *c);
 static void keypress(XEvent *e);
 static void killclient(const Arg *arg);
 static void manage(Window w, XWindowAttributes *wa);
@@ -208,8 +207,10 @@ static void resizemouse(const Arg *arg);
 static void restack(Monitor *m);
 static void run(void);
 static void scan(void);
+static Bool sendevent(Client *c, Atom proto);
 static void sendmon(Client *c, Monitor *m);
 static void setclientstate(Client *c, long state);
+static void setfocus(Client *c);
 static void setlayout(const Arg *arg);
 static void setmfact(const Arg *arg);
 static void setup(void);
@@ -821,7 +822,7 @@ focus(Client *c) {
         attachstack(c);
         grabbuttons(c, True);
         XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
-        XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
+        setfocus(c);
     }
     else
         XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
@@ -834,7 +835,7 @@ focusin(XEvent *e) { /* there are some broken focus acquiring clients */
     XFocusChangeEvent *ev = &e->xfocus;
 
     if(selmon->sel && ev->window != selmon->sel->win)
-        XSetInputFocus(dpy, selmon->sel->win, RevertToPointerRoot, CurrentTime);
+        setfocus(selmon->sel);
 }
 
 void
@@ -1012,20 +1013,6 @@ initfont(const char *fontstr) {
     dc.font.height = dc.font.ascent + dc.font.descent;
 }
 
-Bool
-isprotodel(Client *c) {
-    int n;
-    Atom *protocols;
-    Bool ret = False;
-
-    if(XGetWMProtocols(dpy, c->win, &protocols, &n)) {
-        while(!ret && n--)
-            ret = protocols[n] == wmatom[WMDelete];
-        XFree(protocols);
-    }
-    return ret;
-}
-
 #ifdef XINERAMA
 static Bool
 isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) {
@@ -1054,20 +1041,9 @@ keypress(XEvent *e) {
 
 void
 killclient(const Arg *arg) {
-    XEvent ev;
-
     if(!selmon->sel)
         return;
-    if(isprotodel(selmon->sel)) {
-        ev.type = ClientMessage;
-        ev.xclient.window = selmon->sel->win;
-        ev.xclient.message_type = wmatom[WMProtocols];
-        ev.xclient.format = 32;
-        ev.xclient.data.l[0] = wmatom[WMDelete];
-        ev.xclient.data.l[1] = CurrentTime;
-        XSendEvent(dpy, selmon->sel->win, False, NoEventMask, &ev);
-    }
-    else {
+    if(!sendevent(selmon->sel, wmatom[WMDelete])) {
         XGrabServer(dpy);
         XSetErrorHandler(xerrordummy);
         XSetCloseDownMode(dpy, DestroyAll);
@@ -1124,6 +1100,7 @@ manage(Window w, XWindowAttributes *wa) {
     XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
     configure(c); /* propagates border_width, if size doesn't change */
     updatesizehints(c);
+    updatewmhints(c);
     XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
     grabbuttons(c, False);
     if(!c->isfloating)
@@ -1471,6 +1448,37 @@ setclientstate(Client *c, long state) {
             PropModeReplace, (unsigned char *)data, 2);
 }
 
+Bool
+sendevent(Client *c, Atom proto) {
+    int n;
+    Atom *protocols;
+    Bool exists = False;
+    XEvent ev;
+
+    if(XGetWMProtocols(dpy, c->win, &protocols, &n)) {
+        while(!exists && n--)
+            exists = protocols[n] == proto;
+        XFree(protocols);
+    }
+    if (exists) {
+        ev.type = ClientMessage;
+        ev.xclient.window = c->win;
+        ev.xclient.message_type = wmatom[WMProtocols];
+        ev.xclient.format = 32;
+        ev.xclient.data.l[0] = proto;
+        ev.xclient.data.l[1] = CurrentTime;
+        XSendEvent(dpy, c->win, False, NoEventMask, &ev);
+    }
+    return exists;
+}
+
+void
+setfocus(Client *c) {
+    if (!c->neverfocus)
+        XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
+    sendevent(c, wmatom[WMTakeFocus]);
+}
+
 void
 setlayout(const Arg *arg) {
     if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
@@ -1517,6 +1525,7 @@ setup(void) {
     wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
     wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
     wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
+    wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
     netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
     netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
     netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
@@ -1933,6 +1942,8 @@ updatewmhints(Client *c) {
         }
         else
             c->isurgent = (wmh->flags & XUrgencyHint) ? True : False;
+        if (wmh->flags & InputHint) c->neverfocus = !wmh->input;
+        else                        c->neverfocus = False;
         XFree(wmh);
     }
 }