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