applied Brendan MacDonell's WM_TAKE_FOCUS patch, thanks Brendan!

This commit is contained in:
Anselm R Garbe 2011-04-12 20:19:32 +00:00
parent 96f9855248
commit 1e20a0f78a

73
dwm.c
View file

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