diff options
| author | Anselm R Garbe <anselm@garbe.us> | 2011-04-12 20:19:32 +0000 | 
|---|---|---|
| committer | Anselm R Garbe <anselm@garbe.us> | 2011-04-12 20:19:32 +0000 | 
| commit | 1e20a0f78a580ebf4ad521d0e074125bb0a7d4b8 (patch) | |
| tree | 0dea98987a0066dd2e5ac65597d495bf6e483098 | |
| parent | 96f9855248545d6e6da1aeece04e44a1f7246ccb (diff) | |
applied Brendan MacDonell's WM_TAKE_FOCUS patch, thanks Brendan!
| -rw-r--r-- | dwm.c | 73 | 
1 files changed, 42 insertions, 31 deletions
| @@ -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);  	}  } | 
