From 49d066234f9f528122bb40c5144b40d8b19a0071 Mon Sep 17 00:00:00 2001 From: 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