GNOME Bugzilla – Bug 573922
Using NET_WM_USER_TIME even if startup notification timestamp is larger
Last modified: 2010-05-02 15:49:47 UTC
Please describe the problem: It seems that 2.25.91 has a bug in it that causes new nautilus windows to be launched in the background. Unfortunately, I cannot provide a 100% solid set of repros steps but still the bug is fairly easy to trigger. How to repro (not 100% solid): 1. launch some Firefox windows and a gnome-terminal 2. switch to the gnome-terminal 3. type "xdg-open ." to open the current dir in nautilus If the new nautilus window was created in the background with a flashing entry in the bottom taskbar, then you're seeing the bug. If not, then do this: 4. alt-TAB to Firefox 5. alt-TAB back to gnome-terminal 6. launch "xdg-open ." again If you mess around a little bit with switching windows etc and then launch this command, sooner or later you will get a nautilus window being created in the background. Notes: * This bug repro's using the Ubuntu gnome-straccitella-session (which is a new package that allow you to use a minimally changed GNOME compared to upstream). * I have a nautilus icon in my gnome-panel and this bug also repros _sometimes_ when I click that icon. * This bug is easy to trigger even with compiz turned off. * It's confirmed on both x86 and x64, it's also confirmed on a box which has a single ext3 partition (no NTFS, no external harddrives or weird mounts etc). Another Ubuntu user provided these repro steps: 1. launch audacious, xchat 2. select the audacious window 3. select the xchat window 4. open Places menu and select "Videos" I was able to repro this the first time I did it, but then if I do it again with "Videos" in the end then it doesn't happen. After that I tried it again but I changed "Videos" so that I instead selected "Homedir" from the places menu and boom the bug repro'd again. However, if I repeat it once more with "Homedir" then it doesn't repro. So it's like the first time I open a folder, then it happens. I also tried to create a brand new directory and use "xdg-open ." inside it but that wasn't a 100% solid way to repro it either. More info is available in the Ubuntu bug report: https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/333366 --- Please let me know if there is addition information you need or experiments you would like me to try. Thanks. Steps to reproduce: Actual results: Expected results: Does this happen every time? Other information:
I managed to reproduce this with the first batch of instructions.
On my machine it happens _every_ time that I open Nautilus, so 100% reproduction quote. I don't know which information could be important so feel free to ask everything. Some general stuff (that probably won't use anything...): Ubuntu jaunty x64, ext4 (with some ext3 partitions not entered in fstab and not mounted), Compiz (both 0.7.8 and newly 0.8.2).
This seems to have been introduced around the time we switched to libunique for passing over to the old app during launch. Its probably related to that.
I don't understand it though... Even when it fails the second nautilus instance generates a startup id like _TIME245244984 and passes it on to the first nautilus instance which passes it to gtk_window_set_startup_id(). It *should* work.
In fact, even if using a proper startup notification handling launcher like the panel this can happen. I got the behaviour launching "Computer" from the panel menu and this opened the new window with calling gtk_window_set_startup_id() with "gnome-panel-3676-fatty-nautilus-33_TIME246436843". This is using metacity 2.26.0, no composite.
Here is what happens in metacity when this goes wrong: WINDOW_STATE: Showing window 0x4a00731 (Computer), shaded: 0 iconic: 0 placed: 0 STARTUP: COMPARISON: net_wm_user_time_set : 1 net_wm_user_time : 252396578 initial_timestamp_set: 1 initial_timestamp : 252401211 STARTUP: COMPARISON (continued): focus_window : 0x460599a (iGoogle - ) fw->net_wm_user_time_set : 1 fw->net_wm_user_time : 252398257 STARTUP: window 0x4a00731 (Computer) focus prevented by other activity; 252396578 < 252398257 In other words, we get the right initial_timestamp for the mapped window, but we also get an old net_wm_user_time based on the user_time set on the display (i.e. the last nautilus interaction). This net_wm_user_time is older than the net_wm_user_time on the firefox window, so we're not allowing it to steal the focus. However, both net_wm_user_times are < the initial_timestamp. So, its kinda weird that we're not allowing this. I'm not sure what the behaviour of focus stealing is supposed to be here. Should we add a gdk_x11_window_set_user_time() call somewhere or is metacity buggy?
Elijah: You know this focus prevention stuff best. What should we do here? Should Gtk+ set NET_WM_USER_TIME based on the startup notification timestamp, or should metacity prefer the startup notification timestamp over the net_wm_user_time timestamp if initial_timestamp > net_wm_user_time?
Reassigning since this is clearly not a nautilus bug. Some background research: The startup notify spec says: TIMESTAMP X server timestamp of the user action that caused this launch. For example window manager that doesn't allow stealing of focus by newly mapped windows while the user works in an application can use this timestamp for windows that have matching _NET_STARTUP_ID property if they don't have any _NET_WM_USER_TIME property set or if it's older. See the description of _NET_WM_USER_TIME in the WM spec for details. This seem to imply that if NET_WM_USER_TIME is < the startup time we should use the startup time. Metacity says (in :window.c:intervening_user_event_occurred()): /* To determine the "launch" time of an application, * startup-notification can set the TIMESTAMP and the * application (usually via its toolkit such as gtk or qt) can * set the _NET_WM_USER_TIME. If both are set, then it means * the user has interacted with the application since it * launched, and _NET_WM_USER_TIME is the value that should be * used in the comparison. */ So, metacity doesn't use the TIMESTAMP value from startup notification even if it is larger than _NET_WM_USER_TIME. This is imho a bug.
Created attachment 132247 [details] [review] Patch that uses startup timestamp if larger This patch fixes the nautilus issue for me.
The same occurs when using compiz, so the problem can't exclusively in metacity. Perhaps a similar situation exists in compiz code as well?
On the Gtk+ side there are two issues: First of all, when realizing, if startup_notify is set we already do: guint32 timestamp = extract_time_from_startup_id (priv->startup_id); if (timestamp != GDK_CURRENT_TIME) gdk_x11_window_set_user_time (widget->window, timestamp); However, extract_time_from_startup_id has a bug where it looks at errno after calling strtoul without setting it to 0 before calling it. Secondly, if gtk_window_set_startup_id() is called when the window is already realized we don't currently set the user time. I will attach a patch that fixes these issues.
Created attachment 132269 [details] [review] Gtk+ patch that fixes the issues
Patch looks great, please commit.
This patch was commited right? If so, then I suppose the bug should be marked as RESOLVED as well. At least the bug is gone in Ubuntu so I assume this is the case.
Only the GTK+ patch was committed, still waiting for the metacity one, I think.
I am not sure the metacity patch is conceptually correct: is the assumption that startup notification is always triggered by user action valid ? It would seem to me the bug here is that the user timestamp on the window is not updated, which is the client's responsibility, the EWMH spec says regarding this: Clients can obtain the timestamp that caused its first window to appear from the DESKTOP_STARTUP_ID environment variable, if the app was launched with startup notification. The WM should be able to assume that the _NET_WM_USER_TIME is what the spec says it should be: XServer time at which last user activity in this window took place.
If there is a timestamp from startup notification, that is also user interaction related to showing that window.. So I don't think there is ever a case where we want ignore a *newer* startup notification timestamp. So, in that sense the patch is correct and should make things more robust if the toolkit does what GTK+ used to do and set both, and also if the toolkit sets _NET_WM_USER_TIME but is innocent of startup notification. Though the comment above the patched section of code would have to be updated. It currently says: /* To determine the "launch" time of an application, * startup-notification can set the TIMESTAMP and the * application (usually via its toolkit such as gtk or qt) can * set the _NET_WM_USER_TIME. If both are set, then it means * the user has interacted with the application since it * launched, and _NET_WM_USER_TIME is the value that should be * used in the comparison. */ But there's a trap here: XSERVER_TIME_IS_BEFORE() is only valid when the times aren't separated more than G_MAXUINT/2 milliseconds. And that's only 25 days. So, after 25 days, the startup notification time would start looking newer than then the user time and focus stealing prevention would break a bit though very subtly - if, say, an application unminimized a window without activating it, then Metacity would say "this window has a really new startup notification time, let me focus it", even if the user time was old compared to the currently focused window. I'm not sure that's even worth worrying about, but the fix would be to clear window->initial_timestamp_set at the end of window.c:meta_window_show() - we only want to look at the initial timestamp once.
(In reply to comment #17) > If there is a timestamp from startup notification, that is also user > interaction related to showing that window.. So I don't think there is ever a > case where we want ignore a *newer* startup notification timestamp. I was thinking of a case where a window pops up as the result of some automated action, but that, unlike the current problem, is not such a common scenario perhaps to worry about. > I'm not sure that's even worth worrying about, but the fix would be to clear > window->initial_timestamp_set at the end of window.c:meta_window_show() - we > only want to look at the initial timestamp once. It's probably not worth worrying about, but clearing that flag makes sense and should be harmless. I will prepare an update patch for mutter.
(In reply to comment #18) > (In reply to comment #17) > > If there is a timestamp from startup notification, that is also user > > interaction related to showing that window.. So I don't think there is ever a > > case where we want ignore a *newer* startup notification timestamp. > > I was thinking of a case where a window pops up as the result of some automated > action, but that, unlike the current problem, is not such a common scenario > perhaps to worry about. If a window is popped up from an automated process it shouldn't have a startup timestamp assigned to it at all, right? Unless the automated process involved system("gnome-open /some/dir"), and at that point it isn't distingushable from a user-initiated action.
Created attachment 140215 [details] [review] Mutter patch
Patch looks good to commit to me.
Mutter patch committed as ae32ac86b49fb37f3afb142b29bce3cc75a932f9.
Review of attachment 132247 [details] [review]: Looks good to me.
Review of attachment 140215 [details] [review]: Looks good (as did the parent patch).
Marking bug FIXED.