URI: 
       applied Brendan MacDonell's WM_TAKE_FOCUS patch, thanks Brendan! - dwm - dynamic window manager
  HTML git clone https://git.parazyd.org/dwm
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 1e20a0f78a580ebf4ad521d0e074125bb0a7d4b8
   DIR parent 96f9855248545d6e6da1aeece04e44a1f7246ccb
  HTML 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:
         M dwm.c                               |      73 ++++++++++++++++++-------------
       
       1 file changed, 42 insertions(+), 31 deletions(-)
       ---
   DIR 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);
                }
        }