diff --git a/gnome-shell-3.11.90-background.patch b/gnome-shell-3.11.90-background.patch new file mode 100644 index 0000000..f082396 --- /dev/null +++ b/gnome-shell-3.11.90-background.patch @@ -0,0 +1,183 @@ +From b5d7bd02b514b9862203ff30435b6c98766143ef Mon Sep 17 00:00:00 2001 +From: "Jasper St. Pierre" +Date: Mon, 13 Jan 2014 18:42:32 -0500 +Subject: [PATCH] background: Fix cancellable issues + +If we have the following sequence: + + cache.getImageContent({ filename: "foo", cancellable: cancellable1 }); + cache.getImageContent({ filename: "foo", cancellable: cancellable2 }); + cancellable1.cancel(); + +Then the second load will complete with "null" as its content, even though +it was never cancelled, and we'll see a blank image. Meanwhile, since the +second load simply appends to the list of callers for the second load, +cancellable2 does absolutely nothing: cancelling it won't stop the load, +and it will still receive onFinished handling. + +To prevent this from happening, give the actual load operation its own +Gio.Cancellable, which is "ref-counted" -- only cancel it when all the other +possible callers cancel. + +Additionally, clean up the large nested loops by splitting out duplicated +code and other stuff. + +https://bugzilla.gnome.org/show_bug.cgi?id=722149 +--- + js/ui/background.js | 120 ++++++++++++++++++++++++++++------------------------ + 1 file changed, 65 insertions(+), 55 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 3a7541c..a3224f5 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -132,6 +132,46 @@ const BackgroundCache = new Lang.Class({ + this._removeContent(this._images, content); + }, + ++ _loadImageContentInternal: function(filename, style) { ++ let cancellable = new Gio.Cancellable(); ++ let content = new Meta.Background({ meta_screen: global.screen }); ++ ++ let info = { filename: filename, ++ style: style, ++ cancellable: cancellable, ++ callers: [] }; ++ ++ content.load_file_async(filename, style, cancellable, Lang.bind(this, function(object, result) { ++ if (cancellable.is_cancelled()) ++ return; ++ ++ try { ++ content.load_file_finish(result); ++ } catch(e) { ++ content = null; ++ } ++ ++ if (content) { ++ this._monitorFile(filename); ++ info.callers.forEach(Lang.bind(this, function(caller) { ++ let newContent = content.copy(caller.monitorIndex, caller.effects); ++ this._images.push(newContent); ++ caller.onFinished(newContent); ++ })); ++ } else { ++ info.callers.forEach(Lang.bind(this, function(caller) { ++ caller.onFinished(null); ++ })); ++ } ++ ++ let idx = this._pendingFileLoads.indexOf(info); ++ this._pendingFileLoads.splice(idx, 1); ++ })); ++ ++ this._pendingFileLoads.push(info); ++ return info; ++ }, ++ + _loadImageContent: function(params) { + params = Params.parse(params, { monitorIndex: 0, + style: null, +@@ -140,67 +180,38 @@ const BackgroundCache = new Lang.Class({ + cancellable: null, + onFinished: null }); + ++ let caller = { monitorIndex: params.monitorIndex, ++ effects: params.effects, ++ cancellable: params.cancellable, ++ onFinished: params.onFinished }; ++ ++ let info = null; + for (let i = 0; i < this._pendingFileLoads.length; i++) { +- if (this._pendingFileLoads[i].filename == params.filename && +- this._pendingFileLoads[i].style == params.style) { +- this._pendingFileLoads[i].callers.push({ shouldCopy: true, +- monitorIndex: params.monitorIndex, +- effects: params.effects, +- onFinished: params.onFinished }); +- return; ++ let pendingLoad = this._pendingFileLoads[i]; ++ if (pendingLoad.filename == params.filename && pendingLoad.style == params.style) { ++ info = pendingLoad; ++ break; + } + } + +- this._pendingFileLoads.push({ filename: params.filename, +- style: params.style, +- callers: [{ shouldCopy: false, +- monitorIndex: params.monitorIndex, +- effects: params.effects, +- onFinished: params.onFinished }] }); ++ if (!info) ++ info = this._loadImageContentInternal(params.filename, params.style); + +- let content = new Meta.Background({ meta_screen: global.screen, +- monitor: params.monitorIndex, +- effects: params.effects }); ++ info.callers.push(caller); + +- content.load_file_async(params.filename, +- params.style, +- params.cancellable, +- Lang.bind(this, +- function(object, result) { +- try { +- content.load_file_finish(result); +- +- this._monitorFile(params.filename); +- this._images.push(content); +- } catch(e) { +- content = null; +- } ++ if (caller.cancellable) { ++ caller.cancellable.connect(Lang.bind(this, function() { ++ let idx = info.callers.indexOf(caller); ++ info.callers.splice(idx, 1); + +- for (let i = 0; i < this._pendingFileLoads.length; i++) { +- let pendingLoad = this._pendingFileLoads[i]; +- if (pendingLoad.filename != params.filename || +- pendingLoad.style != params.style) +- continue; +- +- for (let j = 0; j < pendingLoad.callers.length; j++) { +- if (pendingLoad.callers[j].onFinished) { +- let newContent; +- +- if (content && pendingLoad.callers[j].shouldCopy) { +- newContent = content.copy(pendingLoad.callers[j].monitorIndex, +- pendingLoad.callers[j].effects); +- this._images.push(newContent); +- } else { +- newContent = content; +- } +- +- pendingLoad.callers[j].onFinished(newContent); +- } +- } +- +- this._pendingFileLoads.splice(i, 1); +- } +- })); ++ if (info.callers.length == 0) { ++ info.cancellable.cancel(); ++ ++ let idx = this._pendingFileLoads.indexOf(info); ++ this._pendingFileLoads.splice(idx, 1); ++ } ++ })); ++ } + }, + + getImageContent: function(params) { +@@ -250,7 +261,6 @@ const BackgroundCache = new Lang.Class({ + monitorIndex: params.monitorIndex, + cancellable: params.cancellable, + onFinished: params.onFinished }); +- + } + }, + +-- +1.8.5.3 diff --git a/gnome-shell-3.11.90-wifi_secrets.patch b/gnome-shell-3.11.90-wifi_secrets.patch new file mode 100644 index 0000000..4822b94 --- /dev/null +++ b/gnome-shell-3.11.90-wifi_secrets.patch @@ -0,0 +1,137 @@ +From 725f5c83303a192ccf008b963e21592cf8f9fc90 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Thu, 20 Feb 2014 15:10:36 -0600 +Subject: [PATCH] NetworkAgent: fix initial secrets requests after 17726abb + +While the named commit was correct for VPN connections, it didn't +work correctly for the initial secrets requests like when connecting +to a new access point. In that case, secrets *should* be requested +when none are found, but only if interaction is enabled. The +bits of 17726abb which removed checking secrets against the hints +*were* correct, but 17726abb removed too much. + +Also, to ensure passwords don't get inadvertently cleared when +simply reading them from the keyring, don't save passwords +unless something might have changed. + +https://bugzilla.gnome.org/show_bug.cgi?id=724779 +--- + src/shell-network-agent.c | 26 ++++++++++++++++++-------- + 1 file changed, 18 insertions(+), 8 deletions(-) + +diff --git a/src/shell-network-agent.c b/src/shell-network-agent.c +index 8d2b9b2..c6f4b79 100644 +--- a/src/shell-network-agent.c ++++ b/src/shell-network-agent.c +@@ -252,14 +252,15 @@ get_secrets_keyring_cb (GObject *source, + ShellNetworkAgent *self; + ShellNetworkAgentPrivate *priv; + GError *secret_error = NULL; + GError *error = NULL; + GList *items; + GList *l; + GHashTable *outer; ++ gboolean secrets_found = FALSE; + + items = secret_service_search_finish (NULL, result, &secret_error); + + if (g_error_matches (secret_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + { + g_error_free (secret_error); + return; +@@ -308,30 +309,36 @@ get_secrets_keyring_cb (GObject *source, + g_value_set_string (secret_value, secret_value_get (secret, NULL)); + + g_hash_table_insert (closure->entries, secret_name, secret_value); + } + else + g_hash_table_insert (closure->vpn_entries, secret_name, g_strdup (secret_value_get (secret, NULL))); + ++ secrets_found = TRUE; ++ + g_hash_table_unref (attributes); + secret_value_unref (secret); + break; + } + } + + g_hash_table_unref (attributes); + secret_value_unref (secret); + } + + g_list_free_full (items, g_object_unref); + + /* All VPN requests get sent to the VPN's auth dialog, since it knows better +- * than the agent do about what secrets are required. ++ * than the agent about what secrets are required. Otherwise, if no secrets ++ * were found and interaction is allowed the ask for some secrets, because ++ * NetworkManager will fail the connection if not secrets are returned ++ * instead of asking again with REQUEST_NEW. + */ +- if (closure->is_vpn) ++ if (closure->is_vpn || ++ (!secrets_found && (closure->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION))) + { + nm_connection_update_secrets (closure->connection, closure->setting_name, closure->entries, NULL); + + request_secrets_from_ui (closure); + return; + } + +@@ -459,15 +466,14 @@ shell_network_agent_set_password (ShellNetworkAgent *self, + void + shell_network_agent_respond (ShellNetworkAgent *self, + gchar *request_id, + ShellNetworkAgentResponse response) + { + ShellNetworkAgentPrivate *priv; + ShellAgentRequest *request; +- NMConnection *dup; + GHashTable *outer; + + g_return_if_fail (SHELL_IS_NETWORK_AGENT (self)); + + priv = self->priv; + request = g_hash_table_lookup (priv->requests, request_id); + g_return_if_fail (request != NULL); +@@ -494,27 +500,31 @@ shell_network_agent_respond (ShellNetworkAgent *self, + g_error_free (error); + g_hash_table_remove (priv->requests, request_id); + return; + } + + /* response == SHELL_NETWORK_AGENT_CONFIRMED */ + +- /* Save updated secrets */ +- dup = nm_connection_duplicate (request->connection); ++ /* Save any updated secrets */ ++ if ((request->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION) || ++ (request->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW)) ++ { ++ NMConnection *dup = nm_connection_duplicate (request->connection); + +- nm_connection_update_secrets (dup, request->setting_name, request->entries, NULL); +- nm_secret_agent_save_secrets (NM_SECRET_AGENT (self), dup, NULL, NULL); ++ nm_connection_update_secrets (dup, request->setting_name, request->entries, NULL); ++ nm_secret_agent_save_secrets (NM_SECRET_AGENT (self), dup, NULL, NULL); ++ g_object_unref (dup); ++ } + + outer = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (outer, request->setting_name, request->entries); + + request->callback (NM_SECRET_AGENT (self), request->connection, outer, NULL, request->callback_data); + + g_hash_table_destroy (outer); +- g_object_unref (dup); + g_hash_table_remove (priv->requests, request_id); + } + + static void + shell_network_agent_cancel_get_secrets (NMSecretAgent *agent, + const gchar *connection_path, + const gchar *setting_name) +-- +1.8.5.3 + + diff --git a/gnome-shell.spec b/gnome-shell.spec index bdac6b3..3f6d56c 100644 --- a/gnome-shell.spec +++ b/gnome-shell.spec @@ -1,6 +1,6 @@ Name: gnome-shell Version: 3.11.90 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Window management and application launching for GNOME Group: User Interface/Desktops @@ -13,6 +13,12 @@ Source0: http://download.gnome.org/sources/gnome-shell/3.11/%{name}-%{ver # Replace Epiphany with Firefox in the default favourite apps list Patch1: gnome-shell-favourite-apps-firefox.patch +# https://bugzilla.gnome.org/show_bug.cgi?id=722149 +Patch2: gnome-shell-3.11.90-background.patch + +# https://bugzilla.gnome.org/show_bug.cgi?id=724779 +Patch3: gnome-shell-3.11.90-wifi_secrets.patch + %define clutter_version 1.13.4 %define gnome_bluetooth_version 1:3.9.0 %define gobject_introspection_version 0.10.1 @@ -116,6 +122,8 @@ easy to use experience. %prep %setup -q %patch1 -p1 -b .firefox +%patch2 -p1 -b .background +%patch3 -p1 -b .wifi_secrets %build (if ! test -x configure; then NOCONFIGURE=1 ./autogen.sh; fi; @@ -175,6 +183,9 @@ glib-compile-schemas --allow-any-name %{_datadir}/glib-2.0/schemas &> /dev/null %exclude %{_datadir}/gtk-doc %changelog +* Wed Feb 26 2014 Adam Williamson - 3.11.90-4 +- backport a couple of bugfixes from BGO for things that annoy me + * Sat Feb 22 2014 Florian Müllner - 3.11.90-3 - Add dependency on gnome-control-center - several panels are referenced by a number of menu items