GNOME Bugzilla – Bug 721145
_NET_WM_USER_TIME causing windows to not be raised
Last modified: 2014-02-24 15:11:24 UTC
There were a couple of reports for the gala wm, which is based on libmutter, talking about windows not being raised when they are launched, especially the terminal, which is opened by a shortcut. I investigated that problem and at least have a guess now what could be wrong. The problem in mutter is basically here: https://git.gnome.org/browse/mutter/tree/src/core/window.c#n2639 If there's not initial_timestamp, but a user_time, it will be taken and used to compare. When Gtk maps a window, it will assign its display's user_time to the window, unless the display's user_time is at 0, in which case it won't be set. So for that case there are no troubles in mutter. https://git.gnome.org/browse/gtk+/tree/gdk/x11/gdkwindow-x11.c#n950 Now, if the existing window is left alone for a while and then another window of that app is created, it will take the same display's user_time, which is still at the point of the last interaction with the old window, and assign it to the new window. And that's where the mutter code gets problematic, as it now compares to a user_time that's way older than the last interaction and also not unset. So the window won't be raised. I haven't checked the Gtk part very well though, I could be mistaken, but my investigations would strongly suggest that this is the problem or at least something similar. One option to solve that would probably be to make all the applications update their user_time whenever they open a new window, but I suppose that'd be quite a lot of apps. Maybe updating the user_time when the window requests to be mapped or just always unsetting the user_time while mapping would work too? If I could get technical advice on what solution might be the most promising one I could try writing a patch for it. I noticed this behavior with different apps, among them nautilus. I tested on compiz, metacity, mutter and gala obviously. It was especially noticeable for the GtkApplication demo app (https://developer.gnome.org/gtk3/3.11/GtkApplication.html#gtkapplication), just repeatedly launching it from nautilus made the problem instantly apparent (from terminal won't work, because mutter catches that case, the window would never be raised), the first time it will be raised, when launching it again it won't. Apparently the process is never destroyed, making this even more obvious, only a "killall appname" and then starting it again will make the window be raised once again. I'm just reporting this here, maybe it would be better located at gtk+?
Is there a simple reproducer for this? Is it as simple as "launch an app that already has a window open"?
Yes, that's basically it. Of course some conditions have to be met, like that an application_id is set for that application so that each instance shares the same process. A test app which makes the problem very apparent is this: http://pastebin.com/AqJp4r4U Here a quick video demonstration: http://www.youtube.com/watch?v=3HjgCuoGlY8 I picked metacity for demoing it because with the broken window decorations you can see where the focus went more easily :) Basically, as soon as I set a user_time on one instance by clicking on it, all windows spawned after will not be raised anymore.
Created attachment 264973 [details] [review] Gtk patch that would solve the problem If Gtk wouldn't assign its old user_time to a new window the problem would be solved. I don't see any cases where this would create problems. It seems illogical to assign a time that's meant to show the last interaction with a window to an absolutely new window in the first place.
If an application maps a window with an old timestamp, then the window manager definitely should not steal focus from the user. Avoiding that happening is the whole point of "focus stealing prevention" and why we use timestamps. So there is no Mutter (or other WM) bug here. It seems like something is going wrong with the propagation of the launch timestamp from the process that is launched to the window that is created in the new process. As far as I know, there is code somewhere that is supposed to handle that propagation. Reassigning to GTK+.
Could maybe be caused by a mistake introduced by the refactor in bug 720550. Does the patch in bug 721304 fix this for you?
Yes, perfect! The patch fixes it, desrt. However I doubt this was only introduced by the refractor, because it already happened quite long ago. The bug was actually reported on a system running gtk+-3.4 I believe. Do you have any idea if it would be possible to backport this patch to gtk+-3.4 or basically the version that runs on ubuntu 12.04?