Compare commits

...

2 Commits

Author SHA1 Message Date
Mario Sanchez Prada
969db82f5a shell-app: Finish startup sequence for process that exit too early
If a process associated to an application declaring StartupNotify=true
in its desktop file exits before having ever mapped a top level window,
the "remove" X message expected as per the Startup Notification Spec [1]
won't ever be issued, and the shell will keep waiting for a while until
the sequence is finished on time out.

This provides a confusing and bad experience since things like a confusing
icon + a spinner, or the mouse pointer switching to a spinning cursor, will
be showing up in the meantime, so we need to detect those situations and
make sure the sequence gets completed, and the app moved to STOPPED.

[1] https://www.freedesktop.org/wiki/Specifications/startup-notification-spec

Closes: #267
2018-05-17 17:10:05 +01:00
Mario Sanchez Prada
6ee13ff685 window-tracker: Add new public method shell_startup_sequence_complete()
We need to provide a wrapper for sn_startup_sequence_complete() from libsn,
so that's there's a way to make sure that the startup sequence gets always
finished, even if the launched process exits early without an error code
before ever having mapped a top level window (i.e. gnome-control-center).

Closes: #267
2018-05-17 17:09:57 +01:00
3 changed files with 35 additions and 3 deletions

View File

@ -1190,12 +1190,37 @@ app_child_setup (gpointer user_data)
} }
#endif #endif
static void
_shell_app_watch_callback (GPid pid,
gint status,
ShellApp *app)
{
if (app->state == SHELL_APP_STATE_STARTING)
{
ShellWindowTracker *tracker = shell_window_tracker_get_default ();
GSList *startup_sequences = shell_window_tracker_get_startup_sequences (tracker);
GSList *iter = NULL;
for (iter = startup_sequences; iter; iter = g_slist_next (iter))
{
ShellStartupSequence *sequence = (ShellStartupSequence*) iter->data;
ShellApp *startup_app = shell_startup_sequence_get_app (sequence);
if (startup_app == app)
shell_startup_sequence_complete (sequence);
}
shell_app_state_transition (app, SHELL_APP_STATE_STOPPED);
}
g_spawn_close_pid (pid);
}
static void static void
wait_pid (GDesktopAppInfo *appinfo, wait_pid (GDesktopAppInfo *appinfo,
GPid pid, GPid pid,
gpointer user_data) ShellApp *app)
{ {
g_child_watch_add (pid, (GChildWatchFunc) g_spawn_close_pid, NULL); g_child_watch_add (pid, (GChildWatchFunc) _shell_app_watch_callback, app);
} }
/** /**
@ -1242,7 +1267,8 @@ shell_app_launch (ShellApp *app,
#else #else
NULL, NULL, NULL, NULL,
#endif #endif
wait_pid, NULL, (GDesktopAppLaunchCallback) wait_pid,
app,
error); error);
g_object_unref (context); g_object_unref (context);

View File

@ -906,6 +906,11 @@ shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size)
return texture; return texture;
} }
void
shell_startup_sequence_complete (ShellStartupSequence *sequence)
{
sn_startup_sequence_complete ((SnStartupSequence*)sequence);
}
/** /**
* shell_window_tracker_get_default: * shell_window_tracker_get_default:

View File

@ -36,6 +36,7 @@ const char *shell_startup_sequence_get_name (ShellStartupSequence *sequence);
gboolean shell_startup_sequence_get_completed (ShellStartupSequence *sequence); gboolean shell_startup_sequence_get_completed (ShellStartupSequence *sequence);
int shell_startup_sequence_get_workspace (ShellStartupSequence *sequence); int shell_startup_sequence_get_workspace (ShellStartupSequence *sequence);
ClutterActor *shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size); ClutterActor *shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size);
void shell_startup_sequence_complete (ShellStartupSequence *sequence);
G_END_DECLS G_END_DECLS