Blame SOURCES/fix-background-leaks.patch

4c1248
From cdee11381cfb10a93fb41d014b989a4968068b0c Mon Sep 17 00:00:00 2001
4c1248
From: Adel Gadllah <adel.gadllah@gmail.com>
4c1248
Date: Thu, 15 Aug 2013 21:51:46 +0200
4c1248
Subject: [PATCH 01/13] Revert "background: fix asynchronous management of
4c1248
 background loading operations"
4c1248
4c1248
This reverts commit 1020d8a0f8523a04d8336b1348388b8b242e414f.
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=704646
4c1248
---
4c1248
 js/ui/background.js | 69 +++++++++++++++++++----------------------------------
4c1248
 1 file changed, 25 insertions(+), 44 deletions(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 13343c6..1d9ab7c 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -142,40 +142,33 @@ const BackgroundCache = new Lang.Class({
4c1248
                                         cancellable: null,
4c1248
                                         onFinished: null });
4c1248
 
4c1248
-        let fileLoad = { filename: params.filename,
4c1248
-                         style: params.style,
4c1248
-                         shouldCopy: false,
4c1248
-                         monitorIndex: params.monitorIndex,
4c1248
-                         effects: params.effects,
4c1248
-                         onFinished: params.onFinished,
4c1248
-                         cancellable: new Gio.Cancellable(), };
4c1248
-        this._pendingFileLoads.push(fileLoad);
4c1248
-
4c1248
-        if (params.cancellable) {
4c1248
-            params.cancellable.connect(Lang.bind(this, function(c) {
4c1248
-               fileLoad.cancellable.cancel();
4c1248
-            }));
4c1248
+        for (let i = 0; i < this._pendingFileLoads.length; i++) {
4c1248
+            if (this._pendingFileLoads[i].filename == params.filename &&
4c1248
+                this._pendingFileLoads[i].style == params.style) {
4c1248
+                this._pendingFileLoads[i].callers.push({ shouldCopy: true,
4c1248
+                                                         monitorIndex: params.monitorIndex,
4c1248
+                                                         effects: params.effects,
4c1248
+                                                         onFinished: params.onFinished });
4c1248
+                return;
4c1248
+            }
4c1248
         }
4c1248
 
4c1248
+        this._pendingFileLoads.push({ filename: params.filename,
4c1248
+                                      style: params.style,
4c1248
+                                      callers: [{ shouldCopy: false,
4c1248
+                                                  monitorIndex: params.monitorIndex,
4c1248
+                                                  effects: params.effects,
4c1248
+                                                  onFinished: params.onFinished }] });
4c1248
+
4c1248
         let content = new Meta.Background({ meta_screen: global.screen,
4c1248
                                             monitor: params.monitorIndex,
4c1248
                                             effects: params.effects });
4c1248
 
4c1248
         content.load_file_async(params.filename,
4c1248
                                 params.style,
4c1248
-                                fileLoad.cancellable,
4c1248
+                                params.cancellable,
4c1248
                                 Lang.bind(this,
4c1248
                                           function(object, result) {
4c1248
-                                              if (fileLoad.cancellable.is_cancelled()) {
4c1248
-                                                  if (params.cancellable && params.cancellable.is_cancelled()) {
4c1248
-                                                      if (params.onFinished)
4c1248
-                                                          params.onFinished(null);
4c1248
-                                                      this._removePendingFileLoad(fileLoad);
4c1248
-                                                      return;
4c1248
-                                                  }
4c1248
-                                                  return;
4c1248
-                                              }
4c1248
-
4c1248
                                               try {
4c1248
                                                   content.load_file_finish(result);
4c1248
 
4c1248
@@ -185,25 +178,22 @@ const BackgroundCache = new Lang.Class({
4c1248
                                                   content = null;
4c1248
                                               }
4c1248
 
4c1248
-                                              let needsCopy = false;
4c1248
                                               for (let i = 0; i < this._pendingFileLoads.length; i++) {
4c1248
                                                   let pendingLoad = this._pendingFileLoads[i];
4c1248
                                                   if (pendingLoad.filename != params.filename ||
4c1248
                                                       pendingLoad.style != params.style)
4c1248
                                                       continue;
4c1248
 
4c1248
-                                                  if (pendingLoad.cancellable.is_cancelled())
4c1248
-                                                      continue;
4c1248
+                                                  for (let j = 0; j < pendingLoad.callers.length; j++) {
4c1248
+                                                      if (pendingLoad.callers[j].onFinished) {
4c1248
+                                                          if (content && pendingLoad.callers[j].shouldCopy) {
4c1248
+                                                              content = object.copy(pendingLoad.callers[j].monitorIndex,
4c1248
+                                                                                    pendingLoad.callers[j].effects);
4c1248
 
4c1248
-                                                  pendingLoad.cancellable.cancel();
4c1248
-                                                  if (pendingLoad.onFinished) {
4c1248
-                                                      if (content && needsCopy) {
4c1248
-                                                          content = object.copy(pendingLoad.monitorIndex,
4c1248
-                                                                                pendingLoad.effects);
4c1248
-                                                      }
4c1248
+                                                          }
4c1248
 
4c1248
-                                                      needsCopy = true;
4c1248
-                                                      pendingLoad.onFinished(content);
4c1248
+                                                          pendingLoad.callers[j].onFinished(content);
4c1248
+                                                      }
4c1248
                                                   }
4c1248
 
4c1248
                                                   this._pendingFileLoads.splice(i, 1);
4c1248
@@ -211,15 +201,6 @@ const BackgroundCache = new Lang.Class({
4c1248
                                           }));
4c1248
     },
4c1248
 
4c1248
-    _removePendingFileLoad: function(fileLoad) {
4c1248
-        for (let i = 0; i < this._pendingFileLoads.length; i++) {
4c1248
-            if (this._pendingFileLoads[i].cancellable == fileLoad.cancellable) {
4c1248
-                this._pendingFileLoads.splice(i, 1);
4c1248
-                break;
4c1248
-            }
4c1248
-        }
4c1248
-    },
4c1248
-
4c1248
     getImageContent: function(params) {
4c1248
         params = Params.parse(params, { monitorIndex: 0,
4c1248
                                         style: null,
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From 980a8618e1b89911c93183c461528bc9c3d465de Mon Sep 17 00:00:00 2001
4c1248
From: Adel Gadllah <adel.gadllah@gmail.com>
4c1248
Date: Wed, 2 Oct 2013 15:29:30 +0200
4c1248
Subject: [PATCH 02/13] background: Disconnect settings signal handler on
4c1248
 destroy
4c1248
4c1248
We connect to the changed signal in _init() but never actually disconnect from
4c1248
it. The callback has a reference to "this" which results into the background
4c1248
object not getting garbage collected.
4c1248
4c1248
Fix that leaks by disconnecting in _destroy()
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=709263
4c1248
---
4c1248
 js/ui/background.js | 10 +++++++---
4c1248
 1 file changed, 7 insertions(+), 3 deletions(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 1d9ab7c..b855b4e 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -318,9 +318,9 @@ const Background = new Lang.Class({
4c1248
         this._cancellable = new Gio.Cancellable();
4c1248
         this.isLoaded = false;
4c1248
 
4c1248
-        this._settings.connect('changed', Lang.bind(this, function() {
4c1248
-                                   this.emit('changed');
4c1248
-                               }));
4c1248
+        this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() {
4c1248
+                                            this.emit('changed');
4c1248
+                                        }));
4c1248
 
4c1248
         this._load();
4c1248
     },
4c1248
@@ -361,6 +361,10 @@ const Background = new Lang.Class({
4c1248
 
4c1248
         this.actor.disconnect(this._destroySignalId);
4c1248
         this._destroySignalId = 0;
4c1248
+
4c1248
+        if (this._settingsChangedSignalId != 0)
4c1248
+            this._settings.disconnect(this._settingsChangedSignalId);
4c1248
+        this._settingsChangedSignalId = 0;
4c1248
     },
4c1248
 
4c1248
     _setLoaded: function() {
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From cfe72aa21a0aa8ea96dac81bfd6e532af62e9081 Mon Sep 17 00:00:00 2001
4c1248
From: Adel Gadllah <adel.gadllah@gmail.com>
4c1248
Date: Wed, 2 Oct 2013 15:48:39 +0200
4c1248
Subject: [PATCH 03/13] layout: Use monitor index when adding bg managers
4c1248
4c1248
Don't assume that this._bgManagers.push() (i.e adding to the end) is always
4c1248
correct.
4c1248
4c1248
On startup we call _createPrimaryBackground which passes in the primary index
4c1248
which may not be 0.
4c1248
---
4c1248
 js/ui/layout.js | 2 +-
4c1248
 1 file changed, 1 insertion(+), 1 deletion(-)
4c1248
4c1248
diff --git a/js/ui/layout.js b/js/ui/layout.js
4c1248
index e25b3bd..141eecc 100644
4c1248
--- a/js/ui/layout.js
4c1248
+++ b/js/ui/layout.js
4c1248
@@ -347,7 +347,7 @@ const LayoutManager = new Lang.Class({
4c1248
                               BackgroundMenu.addBackgroundMenu(bgManager.background.actor);
4c1248
                           }));
4c1248
 
4c1248
-        this._bgManagers.push(bgManager);
4c1248
+        this._bgManagers[monitorIndex] = bgManager;
4c1248
 
4c1248
         return bgManager.background;
4c1248
     },
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From 304c11552766963f51343d97f8257096e62abb15 Mon Sep 17 00:00:00 2001
4c1248
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
4c1248
Date: Fri, 14 Mar 2014 18:09:22 +0100
4c1248
Subject: [PATCH 04/13] background: Force a GC run after removing a background
4c1248
4c1248
---
4c1248
 js/ui/background.js | 10 ++++++++++
4c1248
 1 file changed, 10 insertions(+)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index b855b4e..0e4ff5d 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -6,8 +6,10 @@ const Gio = imports.gi.Gio;
4c1248
 const GLib = imports.gi.GLib;
4c1248
 const GnomeDesktop = imports.gi.GnomeDesktop;
4c1248
 const Lang = imports.lang;
4c1248
+const Mainloop = imports.mainloop;
4c1248
 const Meta = imports.gi.Meta;
4c1248
 const Signals = imports.signals;
4c1248
+const System = imports.system;
4c1248
 
4c1248
 const Main = imports.ui.main;
4c1248
 const Params = imports.misc.params;
4c1248
@@ -119,6 +121,14 @@ const BackgroundCache = new Lang.Class({
4c1248
 
4c1248
         if (index >= 0)
4c1248
             contentList.splice(index, 1);
4c1248
+
4c1248
+        if (!this._gcId)
4c1248
+            this._gcId = Mainloop.idle_add(Lang.bind(this,
4c1248
+                function() {
4c1248
+                    System.gc();
4c1248
+                    this._gcId = 0;
4c1248
+                    return false;
4c1248
+                }));
4c1248
     },
4c1248
 
4c1248
     removePatternContent: function(content) {
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From 1cd71c438f3ee5dc6ccbc68ef646d42128e6883b Mon Sep 17 00:00:00 2001
4c1248
From: "Jasper St. Pierre" <jstpierre@mecheye.net>
4c1248
Date: Tue, 3 Dec 2013 18:08:42 -0500
4c1248
Subject: [PATCH 05/13] background: Clarify the intent of the code
4c1248
4c1248
Stomping on local variables and trying to keep loop state isn't
4c1248
too fun. Just use a new variable here so we aren't too confused
4c1248
with what we're doing.
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=719803
4c1248
---
4c1248
 js/ui/background.js | 11 +++++++----
4c1248
 1 file changed, 7 insertions(+), 4 deletions(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 0e4ff5d..80a3bba 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -196,13 +196,16 @@ const BackgroundCache = new Lang.Class({
4c1248
 
4c1248
                                                   for (let j = 0; j < pendingLoad.callers.length; j++) {
4c1248
                                                       if (pendingLoad.callers[j].onFinished) {
4c1248
-                                                          if (content && pendingLoad.callers[j].shouldCopy) {
4c1248
-                                                              content = object.copy(pendingLoad.callers[j].monitorIndex,
4c1248
-                                                                                    pendingLoad.callers[j].effects);
4c1248
+                                                          let newContent;
4c1248
 
4c1248
+                                                          if (content && pendingLoad.callers[j].shouldCopy) {
4c1248
+                                                              newContent = content.copy(pendingLoad.callers[j].monitorIndex,
4c1248
+                                                                                        pendingLoad.callers[j].effects);
4c1248
+                                                          } else {
4c1248
+                                                              newContent = content;
4c1248
                                                           }
4c1248
 
4c1248
-                                                          pendingLoad.callers[j].onFinished(content);
4c1248
+                                                          pendingLoad.callers[j].onFinished(newContent);
4c1248
                                                       }
4c1248
                                                   }
4c1248
 
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From f86064aaf8753050582ead02d329aa9c36d0447c Mon Sep 17 00:00:00 2001
4c1248
From: "Jasper St. Pierre" <jstpierre@mecheye.net>
4c1248
Date: Tue, 3 Dec 2013 18:09:23 -0500
4c1248
Subject: [PATCH 06/13] background: Add copied content from pending image loads
4c1248
 to the cache
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=719803
4c1248
---
4c1248
 js/ui/background.js | 1 +
4c1248
 1 file changed, 1 insertion(+)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 80a3bba..6349148 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -201,6 +201,7 @@ const BackgroundCache = new Lang.Class({
4c1248
                                                           if (content && pendingLoad.callers[j].shouldCopy) {
4c1248
                                                               newContent = content.copy(pendingLoad.callers[j].monitorIndex,
4c1248
                                                                                         pendingLoad.callers[j].effects);
4c1248
+                                                              this._images.push(newContent);
4c1248
                                                           } else {
4c1248
                                                               newContent = content;
4c1248
                                                           }
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From 8964898af8dde2e425d5fde711d2e572d87249d3 Mon Sep 17 00:00:00 2001
4c1248
From: Ray Strode <rstrode@redhat.com>
4c1248
Date: Wed, 26 Feb 2014 14:35:38 -0500
4c1248
Subject: [PATCH 07/13] background: always copy background content when loading
4c1248
 into cache
4c1248
4c1248
Copying is actually a lightweight operation, so trying to avoid it just adds
4c1248
code complexity for little gain.
4c1248
4c1248
Based on work from Jasper St. Pierre <jstpierre@macheye.net>
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=722149
4c1248
---
4c1248
 js/ui/background.js | 15 ++++-----------
4c1248
 1 file changed, 4 insertions(+), 11 deletions(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 6349148..1e4d2ae 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -155,8 +155,7 @@ const BackgroundCache = new Lang.Class({
4c1248
         for (let i = 0; i < this._pendingFileLoads.length; i++) {
4c1248
             if (this._pendingFileLoads[i].filename == params.filename &&
4c1248
                 this._pendingFileLoads[i].style == params.style) {
4c1248
-                this._pendingFileLoads[i].callers.push({ shouldCopy: true,
4c1248
-                                                         monitorIndex: params.monitorIndex,
4c1248
+                this._pendingFileLoads[i].callers.push({ monitorIndex: params.monitorIndex,
4c1248
                                                          effects: params.effects,
4c1248
                                                          onFinished: params.onFinished });
4c1248
                 return;
4c1248
@@ -165,14 +164,11 @@ const BackgroundCache = new Lang.Class({
4c1248
 
4c1248
         this._pendingFileLoads.push({ filename: params.filename,
4c1248
                                       style: params.style,
4c1248
-                                      callers: [{ shouldCopy: false,
4c1248
-                                                  monitorIndex: params.monitorIndex,
4c1248
+                                      callers: [{ monitorIndex: params.monitorIndex,
4c1248
                                                   effects: params.effects,
4c1248
                                                   onFinished: params.onFinished }] });
4c1248
 
4c1248
-        let content = new Meta.Background({ meta_screen: global.screen,
4c1248
-                                            monitor: params.monitorIndex,
4c1248
-                                            effects: params.effects });
4c1248
+        let content = new Meta.Background({ meta_screen: global.screen });
4c1248
 
4c1248
         content.load_file_async(params.filename,
4c1248
                                 params.style,
4c1248
@@ -183,7 +179,6 @@ const BackgroundCache = new Lang.Class({
4c1248
                                                   content.load_file_finish(result);
4c1248
 
4c1248
                                                   this._monitorFile(params.filename);
4c1248
-                                                  this._images.push(content);
4c1248
                                               } catch(e) {
4c1248
                                                   content = null;
4c1248
                                               }
4c1248
@@ -198,12 +193,10 @@ const BackgroundCache = new Lang.Class({
4c1248
                                                       if (pendingLoad.callers[j].onFinished) {
4c1248
                                                           let newContent;
4c1248
 
4c1248
-                                                          if (content && pendingLoad.callers[j].shouldCopy) {
4c1248
+                                                          if (content) {
4c1248
                                                               newContent = content.copy(pendingLoad.callers[j].monitorIndex,
4c1248
                                                                                         pendingLoad.callers[j].effects);
4c1248
                                                               this._images.push(newContent);
4c1248
-                                                          } else {
4c1248
-                                                              newContent = content;
4c1248
                                                           }
4c1248
 
4c1248
                                                           pendingLoad.callers[j].onFinished(newContent);
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From 0975134611b07d35cc9dff9c1451c1dc8a2cbafc Mon Sep 17 00:00:00 2001
4c1248
From: Ray Strode <rstrode@redhat.com>
4c1248
Date: Wed, 26 Feb 2014 15:13:21 -0500
4c1248
Subject: [PATCH 08/13] background: refactor file loading
4c1248
4c1248
This commit moves the code around a bit such that the
4c1248
caller gets allocated up front and then a file load is either
4c1248
found or created to attach the caller to.
4c1248
4c1248
Functionally, the code is the same, it's just now factored in a way
4c1248
that will make it easier to fix a bug with cancellation later.
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=722149
4c1248
---
4c1248
 js/ui/background.js | 27 +++++++++++++++++----------
4c1248
 1 file changed, 17 insertions(+), 10 deletions(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 1e4d2ae..63b62a0 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -144,6 +144,10 @@ const BackgroundCache = new Lang.Class({
4c1248
         this._removeContent(this._images, content);
4c1248
     },
4c1248
 
4c1248
+    _attachCallerToFileLoad: function(caller, fileLoad) {
4c1248
+        fileLoad.callers.push(caller);
4c1248
+    },
4c1248
+
4c1248
     _loadImageContent: function(params) {
4c1248
         params = Params.parse(params, { monitorIndex: 0,
4c1248
                                         style: null,
4c1248
@@ -152,21 +156,24 @@ const BackgroundCache = new Lang.Class({
4c1248
                                         cancellable: null,
4c1248
                                         onFinished: null });
4c1248
 
4c1248
+        let caller = { monitorIndex: params.monitorIndex,
4c1248
+                       effects: params.effects,
4c1248
+                       onFinished: params.onFinished };
4c1248
+
4c1248
         for (let i = 0; i < this._pendingFileLoads.length; i++) {
4c1248
-            if (this._pendingFileLoads[i].filename == params.filename &&
4c1248
-                this._pendingFileLoads[i].style == params.style) {
4c1248
-                this._pendingFileLoads[i].callers.push({ monitorIndex: params.monitorIndex,
4c1248
-                                                         effects: params.effects,
4c1248
-                                                         onFinished: params.onFinished });
4c1248
+            let fileLoad = this._pendingFileLoads[i];
4c1248
+
4c1248
+            if (fileLoad.filename == params.filename &&
4c1248
+                fileLoad.style == params.style) {
4c1248
+                this._attachCallerToFileLoad(caller, fileLoad);
4c1248
                 return;
4c1248
             }
4c1248
         }
4c1248
 
4c1248
-        this._pendingFileLoads.push({ filename: params.filename,
4c1248
-                                      style: params.style,
4c1248
-                                      callers: [{ monitorIndex: params.monitorIndex,
4c1248
-                                                  effects: params.effects,
4c1248
-                                                  onFinished: params.onFinished }] });
4c1248
+        let fileLoad = { filename: params.filename,
4c1248
+                         style: params.style,
4c1248
+                         callers: [] };
4c1248
+        this._attachCallerToFileLoad(caller, fileLoad);
4c1248
 
4c1248
         let content = new Meta.Background({ meta_screen: global.screen });
4c1248
 
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From d5fdad361b7224e811921004be0d096cffb18f41 Mon Sep 17 00:00:00 2001
4c1248
From: Ray Strode <rstrode@redhat.com>
4c1248
Date: Wed, 26 Feb 2014 16:09:26 -0500
4c1248
Subject: [PATCH 09/13] background: get rid of nested loop when finishing file
4c1248
 loading
4c1248
4c1248
At the moment when a file is loaded, we iterate through the list of
4c1248
pending file loads and ignore any unrelated to the file, then iterate
4c1248
all the callers of the related file loads and finish them.
4c1248
4c1248
In fact, there can only ever be one pending file load related to the
4c1248
file, and we already know it, so we can avoid the ugly nested loops.
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=722149
4c1248
---
4c1248
 js/ui/background.js | 32 +++++++++++++-------------------
4c1248
 1 file changed, 13 insertions(+), 19 deletions(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 63b62a0..417f70d 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -190,28 +190,22 @@ const BackgroundCache = new Lang.Class({
4c1248
                                                   content = null;
4c1248
                                               }
4c1248
 
4c1248
-                                              for (let i = 0; i < this._pendingFileLoads.length; i++) {
4c1248
-                                                  let pendingLoad = this._pendingFileLoads[i];
4c1248
-                                                  if (pendingLoad.filename != params.filename ||
4c1248
-                                                      pendingLoad.style != params.style)
4c1248
-                                                      continue;
4c1248
-
4c1248
-                                                  for (let j = 0; j < pendingLoad.callers.length; j++) {
4c1248
-                                                      if (pendingLoad.callers[j].onFinished) {
4c1248
-                                                          let newContent;
4c1248
-
4c1248
-                                                          if (content) {
4c1248
-                                                              newContent = content.copy(pendingLoad.callers[j].monitorIndex,
4c1248
-                                                                                        pendingLoad.callers[j].effects);
4c1248
-                                                              this._images.push(newContent);
4c1248
-                                                          }
4c1248
-
4c1248
-                                                          pendingLoad.callers[j].onFinished(newContent);
4c1248
+                                              for (let i = 0; i < fileLoad.callers.length; i++) {
4c1248
+                                                  let caller = fileLoad.callers[i];
4c1248
+                                                  if (caller.onFinished) {
4c1248
+                                                      let newContent;
4c1248
+
4c1248
+                                                      if (content) {
4c1248
+                                                          newContent = content.copy(caller.monitorIndex, caller.effects);
4c1248
+                                                          this._images.push(newContent);
4c1248
                                                       }
4c1248
-                                                  }
4c1248
 
4c1248
-                                                  this._pendingFileLoads.splice(i, 1);
4c1248
+                                                      caller.onFinished(newContent);
4c1248
+                                                  }
4c1248
                                               }
4c1248
+
4c1248
+                                              let idx = this._pendingFileLoads.indexOf(fileLoad);
4c1248
+                                              this._pendingFileLoads.splice(idx, 1);
4c1248
                                           }));
4c1248
     },
4c1248
 
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From ef3fe7c12368f05e5187b89eb88a7454b9d43193 Mon Sep 17 00:00:00 2001
4c1248
From: Ray Strode <rstrode@redhat.com>
4c1248
Date: Wed, 26 Feb 2014 15:45:14 -0500
4c1248
Subject: [PATCH 10/13] background: fix cancellable issue
4c1248
4c1248
If we have the following sequence:
4c1248
4c1248
    cache.getImageContent({ filename: "foo", cancellable: cancellable1 });
4c1248
    cache.getImageContent({ filename: "foo", cancellable: cancellable2 });
4c1248
    cancellable1.cancel();
4c1248
4c1248
Then the second load will complete with "null" as its content, even though
4c1248
it was never cancelled, and we'll see a blank image. Meanwhile, since the
4c1248
second load simply appends to the list of callers for the second load,
4c1248
cancellable2 does absolutely nothing: cancelling it won't stop the load,
4c1248
and it will still receive onFinished handling.
4c1248
4c1248
To prevent this from happening, give the actual load operation its own
4c1248
Gio.Cancellable, which is "ref-counted" -- only cancel it when all the other
4c1248
possible callers cancel.
4c1248
4c1248
Based on work from Jasper St. Pierre <jstpierre@macheye.net>
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=722149
4c1248
---
4c1248
 js/ui/background.js | 17 +++++++++++++++++
4c1248
 1 file changed, 17 insertions(+)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 417f70d..5d6d615 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -146,6 +146,21 @@ const BackgroundCache = new Lang.Class({
4c1248
 
4c1248
     _attachCallerToFileLoad: function(caller, fileLoad) {
4c1248
         fileLoad.callers.push(caller);
4c1248
+
4c1248
+        if (!caller.cancellable)
4c1248
+            return;
4c1248
+
4c1248
+        caller.cancellable.connect(Lang.bind(this, function() {
4c1248
+            let idx = fileLoad.callers.indexOf(caller);
4c1248
+            fileLoad.callers.splice(idx, 1);
4c1248
+
4c1248
+            if (fileLoad.callers.length == 0) {
4c1248
+                fileLoad.cancellable.cancel();
4c1248
+
4c1248
+                let idx = this._pendingFileLoads.indexOf(fileLoad);
4c1248
+                this._pendingFileLoads.splice(idx, 1);
4c1248
+            }
4c1248
+        }));
4c1248
     },
4c1248
 
4c1248
     _loadImageContent: function(params) {
4c1248
@@ -158,6 +173,7 @@ const BackgroundCache = new Lang.Class({
4c1248
 
4c1248
         let caller = { monitorIndex: params.monitorIndex,
4c1248
                        effects: params.effects,
4c1248
+                       cancellable: params.cancellable,
4c1248
                        onFinished: params.onFinished };
4c1248
 
4c1248
         for (let i = 0; i < this._pendingFileLoads.length; i++) {
4c1248
@@ -172,6 +188,7 @@ const BackgroundCache = new Lang.Class({
4c1248
 
4c1248
         let fileLoad = { filename: params.filename,
4c1248
                          style: params.style,
4c1248
+                         cancellable: new Gio.Cancellable(),
4c1248
                          callers: [] };
4c1248
         this._attachCallerToFileLoad(caller, fileLoad);
4c1248
 
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From b9c8c220ea0cdd1f3d1b8ddefb9fc0e43d9e004f Mon Sep 17 00:00:00 2001
4c1248
From: "Jasper St. Pierre" <jstpierre@mecheye.net>
4c1248
Date: Tue, 3 Dec 2013 15:41:42 -0500
4c1248
Subject: [PATCH 11/13] background: Fix the check for spanning backgrounds
4c1248
4c1248
this._monitorIndex does not exist, and neither does
4c1248
MetaBackground.monitor_index...
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=719803
4c1248
---
4c1248
 js/ui/background.js | 2 +-
4c1248
 1 file changed, 1 insertion(+), 1 deletion(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 5d6d615..0ac4ddc 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -247,7 +247,7 @@ const BackgroundCache = new Lang.Class({
4c1248
                 continue;
4c1248
 
4c1248
             if (params.style == GDesktopEnums.BackgroundStyle.SPANNED &&
4c1248
-                this._images[i].monitor_index != this._monitorIndex)
4c1248
+                this._images[i].monitor != params.monitorIndex)
4c1248
                 continue;
4c1248
 
4c1248
             candidateContent = this._images[i];
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From 3466eb95898adb14a28f32740dde559b460a3ca2 Mon Sep 17 00:00:00 2001
4c1248
From: "Jasper St. Pierre" <jstpierre@mecheye.net>
4c1248
Date: Tue, 3 Dec 2013 15:56:12 -0500
4c1248
Subject: [PATCH 12/13] background: Don't wait for gdk-pixbuf to fail before
4c1248
 loading animations
4c1248
4c1248
We don't have any better way of determining whether something is a slideshow
4c1248
animation, so discriminate on the .xml filename instead of waiting for
4c1248
gdk-pixbuf to determine whether it can load a file or not.
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=719803
4c1248
---
4c1248
 js/ui/background.js | 17 +++++++++--------
4c1248
 1 file changed, 9 insertions(+), 8 deletions(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 0ac4ddc..0c22a0d 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -568,24 +568,25 @@ const Background = new Lang.Class({
4c1248
                                            });
4c1248
     },
4c1248
 
4c1248
-    _loadFile: function(filename) {
4c1248
+    _loadImage: function(filename) {
4c1248
         this._cache.getImageContent({ monitorIndex: this._monitorIndex,
4c1248
                                       effects: this._effects,
4c1248
                                       style: this._style,
4c1248
                                       filename: filename,
4c1248
                                       cancellable: this._cancellable,
4c1248
                                       onFinished: Lang.bind(this, function(content) {
4c1248
-                                          if (!content) {
4c1248
-                                              if (!this._cancellable.is_cancelled())
4c1248
-                                                  this._loadAnimation(filename);
4c1248
-                                              return;
4c1248
-                                          }
4c1248
-
4c1248
-                                          this._addImage(content, 0, filename);
4c1248
+                                          if (content)
4c1248
+                                              this._addImage(content, 0, filename);
4c1248
                                           this._setLoaded();
4c1248
                                       })
4c1248
                                     });
4c1248
+    },
4c1248
 
4c1248
+    _loadFile: function(filename) {
4c1248
+        if (filename.indexOf('.xml', filename.length - 4) !== -1)
4c1248
+            this._loadAnimation(filename);
4c1248
+        else
4c1248
+            this._loadImage(filename);
4c1248
     },
4c1248
 
4c1248
     _load: function () {
4c1248
-- 
4c1248
1.9.0
4c1248
4c1248
4c1248
From b44299e03981125c2877082226cc2276ad5b47bd Mon Sep 17 00:00:00 2001
4c1248
From: "Jasper St. Pierre" <jstpierre@mecheye.net>
4c1248
Date: Tue, 3 Dec 2013 17:25:57 -0500
4c1248
Subject: [PATCH 13/13] background: Simplify animation code
4c1248
4c1248
https://bugzilla.gnome.org/show_bug.cgi?id=719803
4c1248
---
4c1248
 js/ui/background.js | 31 ++++++++++++++-----------------
4c1248
 1 file changed, 14 insertions(+), 17 deletions(-)
4c1248
4c1248
diff --git a/js/ui/background.js b/js/ui/background.js
4c1248
index 0c22a0d..5575815 100644
4c1248
--- a/js/ui/background.js
4c1248
+++ b/js/ui/background.js
4c1248
@@ -439,29 +439,27 @@ const Background = new Lang.Class({
4c1248
         this._fileWatches[filename] = signalId;
4c1248
     },
4c1248
 
4c1248
-    _addImage: function(content, index, filename) {
4c1248
-        content.saturation = this._saturation;
4c1248
-        content.brightness = this._brightness;
4c1248
-        content.vignette_sharpness = this._vignetteSharpness;
4c1248
+    _ensureImage: function(index) {
4c1248
+        if (this._images[index])
4c1248
+            return;
4c1248
 
4c1248
         let actor = new Meta.BackgroundActor();
4c1248
-        actor.content = content;
4c1248
 
4c1248
         // The background pattern is the first actor in
4c1248
         // the group, and all images should be above that.
4c1248
         this.actor.insert_child_at_index(actor, index + 1);
4c1248
-
4c1248
         this._images[index] = actor;
4c1248
-        this._watchCacheFile(filename);
4c1248
     },
4c1248
 
4c1248
-    _updateImage: function(content, index, filename) {
4c1248
+    _updateImage: function(index, content, filename) {
4c1248
         content.saturation = this._saturation;
4c1248
         content.brightness = this._brightness;
4c1248
         content.vignette_sharpness = this._vignetteSharpness;
4c1248
 
4c1248
-        this._cache.removeImageContent(this._images[index].content);
4c1248
-        this._images[index].content = content;
4c1248
+        let image = this._images[index];
4c1248
+        if (image.content)
4c1248
+            this._cache.removeImageContent(content);
4c1248
+        image.content = content;
4c1248
         this._watchCacheFile(filename);
4c1248
     },
4c1248
 
4c1248
@@ -509,11 +507,8 @@ const Background = new Lang.Class({
4c1248
                                                   return;
4c1248
                                               }
4c1248
 
4c1248
-                                              if (!this._images[i]) {
4c1248
-                                                  this._addImage(content, i, files[i]);
4c1248
-                                              } else {
4c1248
-                                                  this._updateImage(content, i, files[i]);
4c1248
-                                              }
4c1248
+                                              this._ensureImage(i);
4c1248
+                                              this._updateImage(i, content, files[i]);
4c1248
 
4c1248
                                               if (numPendingImages == 0) {
4c1248
                                                   this._setLoaded();
4c1248
@@ -575,8 +570,10 @@ const Background = new Lang.Class({
4c1248
                                       filename: filename,
4c1248
                                       cancellable: this._cancellable,
4c1248
                                       onFinished: Lang.bind(this, function(content) {
4c1248
-                                          if (content)
4c1248
-                                              this._addImage(content, 0, filename);
4c1248
+                                          if (content) {
4c1248
+                                              this._ensureImage(0);
4c1248
+                                              this._updateImage(0, content, filename);
4c1248
+                                          }
4c1248
                                           this._setLoaded();
4c1248
                                       })
4c1248
                                     });
4c1248
-- 
4c1248
1.9.0
4c1248