GNOME Bugzilla – Bug 597352
alt-tab'ing to windows on different workspace doesn't focus them
Last modified: 2011-04-20 17:41:01 UTC
The problem is as per summary. It seems the window that the last focused windows will get focus when returning to the workspace (by alt-tab'ing to a different window on the same workspace). git: caa08f27fa0afd96f7684245cbded641335377f2
OK, have this one tracked down. It's pretty nasty. Mutter keeps two ideas of the focus window display->focus_window The last window where we got a FocusIn notification from X display->expected_focus_window The last window we called XSetInputFocus() In most cases, Mutter is using display->focus_window not display->expected_focus_window. (Or it is using window->has_focus, which is set to match display->focus_window.) In Metacity, it was almost always the case that focus events would get processed pretty quickly, so cases where we called XSetInputFocus() but hadn't yet gotten the notification back were rare race conditions. However, the way we do things now we do a single frame of: - Process clutter events - Process idles (show/hide windows, restack, etc.) - Paint So if in processing clutter events we do something that changes the input focus we'll process all the idles and paint before we get the notification back from X. In this case, what happens is: - We focus the new window on the other desktop - We add an idle to show/hide the rest of the windows - When the idle runs we hide the old focus window - We notice that the window we are hiding has ->has_focus set (since we haven't yet gotten focus notifications) - We panic and focus a random window to avoid leaving the user with no focus. I'm pretty sure the right thing here is to basically change all of Mutter to use the _expected_ focus window rather than the focus window from events. But along with having to change 20 or so places and check that it makes sense in every case, there's a couple of other things that have to be done: - display->expected_focus_window is literally the last window we tried to focus, even if we got a FocusIn event on another window with a later timestamp. We actually want to track "our best idea of where the focus is currently" which requires a bit more sophistication. - we should also try to catch the case where we called XSetInputFocus() on a window and it got denied (an old timestamp for example) - this can be done by tracking serial of the last XSetInputFocus() call, if we get events with a newer serial and the focus hasn't changed, then we no nothing happened. - The globally active input mode (ICCCM section 4.1.7) is problematical since in this mode we send the client an event, and at some unpredictable later point it sets the focus, so we can't distinguish that failing or the client just ignoring the WM_TAKE_FOCUS from the client not having taken the focus yet. My best idea here is to focus the no_focus_window before sending the message so that if the window doesn't take the focus events get eaten rather than going to the old app. It's a reasonably big and tricky set of changes, I'm going to try and come up with a temporary workaround for just this particular problem, since I'm trying to get to the point of being able to roll a Mutter tarball.
Created attachment 144977 [details] [review] Work around race condition focusing a window on a different workspace When we focus a window on a different desktop, and the calc_showing idle that hides/shows the windows gets run before we get focus events back from X, we think that we are hiding the window with the focus so we focus a "random" window to avoid leaving the user with no focus. Work around this temporarily by checking display->expected_focus_window; this isn't a perfect fix because there are cases where display->expected_focus_window corresponds to a window we tried to focus in the past but failed, but it makes things work fairly well.
Comment on attachment 144977 [details] [review] Work around race condition focusing a window on a different workspace so it seems to do what you say and have the problems you mention. an alternate possibility if you don't like this patch would be to do some workaround that was specific to meta_workspace_activate_with_focus()
*** Bug 597274 has been marked as a duplicate of this bug. ***
(In reply to comment #3) > (From update of attachment 144977 [details] [review]) > so it seems to do what you say and have the problems you mention. > > an alternate possibility if you don't like this patch would be to do some > workaround that was specific to meta_workspace_activate_with_focus() I don't have any great good ideas for such a workaround - so I'm going to go with this patch.
Comment on attachment 144977 [details] [review] Work around race condition focusing a window on a different workspace Attachment 144977 [details] pushed as e8a29c1 - Work around race condition focusing a window on a different workspace
Is this bug still valid? I can't reproduce, but I'm not sure if it was every easy to reproduce.
The remainder of this is now bug 647706 *** This bug has been marked as a duplicate of bug 647706 ***