applied Brendan MacDonell's WM_TAKE_FOCUS patch, thanks Brendan! 1e20a0f7
Anselm R Garbe · 2011-04-12 20:19 1 file(s) · +42 −31
dwm.c +42 −31
59 59
enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
60 60
enum { NetSupported, NetWMName, NetWMState,
61 61
       NetWMFullscreen, NetLast };                      /* EWMH atoms */
62 -
enum { WMProtocols, WMDelete, WMState, WMLast };        /* default atoms */
62 +
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
63 63
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
64 64
       ClkClientWin, ClkRootWin, ClkLast };             /* clicks */
65 65
88 88
	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
89 89
	int bw, oldbw;
90 90
	unsigned int tags;
91 -
	Bool isfixed, isfloating, isurgent, oldstate;
91 +
	Bool isfixed, isfloating, isurgent, neverfocus, oldstate;
92 92
	Client *next;
93 93
	Client *snext;
94 94
	Monitor *mon;
190 190
static void grabbuttons(Client *c, Bool focused);
191 191
static void grabkeys(void);
192 192
static void initfont(const char *fontstr);
193 -
static Bool isprotodel(Client *c);
194 193
static void keypress(XEvent *e);
195 194
static void killclient(const Arg *arg);
196 195
static void manage(Window w, XWindowAttributes *wa);
208 207
static void restack(Monitor *m);
209 208
static void run(void);
210 209
static void scan(void);
210 +
static Bool sendevent(Client *c, Atom proto);
211 211
static void sendmon(Client *c, Monitor *m);
212 212
static void setclientstate(Client *c, long state);
213 +
static void setfocus(Client *c);
213 214
static void setlayout(const Arg *arg);
214 215
static void setmfact(const Arg *arg);
215 216
static void setup(void);
821 822
		attachstack(c);
822 823
		grabbuttons(c, True);
823 824
		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
824 -
		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
825 +
		setfocus(c);
825 826
	}
826 827
	else
827 828
		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
834 835
	XFocusChangeEvent *ev = &e->xfocus;
835 836
836 837
	if(selmon->sel && ev->window != selmon->sel->win)
837 -
		XSetInputFocus(dpy, selmon->sel->win, RevertToPointerRoot, CurrentTime);
838 +
		setfocus(selmon->sel);
838 839
}
839 840
840 841
void
1012 1013
	dc.font.height = dc.font.ascent + dc.font.descent;
1013 1014
}
1014 1015
1015 -
Bool
1016 -
isprotodel(Client *c) {
1017 -
	int n;
1018 -
	Atom *protocols;
1019 -
	Bool ret = False;
1020 -
1021 -
	if(XGetWMProtocols(dpy, c->win, &protocols, &n)) {
1022 -
		while(!ret && n--)
1023 -
			ret = protocols[n] == wmatom[WMDelete];
1024 -
		XFree(protocols);
1025 -
	}
1026 -
	return ret;
1027 -
}
1028 -
1029 1016
#ifdef XINERAMA
1030 1017
static Bool
1031 1018
isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) {
1054 1041
1055 1042
void
1056 1043
killclient(const Arg *arg) {
1057 -
	XEvent ev;
1058 -
1059 1044
	if(!selmon->sel)
1060 1045
		return;
1061 -
	if(isprotodel(selmon->sel)) {
1062 -
		ev.type = ClientMessage;
1063 -
		ev.xclient.window = selmon->sel->win;
1064 -
		ev.xclient.message_type = wmatom[WMProtocols];
1065 -
		ev.xclient.format = 32;
1066 -
		ev.xclient.data.l[0] = wmatom[WMDelete];
1067 -
		ev.xclient.data.l[1] = CurrentTime;
1068 -
		XSendEvent(dpy, selmon->sel->win, False, NoEventMask, &ev);
1069 -
	}
1070 -
	else {
1046 +
	if(!sendevent(selmon->sel, wmatom[WMDelete])) {
1071 1047
		XGrabServer(dpy);
1072 1048
		XSetErrorHandler(xerrordummy);
1073 1049
		XSetCloseDownMode(dpy, DestroyAll);
1124 1100
	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
1125 1101
	configure(c); /* propagates border_width, if size doesn't change */
1126 1102
	updatesizehints(c);
1103 +
	updatewmhints(c);
1127 1104
	XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
1128 1105
	grabbuttons(c, False);
1129 1106
	if(!c->isfloating)
1471 1448
			PropModeReplace, (unsigned char *)data, 2);
1472 1449
}
1473 1450
1451 +
Bool
1452 +
sendevent(Client *c, Atom proto) {
1453 +
	int n;
1454 +
	Atom *protocols;
1455 +
	Bool exists = False;
1456 +
	XEvent ev;
1457 +
1458 +
	if(XGetWMProtocols(dpy, c->win, &protocols, &n)) {
1459 +
		while(!exists && n--)
1460 +
			exists = protocols[n] == proto;
1461 +
		XFree(protocols);
1462 +
	}
1463 +
	if (exists) {
1464 +
		ev.type = ClientMessage;
1465 +
		ev.xclient.window = c->win;
1466 +
		ev.xclient.message_type = wmatom[WMProtocols];
1467 +
		ev.xclient.format = 32;
1468 +
		ev.xclient.data.l[0] = proto;
1469 +
		ev.xclient.data.l[1] = CurrentTime;
1470 +
		XSendEvent(dpy, c->win, False, NoEventMask, &ev);
1471 +
	}
1472 +
	return exists;
1473 +
}
1474 +
1475 +
void
1476 +
setfocus(Client *c) {
1477 +
	if (!c->neverfocus)
1478 +
		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
1479 +
	sendevent(c, wmatom[WMTakeFocus]);
1480 +
}
1481 +
1474 1482
void
1475 1483
setlayout(const Arg *arg) {
1476 1484
	if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
1517 1525
	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
1518 1526
	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
1519 1527
	wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
1528 +
	wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
1520 1529
	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
1521 1530
	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
1522 1531
	netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
1933 1942
		}
1934 1943
		else
1935 1944
			c->isurgent = (wmh->flags & XUrgencyHint) ? True : False;
1945 +
		if (wmh->flags & InputHint) c->neverfocus = !wmh->input;
1946 +
		else                        c->neverfocus = False;
1936 1947
		XFree(wmh);
1937 1948
	}
1938 1949
}