shell/app: Re-order running-state cleanup

Since commit 1807be1, we clear the fallback icon when a window is
removed, and notify the icon change. The notify call currently
happens after removing the window from the running state, but
before syncing the state (and possibly clear the running state
altogether).

That state is inconsistent and results in an assertion hit when
some code tries to re-fetch the icon in response to the notify
call.

Address this by updating the state before clearing the fallback
icon, so that the app will be in the correct STOPPED state after
removing the last window.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4888

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2073>
This commit is contained in:
Florian Müllner 2021-12-22 01:53:17 +01:00
parent 7e0c6dc2c1
commit 331454a757

View File

@ -1140,6 +1140,13 @@ _shell_app_remove_window (ShellApp *app,
app->running_state->windows = g_slist_remove (app->running_state->windows, window); app->running_state->windows = g_slist_remove (app->running_state->windows, window);
if (!meta_window_is_skip_taskbar (window))
app->running_state->interesting_windows--;
shell_app_sync_running_state (app);
if (app->running_state->windows == NULL)
g_clear_pointer (&app->running_state, unref_running_state);
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(shell_app_on_user_time_changed), app); g_signal_handlers_disconnect_by_func (window, G_CALLBACK(shell_app_on_user_time_changed), app);
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(shell_app_on_skip_taskbar_changed), app); g_signal_handlers_disconnect_by_func (window, G_CALLBACK(shell_app_on_skip_taskbar_changed), app);
if (window == app->fallback_icon_window) if (window == app->fallback_icon_window)
@ -1152,15 +1159,8 @@ _shell_app_remove_window (ShellApp *app,
g_object_notify (G_OBJECT (app), "icon"); g_object_notify (G_OBJECT (app), "icon");
} }
if (!meta_window_is_skip_taskbar (window))
app->running_state->interesting_windows--;
shell_app_sync_running_state (app);
g_object_unref (window); g_object_unref (window);
if (app->running_state->windows == NULL)
g_clear_pointer (&app->running_state, unref_running_state);
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0); g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
} }