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.
This commit is contained in:
Owen W. Taylor 2014-09-12 17:07:31 -04:00
parent ed52a5a58b
commit 0992bd41ed

View File

@ -242,11 +242,7 @@ const Background = new Lang.Class({
destroy: function() { destroy: function() {
this._cancellable.cancel(); this._cancellable.cancel();
this._removeAnimationTimeout();
if (this._updateAnimationTimeoutId) {
GLib.source_remove (this._updateAnimationTimeoutId);
this._updateAnimationTimeoutId = 0;
}
let i; let i;
let keys = Object.keys(this._fileWatches); let keys = Object.keys(this._fileWatches);
@ -260,6 +256,13 @@ const Background = new Lang.Class({
this._settingsChangedSignalId = 0; this._settingsChangedSignalId = 0;
}, },
updateResolution: function() {
if (this._animation) {
this._removeAnimationTimeout();
this._updateAnimation();
}
},
_setLoaded: function() { _setLoaded: function() {
if (this.isLoaded) if (this.isLoaded)
return; return;
@ -303,6 +306,13 @@ const Background = new Lang.Class({
this._fileWatches[filename] = signalId; this._fileWatches[filename] = signalId;
}, },
_removeAnimationTimeout: function() {
if (this._updateAnimationTimeoutId) {
GLib.source_remove(this._updateAnimationTimeoutId);
this._updateAnimationTimeoutId = 0;
}
},
_updateAnimation: function() { _updateAnimation: function() {
this._updateAnimationTimeoutId = 0; this._updateAnimationTimeoutId = 0;
@ -477,6 +487,23 @@ const BackgroundSource = new Lang.Class({
this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE'); this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
this._settings = new Gio.Settings({ schema_id: settingsSchema }); this._settings = new Gio.Settings({ schema_id: settingsSchema });
this._backgrounds = []; 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) { getBackground: function(monitorIndex) {
@ -513,8 +540,8 @@ const BackgroundSource = new Lang.Class({
style: style style: style
}); });
let changedId = background.connect('changed', Lang.bind(this, function() { background._changedId = background.connect('changed', Lang.bind(this, function() {
background.disconnect(changedId); background.disconnect(background._changedId);
background.destroy(); background.destroy();
delete this._backgrounds[monitorIndex]; delete this._backgrounds[monitorIndex];
})); }));
@ -526,8 +553,13 @@ const BackgroundSource = new Lang.Class({
}, },
destroy: function() { destroy: function() {
for (let monitorIndex in this._backgrounds) global.screen.disconnect(this._monitorsChangedId);
this._backgrounds[monitorIndex].destroy();
for (let monitorIndex in this._backgrounds) {
let background = this._backgrounds[monitorIndex];
background.disconnect(background._changedId);
background.destroy();
}
this._backgrounds = null; this._backgrounds = null;
} }