workspaceThumbnail: improve handling of notify::minimized signal

There were various cases where we could lose track of a window and
leave the notify::minimized signal connect after the actor was destroyed
or the workspace removed. This could result in operations on a removed
workspace and assertion failures inside Mutter.

https://bugzilla.redhat.com/show_bug.cgi?id=773059
https://bugzilla.gnome.org/show_bug.cgi?id=667652
This commit is contained in:
Owen W. Taylor 2012-01-11 17:59:17 -05:00
parent 8943b3b0e9
commit 301bacec9f

View File

@ -181,17 +181,21 @@ const WorkspaceThumbnail = new Lang.Class({
let monitor = Main.layoutManager.primaryMonitor;
this.setPorthole(monitor.x, monitor.y, monitor.width, monitor.height);
let windows = global.get_window_actors().filter(this._isMyWindow, this);
let windows = global.get_window_actors().filter(this._isWorkspaceWindow, this);
// Create clones for windows that should be visible in the Overview
this._windows = [];
this._allWindows = [];
this._minimizedChangedIds = [];
for (let i = 0; i < windows.length; i++) {
windows[i].meta_window._minimizedChangedId =
let minimizedChangedId =
windows[i].meta_window.connect('notify::minimized',
Lang.bind(this,
this._updateMinimized));
this._allWindows.push(windows[i].meta_window);
this._minimizedChangedIds.push(minimizedChangedId);
if (this._isOverviewWindow(windows[i])) {
if (this._isMyWindow(windows[i]) && this._isOverviewWindow(windows[i])) {
this._addWindowClone(windows[i]);
}
}
@ -276,12 +280,6 @@ const WorkspaceThumbnail = new Lang.Class({
let clone = this._windows[index];
this._windows.splice(index, 1);
if (win && this._isOverviewWindow(win)) {
if (metaWin._minimizedChangedId) {
metaWin.disconnect(metaWin._minimizedChangedId);
delete metaWin._minimizedChangedId;
}
}
clone.destroy();
},
@ -307,13 +305,14 @@ const WorkspaceThumbnail = new Lang.Class({
// We might have the window in our list already if it was on all workspaces and
// now was moved to this workspace
if (this._lookupIndex (metaWin) != -1)
if (this._allWindows.indexOf(metaWin) != -1)
return;
if (!metaWin._minimizedChangedId)
metaWin._minimizedChangedId = metaWin.connect('notify::minimized',
Lang.bind(this,
this._updateMinimized));
let minimizedChangedId = metaWin.connect('notify::minimized',
Lang.bind(this,
this._updateMinimized));
this._allWindows.push(metaWin);
this._minimizedChangedIds.push(minimizedChangedId);
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
return;
@ -326,6 +325,13 @@ const WorkspaceThumbnail = new Lang.Class({
},
_windowRemoved : function(metaWorkspace, metaWin) {
let index = this._allWindows.indexOf(metaWin);
if (index != -1) {
metaWin.disconnect(this._minimizedChangedIds[index]);
this._allWindows.splice(index, 1);
this._minimizedChangedIds.splice(index, 1);
}
this._doRemoveWindow(metaWin);
},
@ -363,13 +369,8 @@ const WorkspaceThumbnail = new Lang.Class({
global.screen.disconnect(this._windowEnteredMonitorId);
global.screen.disconnect(this._windowLeftMonitorId);
for (let i = 0; i < this._windows.length; i++) {
let metaWin = this._windows[i].metaWindow;
if (metaWin._minimizedChangedId) {
metaWin.disconnect(metaWin._minimizedChangedId);
delete metaWin._minimizedChangedId;
}
}
for (let i = 0; i < this._allWindows.length; i++)
this._allWindows[i].disconnect(this._minimizedChangedIds[i]);
},
_onDestroy: function(actor) {
@ -379,9 +380,14 @@ const WorkspaceThumbnail = new Lang.Class({
this.actor = null;
},
// Tests if @win belongs to this workspace
_isWorkspaceWindow : function (win) {
return Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index());
},
// Tests if @win belongs to this workspace and monitor
_isMyWindow : function (win) {
return Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index()) &&
return this._isWorkspaceWindow(win) &&
(!win.get_meta_window() || win.get_meta_window().get_monitor() == this.monitorIndex);
},