On Thu, Sep 22, 2011 at 05:34:32PM -0400, Benjamin R. Haskell wrote: > On Thu, 22 Sep 2011, Roman Z. wrote: > > >On Wed, Sep 21, 2011 at 09:48:11PM +0200, Roman Z. wrote: > >>Currently, if you run a program in tabbed and move the mouse > >>away from that window, the program will not respond anymore. > >> > >>Since this is much like how X behaves when you run no window > >>manager, I've been looking in dwm code for solutions to this > >>problem but to no avail. Maybe you can tell me what part of dwm > >>handles this and I can apply it to tabbed? Or do you have other > >>ideas? > >> > >>To reproduce: > >>1. open xterm in tabbed. This hasn't worked for me with the > >>newest version, I use revision 142. > >>2. put the mouse inside the tabbed window and type "a". It works. > >>3. move the mouse out of the window and type "a". Nothing happens. > > > >One solution is to revert the changeset 138. It has the commit > >message: "removing XSetInputFocus() calls to be ICCCM compliant > >again. Thanks to Thomas Adam". > > > >Please consider reverting this changeset in upstream since you now > >know that it introduced a bug. > > Confirming that reverting 138 worked here, too: > > changeset: 138:5eff0bc41822 > user: Enno Boland (tox) <t...@s01.de> > date: Mon Apr 26 22:30:27 2010 +0200 > summary: removing XSetInputFocus() calls to be ICCCM compliant again. > Thanks to Thomas Adam fixes tabbed for me, too, under dwm. > > It'd also be nice if the 'command' of 'tabbed [-d] [-v] command' > were optional. Not sure how hard that'd be. It was weird to have > to test it differently based on what version I was testing. I'll > look at it later (instead of just complaining) if someone doesn't do > it first. > > -- > Best, > Ben >
Only reverting 138 will not do the trick, as new problems arise. Now, focus() will imply a XSetInputFocus on the selected subwindow. This can steal the input focus from any other window. For example, focus() is called on EnterNotify, (when the mouse enters tabbed) independent of whether tabbed is focused or not. You can reproduce it using dwm as window manager by running xterm in tabbed, focusing another window, holding the key "x" and repeatedly moving the mouse in and out of the tabbed window. Sooner or later, some of the x'es will be passed to the xterm in tabbed even though it's not focused by the window manager. So I removed the handler for EnterNotify. I don't know why it was added in the first place, but I don't see any downside after removing it either. There are more places where focus is called but XSetInputFocus should not be called. For example in the XFocusChangeEvent/FocusIn handler, maybe in expose() too. I attached a patch for 144 which fixes things for me, but I'm not confident that it works without errors. Especially on different machines with different setups.
# HG changeset patch # User Roman Z (rom...@lavabit.com) # Date 1316737168 -7200 # Node ID a6e79969664bf738c40daa4357e7aaa00f35c938 # Parent af9499282ed599d8a40b555cace28170543d3b84 Partially reverted 138 and fixed some resulting bugs diff -r af9499282ed5 -r a6e79969664b tabbed.c --- a/tabbed.c Sat Jun 18 14:37:43 2011 +0100 +++ b/tabbed.c Fri Sep 23 02:19:28 2011 +0200 @@ -94,7 +94,6 @@ static void drawbar(); static void drawtext(const char *text, unsigned long col[ColLast]); static void *emallocz(size_t size); -static void enternotify(const XEvent *e); static void expose(const XEvent *e); static void focus(Client *c); static void focusin(const XEvent *e); @@ -134,7 +133,6 @@ [ConfigureRequest] = configurerequest, [CreateNotify] = createnotify, [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, [Expose] = expose, [FocusIn] = focusin, [KeyPress] = keypress, @@ -368,11 +366,6 @@ } void -enternotify(const XEvent *e) { - focus(sel); -} - -void expose(const XEvent *e) { const XExposeEvent *ev = &e->xexpose; @@ -390,6 +383,7 @@ } resize(c, ww, wh - bh); XRaiseWindow(dpy, c->win); + XSetInputFocus(dpy, c->win, RevertToParent, CurrentTime); sendxembed(c, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0); sendxembed(c, XEMBED_WINDOW_ACTIVATE, 0, 0, 0); XStoreName(dpy, win, c->name); @@ -402,7 +396,14 @@ void focusin(const XEvent *e) { - focus(sel); + const XFocusChangeEvent *ev = &e->xfocus; + int dummy; + Window focused_win; + if (ev->mode != NotifyUngrab) { + XGetInputFocus(dpy, &focused_win, &dummy); + if (focused_win == win) + focus(sel); + } } void