Blob Blame History Raw
From 49d066234f9f528122bb40c5144b40d8b19a0071 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Mon, 22 Aug 2022 12:52:19 +0200
Subject: [PATCH] Background: Avoid double dispose and actors recreations

Subject: [PATCH 1/2] background: Use Garbage Collector to dispose background:

The same Meta.Background could be used by multiple instances of background
actors, and so should not be disposed when the actor using it is destroyed.

Instead of calling `run_dispose` directly on it, just nullify the reference
on destroy method, leaving the job of doing the proper disposition to the
gabage collector that keeps the proper reference count on the Meta.Background.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/501

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/558

Subject: [PATCH 2/2] background: Group 'changed' signal emission

Background is monitoring the whole `org.gnome.desktop.background` gsettings keys
for changes connecting to the non-specialized 'changed' signal and re-emitting
this as-is.
This means that when the background is changed via control-center, we get
multiple 'changed' signal events from GSettings, and for each one of this we
recreate a Background and a BackgroundActor.

Avoid this by using an idle to delay the emission of the 'changed' signal
grouping the events.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/558
---
 js/ui/background.js | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/js/ui/background.js b/js/ui/background.js
index 06e0388..2a404ae 100644
--- a/js/ui/background.js
+++ b/js/ui/background.js
@@ -257,14 +257,15 @@ var Background = class Background {
                 this._refreshAnimation();
             });
 
-        this._settingsChangedSignalId = this._settings.connect('changed', () => {
-            this.emit('changed');
-        });
+        this._settingsChangedSignalId =
+            this._settings.connect('changed', this._emitChangedSignal.bind(this));
 
         this._load();
     }
 
     destroy() {
+        this.background = null;
+
         this._cancellable.cancel();
         this._removeAnimationTimeout();
 
@@ -288,6 +289,22 @@ var Background = class Background {
         if (this._settingsChangedSignalId != 0)
             this._settings.disconnect(this._settingsChangedSignalId);
         this._settingsChangedSignalId = 0;
+
+        if (this._changedIdleId) {
+            GLib.source_remove(this._changedIdleId);
+            this._changedIdleId = 0;
+        }
+    }
+
+    _emitChangedSignal() {
+        if (this._changedIdleId)
+            return;
+
+        this._changedIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
+            this._changedIdleId = 0;
+            this.emit('changed');
+            return GLib.SOURCE_REMOVE;
+        });
     }
 
     updateResolution() {
@@ -343,7 +360,7 @@ var Background = class Background {
                                                if (changedFile.equal(file)) {
                                                    let imageCache = Meta.BackgroundImageCache.get_default();
                                                    imageCache.purge(changedFile);
-                                                   this.emit('changed');
+                                                   this._emitChangedSignal();
                                                }
                                            });
         this._fileWatches[key] = signalId;
@@ -699,7 +716,6 @@ var BackgroundManager = class BackgroundManager {
                            time: FADE_ANIMATION_TIME,
                            transition: 'easeOutQuad',
                            onComplete() {
-                               oldBackgroundActor.background.run_dispose();
                                oldBackgroundActor.destroy();
                            }
                          });
-- 
2.35.3