WindowAttentionHandler: Fix notify callback leak

Keep track of the connected handlers and disconnect them on
when destroying the source.

https://bugzilla.gnome.org/show_bug.cgi?id=640781
This commit is contained in:
Adel Gadllah 2011-03-03 18:10:32 +01:00
parent e01971eac7
commit 2ee4f57395

View File

@ -15,12 +15,11 @@ function WindowAttentionHandler() {
WindowAttentionHandler.prototype = { WindowAttentionHandler.prototype = {
_init : function() { _init : function() {
this._startupIds = {}; this._startupIds = {};
this._sources = {}; this._tracker = Shell.WindowTracker.get_default();
this._tracker.connect('startup-sequence-changed', Lang.bind(this, this._onStartupSequenceChanged));
let display = global.screen.get_display(); let display = global.screen.get_display();
display.connect('window-demands-attention', Lang.bind(this, this._onWindowDemandsAttention)); display.connect('window-demands-attention', Lang.bind(this, this._onWindowDemandsAttention));
let tracker = Shell.WindowTracker.get_default();
tracker.connect('startup-sequence-changed', Lang.bind(this, this._onStartupSequenceChanged));
}, },
_onStartupSequenceChanged : function(tracker) { _onStartupSequenceChanged : function(tracker) {
@ -57,28 +56,16 @@ WindowAttentionHandler.prototype = {
if (!window || window.has_focus() || window.is_skip_taskbar()) if (!window || window.has_focus() || window.is_skip_taskbar())
return; return;
let tracker = Shell.WindowTracker.get_default(); let app = this._tracker.get_window_app(window);
let app = tracker.get_window_app(window); let source = new Source(app, window);
let appId = app.get_id();
let source = this._sources[appId];
if (source == null) {
source = new Source(app, window);
this._sources[appId] = source;
Main.messageTray.add(source); Main.messageTray.add(source);
source.connect('destroy', Lang.bind(this, function() { delete this._sources[appId]; }));
}
let notification = new MessageTray.Notification(source, this._getTitle(app, window), this._getBanner(app, window)); let notification = new MessageTray.Notification(source, this._getTitle(app, window), this._getBanner(app, window));
source.notify(notification); source.notify(notification);
window.connect('notify::title', Lang.bind(this, function(win) { source.signalIDs.push(window.connect('notify::title', Lang.bind(this, function(win) {
notification.update(this._getTitle(app, win), this._getBanner(app, win)); notification.update(this._getTitle(app, win), this._getBanner(app, win));
})); })));
window.connect('notify::demands-attention', Lang.bind(this, function() { source.destroy(); }));
window.connect('focus', Lang.bind(this, function() { source.destroy(); }));
window.connect('unmanaged', Lang.bind(this, function() { source.destroy(); }));
} }
}; };
@ -94,6 +81,20 @@ Source.prototype = {
this._window = window; this._window = window;
this._app = app; this._app = app;
this._setSummaryIcon(this.createNotificationIcon()); this._setSummaryIcon(this.createNotificationIcon());
this.signalIDs = [];
this.signalIDs.push(this._window.connect('notify::demands-attention', Lang.bind(this, function() { this.destroy(); })));
this.signalIDs.push(this._window.connect('focus', Lang.bind(this, function() { this.destroy(); })));
this.signalIDs.push(this._window.connect('unmanaged', Lang.bind(this, function() { this.destroy(); })));
this.connect('destroy', Lang.bind(this, this._onDestroy));
},
_onDestroy : function() {
for(let i = 0; i < this.signalIDs.length; i++) {
this._window.disconnect(this.signalIDs[i]);
}
this.signalIDs = [];
}, },
createNotificationIcon : function() { createNotificationIcon : function() {