From e4a6bf994fb5c0a2abaa91b12ffae1f534d122c1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 7 Jun 2010 16:31:30 -0400 Subject: [PATCH] Fix ShellAppSystem's use of no_focus_window, clean up state handling First, we were passing an incorrect timestamp to meta_display_focus_the_no_focus_window - fix that. The invocation of set_focus_app to the started app there couldn't really work, because (if the above call had worked) we'd get the X reply *after* the started app. What we need to untangle here is the distinction that's now made in ShellApp between _STATE_STARTING and _STATE_RUNNING. A nice way to start doing this is to rebase ShellWindowTracker to only be concerned with app states. Concretely, the current "has windows implies running" logic now lives just inside shell-app.c. Rename the app-running-changed signal to be app-state-changed. This will ultimately be useful so that inside the panel, we can track the last started app. https://bugzilla.gnome.org/show_bug.cgi?id=620899 --- js/ui/appDisplay.js | 2 +- js/ui/panel.js | 2 +- src/Makefile.am | 3 +- src/shell-app-usage.c | 10 +++--- src/shell-app.c | 4 ++- src/shell-window-tracker.c | 64 ++++++++++++++++++++------------------ 6 files changed, 45 insertions(+), 40 deletions(-) diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 471a65c85..f43af8e87 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -1078,7 +1078,7 @@ AppWell.prototype = { this._appSystem.connect('installed-changed', Lang.bind(this, this._queueRedisplay)); AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay)); - this._tracker.connect('app-running-changed', Lang.bind(this, this._queueRedisplay)); + this._tracker.connect('app-state-changed', Lang.bind(this, this._queueRedisplay)); }, _appIdListToHash: function(apps) { diff --git a/js/ui/panel.js b/js/ui/panel.js index aab4a03aa..6546e8b5c 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -697,7 +697,7 @@ AppMenuButton.prototype = { // cases where the focused window's application changes without the focus // changing. An example case is how we map Firefox based on the window // title which is a dynamic property. - tracker.connect('app-running-changed', Lang.bind(this, this._sync)); + tracker.connect('app-state-changed', Lang.bind(this, this._sync)); this._sync(); }, diff --git a/src/Makefile.am b/src/Makefile.am index 5ab98c351..ffc546909 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,7 +116,8 @@ libgnome_shell_la_SOURCES = \ non_gir_sources = \ shell-embedded-window-private.h \ - shell-global-private.h + shell-global-private.h \ + shell-window-tracker-private.h shell_recorder_sources = \ shell-recorder.c \ diff --git a/src/shell-app-usage.c b/src/shell-app-usage.c index 2210f1736..2cddffaca 100644 --- a/src/shell-app-usage.c +++ b/src/shell-app-usage.c @@ -313,9 +313,9 @@ increment_usage_for_app (ShellAppUsage *self, } static void -on_app_running_changed (ShellWindowTracker *tracker, - ShellApp *app, - gpointer user_data) +on_app_state_changed (ShellWindowTracker *tracker, + ShellApp *app, + gpointer user_data) { ShellAppUsage *self = SHELL_APP_USAGE (user_data); UsageData *usage; @@ -326,7 +326,7 @@ on_app_running_changed (ShellWindowTracker *tracker, usage = get_usage_for_app (self, app); - running = shell_app_get_n_windows (app) > 0; + running = shell_app_get_state (app) == SHELL_APP_STATE_RUNNING; usage->last_seen = get_time (); } @@ -389,7 +389,7 @@ shell_app_usage_init (ShellAppUsage *self) tracker = shell_window_tracker_get_default (); g_signal_connect (tracker, "notify::focus-app", G_CALLBACK (on_focus_app_changed), self); - g_signal_connect (tracker, "app-running-changed", G_CALLBACK (on_app_running_changed), self); + g_signal_connect (tracker, "app-state-changed", G_CALLBACK (on_app_state_changed), self); session_bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); self->session_proxy = dbus_g_proxy_new_for_name (session_bus, "org.gnome.SessionManager", diff --git a/src/shell-app.c b/src/shell-app.c index b62799491..dca21a283 100644 --- a/src/shell-app.c +++ b/src/shell-app.c @@ -8,7 +8,7 @@ #include "shell-enum-types.h" #include "display.h" #include "st.h" -#include "shell-window-tracker.h" +#include "shell-window-tracker-private.h" #include @@ -632,6 +632,8 @@ shell_app_state_transition (ShellApp *app, state == SHELL_APP_STATE_STARTING)); app->state = state; g_object_notify (G_OBJECT (app), "state"); + + _shell_window_tracker_notify_app_state_changed (shell_window_tracker_get_default (), app); } static void diff --git a/src/shell-window-tracker.c b/src/shell-window-tracker.c index 4a5d3a2e6..e2957d9e6 100644 --- a/src/shell-window-tracker.c +++ b/src/shell-window-tracker.c @@ -13,7 +13,7 @@ #define SN_API_NOT_YET_FROZEN 1 #include -#include "shell-window-tracker.h" +#include "shell-window-tracker-private.h" #include "shell-app-system.h" #include "shell-app-private.h" #include "st/st-texture-cache.h" @@ -64,7 +64,6 @@ struct _ShellWindowTracker { GObject parent; - guint idle_focus_change_id; ShellApp *focus_app; /* */ @@ -82,7 +81,7 @@ enum { }; enum { - APP_RUNNING_CHANGED, + APP_STATE_CHANGED, STARTUP_SEQUENCE_CHANGED, TRACKED_WINDOWS_CHANGED, @@ -135,14 +134,14 @@ shell_window_tracker_class_init (ShellWindowTrackerClass *klass) SHELL_TYPE_APP, G_PARAM_READABLE)); - signals[APP_RUNNING_CHANGED] = g_signal_new ("app-running-changed", - SHELL_TYPE_WINDOW_TRACKER, - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - SHELL_TYPE_APP); + signals[APP_STATE_CHANGED] = g_signal_new ("app-state-changed", + SHELL_TYPE_WINDOW_TRACKER, + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + SHELL_TYPE_APP); signals[STARTUP_SEQUENCE_CHANGED] = g_signal_new ("startup-sequence-changed", SHELL_TYPE_WINDOW_TRACKER, G_SIGNAL_RUN_LAST, @@ -516,14 +515,6 @@ track_window (ShellWindowTracker *self, _shell_app_add_window (app, window); - if (shell_app_get_n_windows (app) == 1) - { - /* key is owned by the app */ - g_hash_table_insert (self->running_apps, (char*)shell_app_get_id (app), - app); - g_signal_emit (self, signals[APP_RUNNING_CHANGED], 0, app); - } - g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0); } @@ -553,13 +544,6 @@ disassociate_window (ShellWindowTracker *self, _shell_app_remove_window (app, window); - if (shell_app_get_n_windows (app) == 0) - { - const char *id = shell_app_get_id (app); - g_hash_table_remove (self->running_apps, id); - g_signal_emit (self, signals[APP_RUNNING_CHANGED], 0, app); - } - g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0); g_object_unref (app); @@ -643,6 +627,27 @@ init_window_tracking (ShellWindowTracker *self) shell_window_tracker_on_n_workspaces_changed (screen, NULL, self); } +void +_shell_window_tracker_notify_app_state_changed (ShellWindowTracker *self, + ShellApp *app) +{ + ShellAppState state = shell_app_get_state (app); + + switch (state) + { + case SHELL_APP_STATE_RUNNING: + /* key is owned by the app */ + g_hash_table_insert (self->running_apps, (char*)shell_app_get_id (app), app); + break; + case SHELL_APP_STATE_STARTING: + break; + case SHELL_APP_STATE_STOPPED: + g_hash_table_remove (self->running_apps, shell_app_get_id (app)); + break; + } + g_signal_emit (self, signals[APP_STATE_CHANGED], 0, app); +} + static void on_startup_sequence_changed (MetaScreen *screen, SnStartupSequence *sequence, @@ -665,13 +670,10 @@ on_startup_sequence_changed (MetaScreen *screen, { MetaScreen *screen = shell_global_get_screen (shell_global_get ()); MetaDisplay *display = meta_screen_get_display (screen); - long tv_sec, tv_usec; - - sn_startup_sequence_get_initiated_time (sequence, &tv_sec, &tv_usec); _shell_app_set_starting (app, starting); - set_focus_app (self, app); - meta_display_focus_the_no_focus_window (display, screen, tv_sec); + meta_display_focus_the_no_focus_window (display, screen, + sn_startup_sequence_get_timestamp (sequence)); } }