GNOME Bugzilla – Bug 795779
Ensure that the the startup sequence is finished when the launchee exits early without an error code
Last modified: 2018-05-11 12:29:04 UTC
I think I might have found an issue with how some of the bits related to the Startup Notification spec [1] are implemented in GLib, since there seems to be a problem when dealing with single-instance applications shipping multiple .desktop files that run the same executable file, such as gnome-control-center. As per the Startup Notification Spec, when an application declares this in its desktop file, it the launcher (e.g. the shell) will initiate the startup process, expecting the launchee to finish it with a "remove" X message once it's ready, unless there's a failure launching it. The problem I found with the particular case of gnome-control-center can be seen following these steps: 1. Open gnome-control-center and leave it open, making sure that g-c-c's Name and Icon are shown in the top panel (right of "Activities") 2. From GNOME Shell's top panel, open the system indicators popup and open any panel in the control panel from there (e.g. "Account Settings") 3. Look at the name & icon in the top panel while this second panel is loading --> you'll see how it changes from "Settings" to the name & icon of the panel being loaded (e.g. "Users") for some seconds, and a spinner is shown 4. Hovering over g-c-c's window shows the spinning cursor as well for a few seconds, then it finally changes back to the arrow and the panel is shown. What is going on? The problem here is that these panel-specific desktop files declare `StartupNotify=true`, which makes the shell (as per a call to `g_desktop_app_info_launch_uris_with_spawn()`) to initiate the startup sequence when trying to open the desired panel from g-c-c, as that's inline with the spec in [1]. However, since g-c-c is a single-instance application and the `Exec` lines in all those panel-specific desktop files point to the `gnome-control-center` binary, what that new process does as soon as it's run is to realize that another main instance is running, hand over the parameters passed to it, and exit gracefully without an exit code. However, at this point the startup sequence was already started and, as a result, it was expected that the launchee would eventually send a "remove" X message as per the spec. But that message would be only sent once the "new" application's top level window gets mapped (from `gdk_x11_display_notify_startup_complete()`), and since that second process exits early before mapping any window, that message is never sent... resulting in the whole sequence to keep alive until it's ended on a timeout. In summary, this means that the shell will believe for a while (until the process is ended on a timeout) that an actual second application is starting up, with its own name and icon, since a different desktop file other than gnome-control-center.desktop was used for the launch... which is really confusing. Reading the section "Launchee failures" from the spec in [1], it says: "The launcher process is responsible for detecting launchee failures such as a crash and should end the launch sequence in such case. In case launchee fails to end the launch sequence, clients should treat the launch sequence as ended withing a reasonable time. The problem here is that there's not really a failure in the launchee, which exits gracefully after handing over the parameters, which I believe is a bug somewhere: IMHO, it should be detected when this kind of situation happens and make sure that the startup sequence is correctly finished in that case. I'm filing this under GLib since that's where the whole process gets initiated via a call to `g_app_launch_context_get_startup_notify_id()` (which in the case of gnome-control-center gets implemented in GDK (e.g. gdk_x11_app_launch_context_get_startup_notify_id), so I assume that whatever fix gets implemented will require bits in GLib itself, even if perhaps some more bits will be required in GTK+ too, not sure yet though. [1] https://www.freedesktop.org/wiki/Specifications/startup-notification-spec
Temporary "fix" (it's really an attempt to mitigated the bad UX, to be honest) proposed for gnome-control-center here: https://gitlab.gnome.org/GNOME/gnome-control-center/merge_requests/35 PS: that should be removed as soon as this more general issue gets fixed
I don’t really know much about this area of the code; the GTK+ developers probably know more. If what you say is true, there’s a question about whether the newly launched (and immediately exiting) process should send the "remove" message, or whether the existing (and now newly activated) process should send it. The former is easier, but the latter closes the feedback loop properly and means we guarantee the existing process has a chance to process the activation (e.g. show the right g-c-c panel) before notifying gnome-shell with "remove".
I believe the right thing to do here is to have the same process that has just been activated (the one which will exit after realizing of the remote main instance) sends the "remote" message, because that would be the only way to pair with the ID of the process the startup sequence was initiated for, by the launcher (the shell, in this case). If you send the "remove" message from the main and previously existing instance instead, after having handled the arguments from the newer process, the startup notification ID won't match the sequence that has been initiated, and won't work, I think.
(In reply to Mario Sánchez Prada from comment #3) > I believe the right thing to do here is to have the same process that has > just been activated (the one which will exit after realizing of the remote > main instance) sends the "remote" message, because that would be the only > way to pair with the ID of the process the startup sequence was initiated > for, by the launcher (the shell, in this case). > > If you send the "remove" message from the main and previously existing > instance instead, after having handled the arguments from the newer process, > the startup notification ID won't match the sequence that has been > initiated, and won't work, I think. Actually, it seems to me that the place to terminate the process is neither the main instance of the process being launched nor the latest instance that will early return, but the *launcher* (i.e. the shell). As I mentioned in https://gitlab.gnome.org/GNOME/gnome-shell/issues/267: """ I've been working on this and I think I have a patch for the shell that would fix this problem by making sure that the shell completes any startup sequence that might have been initiated for a process being launched that exit successfully (exit code 0) without ever having shown a top level window. It's technically not a case where "the launchee fails" (as per the spec), but still seems to make sense to me to that the shell cleaning up, since at the point g-c-c (or any other similar process) exits early, that's the only place where you know the startup sequence's ID and, therefore, the only place where the process can be properly completed. """ Therefore, I'm closing this GLib bug as invalid and moving the discussion to https://gitlab.gnome.org/GNOME/gnome-shell/issues/267 instead.