File gnome-shell-background-image-change.patch of Package gnome-shell.160

diff -Npur gnome-shell-3.10.4/js/ui/background.js gnome-shell-3.10.4-new/js/ui/background.js
--- gnome-shell-3.10.4/js/ui/background.js	2014-07-22 02:50:59.681192579 +0800
+++ gnome-shell-3.10.4-new/js/ui/background.js	2014-07-23 06:56:16.767305520 +0800
@@ -40,6 +40,7 @@ const BackgroundCache = new Lang.Class({
        this._images = [];
        this._pendingFileLoads = [];
        this._fileMonitors = {};
+       this._animations = [];
     },
 
     getPatternContent: function(params) {
@@ -131,6 +132,25 @@ const BackgroundCache = new Lang.Class({
         this._removeContent(this._images, content);
     },
 
+    _attachCallerToFileLoad: function(caller, fileLoad) {
+        fileLoad.callers.push(caller);
+
+        if (!caller.cancellable)
+            return;
+
+        caller.cancellable.connect(Lang.bind(this, function() {
+            let idx = fileLoad.callers.indexOf(caller);
+            fileLoad.callers.splice(idx, 1);
+
+            if (fileLoad.callers.length == 0) {
+                fileLoad.cancellable.cancel();
+
+                let idx = this._pendingFileLoads.indexOf(fileLoad);
+                this._pendingFileLoads.splice(idx, 1);
+            }
+        }));
+    },
+
     _loadImageContent: function(params) {
         params = Params.parse(params, { monitorIndex: 0,
                                         style: null,
@@ -139,27 +159,27 @@ const BackgroundCache = new Lang.Class({
                                         cancellable: null,
                                         onFinished: null });
 
+        let caller = { monitorIndex: params.monitorIndex,
+                       effects: params.effects,
+                       cancellable: params.cancellable,
+                       onFinished: params.onFinished };
+
         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 });
+            let fileLoad = this._pendingFileLoads[i];
+
+            if (fileLoad.filename == params.filename &&
+                fileLoad.style == params.style) {
+                this._attachCallerToFileLoad(caller, fileLoad);
                 return;
             }
         }
+        let fileLoad = { filename: params.filename,
+                         style: params.style,
+                         cancellable: new Gio.Cancellable(),
+                         callers: [] };
+        this._attachCallerToFileLoad(caller, fileLoad);
 
-        this._pendingFileLoads.push({ filename: params.filename,
-                                      style: params.style,
-                                      callers: [{ shouldCopy: false,
-                                                  monitorIndex: params.monitorIndex,
-                                                  effects: params.effects,
-                                                  onFinished: params.onFinished }] });
-
-        let content = new Meta.Background({ meta_screen: global.screen,
-                                            monitor: params.monitorIndex,
-                                            effects: params.effects });
+        let content = new Meta.Background({ meta_screen: global.screen });
 
         content.load_file_async(params.filename,
                                 params.style,
@@ -170,35 +190,26 @@ const BackgroundCache = new Lang.Class({
                                                   content.load_file_finish(result);
 
                                                   this._monitorFile(params.filename);
-                                                  this._images.push(content);
                                               } catch(e) {
                                                   content = null;
                                               }
 
-                                              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);
+                                              for (let i = 0; i < fileLoad.callers.length; i++) {
+                                                  let caller = fileLoad.callers[i];
+                                                  if (caller.onFinished) {
+                                                      let newContent;
+
+                                                      if (content) {
+                                                          newContent = content.copy(caller.monitorIndex, caller.effects);
+                                                          this._images.push(newContent);
                                                       }
-                                                  }
 
-                                                  this._pendingFileLoads.splice(i, 1);
+                                                      caller.onFinished(newContent);
+                                                  }
                                               }
+
+                                              let idx = this._pendingFileLoads.indexOf(fileLoad);
+                                              this._pendingFileLoads.splice(idx, 1);
                                           }));
     },
 
@@ -257,25 +268,34 @@ const BackgroundCache = new Lang.Class({
         params = Params.parse(params, { filename: null,
                                         onLoaded: null });
 
-        if (this._animationFilename == params.filename) {
-            if (params.onLoaded) {
-                GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
-                    params.onLoaded(this._animation);
-                }));
+        let i;
+        let animation = null;
+        for (i = 0; i < this._animations.length; i++) {
+            if (this._animations[i].filename == params.filename) {
+                animation = this._animations[i];
+                if (params.onLoaded) {
+                    let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
+                        params.onLoaded(this._animation);
+                        return GLib.SOURCE_REMOVE;
+                    }));
+                    GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
+                }
             }
         }
 
-        let animation = new Animation({ filename: params.filename });
-
+        if (animation == null) {
+            animation = new Animation({ filename: params.filename });
+            this._animations.push(animation);
+        }
         animation.load(Lang.bind(this, function() {
                            this._monitorFile(params.filename);
-                           this._animationFilename = params.filename;
-                           this._animation = animation;
 
                            if (params.onLoaded) {
-                               GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
-                                   params.onLoaded(this._animation);
+                               let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
+                                   params.onLoaded(animation);
+                                   return GLib.SOURCE_REMOVE;
                                }));
+                               GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
                            }
                        }));
     }
openSUSE Build Service is sponsored by