GNOME Bugzilla – Bug 84564
Keybindings don't work when no window is focused
Last modified: 2004-12-22 21:47:04 UTC
I have the 7th June sources from CVS. I find no way of gaining control of any window using shortcut keys (please note), after once i have lost focus. This happens in the following sequence. 1) Type 'nautilus &' on any terminal, to invoke nautilus 2) Open another nautilus window from the open nautilus window (Ctrl+N or File/New window) 3) After the new window has opened, click on any of the windows, and close all nautilus windows (Ctrl+Shift+W or File/Close All Windows) 4) The focus is lost. And no keyboard shortcuts can return back focus to either of my terminals, panel or desktop.
ctl+alt+tab will do this for you, anand.
Louie: I'm able to simulate this problem here in my machine in the foll steps: 1) Type 'nautilus &' on any terminal, to invoke open nautilus (window1) 2) Open another nautilus window from the open nautilus window (Ctrl+N or File/New window) - window2 3) Click on nautilus window2, and close all nautilus windows (Ctrl+Shift+W or File/Close All Windows) 4) The focus is lost. And no shortcut keys work. Please note that this works fine is window1 has gained focus in step 3 Reopening bug.
Created attachment 9095 [details] [review] 84564 patch
Reproduced with June 9 CVS. It appears the root of the problem is that window focus is not always properly reset when a focused window is freed. Notice that in the scenario above focus is not being restored to the xterm after the nautilus windows are closed. A fix for the problem is to properly refocus on window closure, see attached patch.
Oh, OK. Should have specified all those details when you first filed :)
blackc, I think that's a separate problem - also, key shortcuts should be working when no window is focused. I can't figure out why they don't, though it's probably something pretty silly.
Agreed this is definitely two problems. My patch only fixes a problem with focus not being correctly set when a focused window is freed. The no focus window, no keyboard shortcuts problem is still present, just no longer in this scenario.
*** Bug 85108 has been marked as a duplicate of this bug. ***
Is it not the rootwindow(workspace) that has to be given the focus by default when no window is focused, so that it grabs the screen/global bindings set?
I don't think this patch is quite right; at the moment, metacity tracks the focus window according to focus in/out events. If you set the metacity-side focus window before receiving the events from the server, you potentially create a race condition where metacity thinks a window is focused but it really isn't, or isn't yet.
Agreed, the patch is plain wrong to force the focus window. The behavior I was seeing was the top nautilus window was being freed passing focus to the second nautilus window. However before the FocusIn arrived the second nautilus window was also freed. This time in meta_window_free the has_focus field was not yet set so the meta_screen_focus_top_window call was not made a second time. Thus the terminal was never given focus. Unfortunately I can no longer reproduce this anymore with the current CVS, not sure what may have fixed it.
Reproduced again with July 15 CVS. It helps to launch many (> 5) nautilus windows and then do the close all. A better explanation of the problem is after a XSetInputFocus call on a window the resulting FocusIn event does not always arrive before a Unmap event on the window. Since metacity only tracks window focus with focus in/out events focus gets lost. Consider the two nautilus windows and a terminal scenario as described above: 1) The second (focused) nautilus window is closed, causing an Unmap notify. 2) meta_window_free() is called and recgonizes the window as the focus window 3) meta_screen_focus_top_window() called to pick a new focus window. 4) meta_window_focus() is called to focus the first nautilus window, XSetInputFocus called here 5) a UnmapNotify arrives for the first nautilus window 6) meta_window_free() is called for the first nautilus window. Since the FocusIn event has not arrived yet it does not recgonize the window as the focus window, thus meta_screen_focus_top_window() is NOT called. 7) focus is now lost when it should be on the terminal window I'll attach a slightly better patch that doesn't force focus but instead tracks when a focus event is expected on a window. Any thoughts on all this?
Created attachment 9922 [details] [review] less forceful 84564 patch
This patch looks like a better approach. I'm slightly worried that in some cases "expecting_focus_event" might not get unset - I wonder if there are cases when we can "lose" a focus event? One case might be if we XSetInputFocus() on a window that already has focus, which the current code does tend to do pretty often. Just to make things more robust against this possibility, we could store display->expected_focus_window perhaps, that way you at least have only one stale window-we-think-should-be-focused at a time. btw, since you're writing so many patches, if you want you should mail cvsmaster@gnome.org as explained at the bottom of http://developer.gnome.org/tools/cvs.html and ask for a CVS account; will be more efficient for both of us that way.
Created attachment 10014 [details] [review] better expected focus window 84564 patch
Created attachment 10352 [details] [review] 84564 patch (fix for GTK2 windows - set expected focus on WM_SET_FOCUS only)
patch committed to CVS
The change to the patch isn't quite what I meant; there are four kinds of window, based on the 2x2 grid of TAKE_FOCUS yes/no and input hint yes/no. So there are 3 kinds of window that can be focused. 1. send TAKE_FOCUS 2. just set input focus 3. do both I think we want to set the expected focus window if we set the focus in any of those ways. I thought your original patch only set expected focus window for 2 and 3, so was suggesting adding 1.
Sorry, I misread it as only on WM_TAKE_FOCUS was it safe to set the expected focus window. Just to be totally clear would the following patch fix your case 2 and 3 again? Index: window.c =================================================================== RCS file: /cvs/gnome/metacity/src/window.c,v retrieving revision 1.201 diff -u -r1.201 window.c --- window.c 8 Aug 2002 04:45:13 -0000 1.201 +++ window.c 8 Aug 2002 06:01:09 -0000 @@ -2781,6 +2781,7 @@ window->frame->xwindow, RevertToPointerRoot, CurrentTime); + window->display->expected_focus_window = window; } } else @@ -2796,6 +2797,7 @@ window->xwindow, RevertToPointerRoot, timestamp); + window->display->expected_focus_window = window; } if (window->take_focus)
Yes, I think that fix works.
patch to the patch committed to CVS
So we still theoretically have the "keybindings broken when no window is focused" problem. At least one person said this was now fixed for them, but I don't know what was wrong or why it works now, if it was fixed.
*** Bug 90342 has been marked as a duplicate of this bug. ***
Here's something that might help the process. I just realized my testing only involved one initial window. If I iconify two windows, everything is dandy.
Hrm. This works here :) At any rate, this was originally set high mainly as an a11y problem- should it still be high? (My HO is no.)
I dunno, I got completely lost about halfway down so I've no idea what the current status is :)
Still broken for me with 2.4.1.
I really wish I knew what the heck was going wrong here.
Interestingly enough, when I downgraded to 4.2.0.92-5 with Psyche, the problem went away . . . nautilus is running, though, so I supposed something was still in focus. Removing nautilus from the current session still did not provoke the bug.
*** Bug 114114 has been marked as a duplicate of this bug. ***
We still have the keybindings are broken when no window is focused. This seems to be a consequence of the fact that XGrabKey does not work if there is no focus window. This can happen if WM_TAKE_FOCUS client message is sent to a window and XSetInputFocus is not called by the application receiving the message. The test case for this is to run gok and dismiss the dialog box which is displays. I had thought that the solution would be to call XSetInputFocus (.., PointerRoot, ...) before sending WM_TAKE_FOCUS message. This seems to ensure that the keybindings still work but has the side effect that gok receives FocusIn and FocusOut events when the mouse is moved into and out of gok window.
*** Bug 116248 has been marked as a duplicate of this bug. ***
Created attachment 19384 [details] [review] Proposed patch to ensure that keybindings work
if this works, you're a hero to us all.
I am not sure that this patch is necessary. I have found that the problem does not cocur with the fix for bug 112031.
112031 just means we always focus a window again. I don't understand though; all XSetInputFocus() calls in metacity currently set RevertToPointerRoot. So how is the focus ever getting unset? If we RevertToPointerRoot there always has to be a focus window, we can't get into a focus = None state, right? Is some other application maybe setting RevertToNone? If so, can we kick its ass? Keith - XFIXES to let the window manager redirect setinputfocus? ;-)
The focus may be set but for Ctrl+Alt+Tab to work metcity must call XGrabKey on a window. This only seems to happen when a user's window has focus.
In eel/eel/eel-gdk-extensions.c: void eel_gdk_window_focus (GdkWindow *window, guint32 timestamp) { gdk_error_trap_push (); XSetInputFocus (GDK_DISPLAY (), GDK_WINDOW_XWINDOW (window), RevertToNone, timestamp); gdk_flush(); gdk_error_trap_pop (); } This could very well be our white whale right there...
shall we file an eel bug, and ask for justification of why eel wants to set focus to RevertToNone? This is still a really serious accessibility bug, it appears to be a stopper for keynav-only users.
Ideally it wouldn't be possible for an application to break keybindings by setting the focus to None. Is there any way metacity could perhaps detect this and at the very least react when it happens and set the focus to the no_focus window? But it's probably worthwhile fixing this in eel also.
I just read over Xserver/dix/events.c and if I read the code correctly we are on the right track here. Passive grabs don't get keyboard events if there's no focus window, even if the passive grab is on the root window. When focus goes to None, we should get a focus event with NotifyDetailNone. Should we add a warning metacity will print if this happens? - I'm assuming it always means someone used RevertToNone and that using RevertToNone is always a bug. If we find a legitimate use of RevertToNone we might have to revert the change. I guess it's also possible to call XSetInputFocus (display, None) - is there any legitimate reason to do that? Keith do you know why X has this "no window is focused" concept in the first place? Perhaps XFIXES should allow a passive keyboard grab which is truly global. Anyway, how potentially breakage-causing would it be to move the input focus to some window ourselves whenever we get NotifyDetailNone? I guess that hinges on whether there's a legitimate reason to set focus to None.
*** Bug 120099 has been marked as a duplicate of this bug. ***
I put in all the workarounds I could think of for this, other than that, we just have to destroy any instance of RevertToNone or setting focus to None in any application - only a small task...