Before this patch when receiving a _NET_ACTIVE_WINDOW event from a window which is out of view one of the two altenative views/tagsets gets purged and replaced with just the tags where the respective window is visible. For example if you have tags [1,2,3] selected in the first view and tags [4,5,6] on the second view and are currently on the second one, then when a window on tag 7 sends the _NET_ACTIVE_WINDOW event the first view is purged and replaced by just tags [7]. To get back to your previous setup you have to re-select tags 1-3 and then have the views [1,2,3,7] and [4,5,6] where the new window is still on the view you were not using previously, but on the other one.
After this patch the event sending window just gets set to urgent leaving the user the choice when to handle the event. The patch also removes the behavior of such windows getting popped to the top of the master area. --- Heyho Anselm, Here is the version which sets the urgency hint on receiving _NET_ACTIVE_WINDOW messages. There is no real "extra code", but a small refactoring was needed to stay sane: clearurgent() was renamed to seturgent() which takes the value to set the urgency hint to as an extra parameter. Also after the patch the window does not get popped to the top of the master area anymore, since I thought that was in the same line of intrusiveness. This patch even saves 3 SLoC. :) --Markus dwm.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/dwm.c b/dwm.c index 1d57971..0afd630 100644 --- a/dwm.c +++ b/dwm.c @@ -154,7 +154,6 @@ static void buttonpress(XEvent *e); static void checkotherwm(void); static void cleanup(void); static void cleanupmon(Monitor *mon); -static void clearurgent(Client *c); static void clientmessage(XEvent *e); static void configure(Client *c); static void configurenotify(XEvent *e); @@ -205,6 +204,7 @@ static void setfullscreen(Client *c, int fullscreen); static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setup(void); +static void seturgent(Client *c, int urg); static void showhide(Client *c); static void sigchld(int unused); static void spawn(const Arg *arg); @@ -510,19 +510,6 @@ cleanupmon(Monitor *mon) } void -clearurgent(Client *c) -{ - XWMHints *wmh; - - c->isurgent = 0; - if (!(wmh = XGetWMHints(dpy, c->win))) - return; - wmh->flags &= ~XUrgencyHint; - XSetWMHints(dpy, c->win, wmh); - XFree(wmh); -} - -void clientmessage(XEvent *e) { XClientMessageEvent *cme = &e->xclient; @@ -535,11 +522,8 @@ clientmessage(XEvent *e) setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); } else if (cme->message_type == netatom[NetActiveWindow]) { - if (!ISVISIBLE(c)) { - c->mon->seltags ^= 1; - c->mon->tagset[c->mon->seltags] = c->tags; - } - pop(c); + if (c != selmon->sel && !c->isurgent) + seturgent(c, 1); } } @@ -807,7 +791,7 @@ focus(Client *c) if (c->mon != selmon) selmon = c->mon; if (c->isurgent) - clearurgent(c); + seturgent(c, 0); detachstack(c); attachstack(c); grabbuttons(c, 1); @@ -1607,6 +1591,19 @@ setup(void) } void +seturgent(Client *c, int urg) +{ + XWMHints *wmh; + + c->isurgent = urg; + if (!(wmh = XGetWMHints(dpy, c->win))) + return; + wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); + XSetWMHints(dpy, c->win, wmh); + XFree(wmh); +} + +void showhide(Client *c) { if (!c) -- 2.7.3