From 0992bd41ed27d5f1243e9111a10e48d4631b5751 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 12 Sep 2014 17:07:31 -0400 Subject: [PATCH] background.js: fix updating a BackgroundSource on monitor changes It was assumed that BackgroundSource objects were always destroyed on monitor changes because the BackgroundManager objects that hold references were destroyed, but sequencing of updating of different BackgroundManager objects meant that was not the case. Properly update any cached Background objects held by the BackgroundSource on a change to the monitor layout; in particular this means updating animations in case they are multi-resolution. --- js/ui/background.js | 50 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/js/ui/background.js b/js/ui/background.js index 00b9d6375..9ca9312ec 100644 --- a/js/ui/background.js +++ b/js/ui/background.js @@ -242,11 +242,7 @@ const Background = new Lang.Class({ destroy: function() { this._cancellable.cancel(); - - if (this._updateAnimationTimeoutId) { - GLib.source_remove (this._updateAnimationTimeoutId); - this._updateAnimationTimeoutId = 0; - } + this._removeAnimationTimeout(); let i; let keys = Object.keys(this._fileWatches); @@ -260,6 +256,13 @@ const Background = new Lang.Class({ this._settingsChangedSignalId = 0; }, + updateResolution: function() { + if (this._animation) { + this._removeAnimationTimeout(); + this._updateAnimation(); + } + }, + _setLoaded: function() { if (this.isLoaded) return; @@ -303,6 +306,13 @@ const Background = new Lang.Class({ this._fileWatches[filename] = signalId; }, + _removeAnimationTimeout: function() { + if (this._updateAnimationTimeoutId) { + GLib.source_remove(this._updateAnimationTimeoutId); + this._updateAnimationTimeoutId = 0; + } + }, + _updateAnimation: function() { this._updateAnimationTimeoutId = 0; @@ -477,6 +487,23 @@ const BackgroundSource = new Lang.Class({ this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE'); this._settings = new Gio.Settings({ schema_id: settingsSchema }); this._backgrounds = []; + + this._monitorsChangedId = global.screen.connect('monitors-changed', + Lang.bind(this, this._onMonitorsChanged)); + }, + + _onMonitorsChanged: function() { + for (let monitorIndex in this._backgrounds) { + let background = this._backgrounds[monitorIndex]; + + if (monitorIndex < this._layoutManager.monitors.length) { + background.updateResolution(); + } else { + background.disconnect(background._changedId); + background.destroy(); + delete this._backgrounds[monitorIndex]; + } + } }, getBackground: function(monitorIndex) { @@ -513,8 +540,8 @@ const BackgroundSource = new Lang.Class({ style: style }); - let changedId = background.connect('changed', Lang.bind(this, function() { - background.disconnect(changedId); + background._changedId = background.connect('changed', Lang.bind(this, function() { + background.disconnect(background._changedId); background.destroy(); delete this._backgrounds[monitorIndex]; })); @@ -526,8 +553,13 @@ const BackgroundSource = new Lang.Class({ }, destroy: function() { - for (let monitorIndex in this._backgrounds) - this._backgrounds[monitorIndex].destroy(); + global.screen.disconnect(this._monitorsChangedId); + + for (let monitorIndex in this._backgrounds) { + let background = this._backgrounds[monitorIndex]; + background.disconnect(background._changedId); + background.destroy(); + } this._backgrounds = null; }