keyboard: Disconnect from input source manager when destroying indicator

When an InputSourceIndicator is destroyed, the InputSourceManager it was
connected to could (and probably will) outlive it (since the manager is
a singleton). If the InputSourceManager emits any subsequent signals,
the callbacks from the finalised InputSourceIndicator could be invoked,
and will reference finalised objects.

This can be triggered by running `pkexec true` from a gnome-terminal
window, then calling `pkill pkexec` from another terminal (on a
different VT or via SSH). This causes the dialogue to be cancelled by
polkitd.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357
This commit is contained in:
Philip Withnall 2019-01-18 13:23:36 +00:00 committed by Florian Müllner
parent 21de3c327b
commit 8bb9eb0fc9

View File

@ -832,6 +832,8 @@ var InputSourceIndicator = new Lang.Class({
_init() { _init() {
this.parent(0.0, _("Keyboard")); this.parent(0.0, _("Keyboard"));
this.connect('destroy', this._onDestroy.bind(this));
this._menuItems = {}; this._menuItems = {};
this._indicatorLabels = {}; this._indicatorLabels = {};
@ -856,11 +858,21 @@ var InputSourceIndicator = new Lang.Class({
this._sessionUpdated(); this._sessionUpdated();
this._inputSourceManager = getInputSourceManager(); this._inputSourceManager = getInputSourceManager();
this._inputSourceManagerSourcesChangedId =
this._inputSourceManager.connect('sources-changed', this._sourcesChanged.bind(this)); this._inputSourceManager.connect('sources-changed', this._sourcesChanged.bind(this));
this._inputSourceManagerCurrentSourceChangedId =
this._inputSourceManager.connect('current-source-changed', this._currentSourceChanged.bind(this)); this._inputSourceManager.connect('current-source-changed', this._currentSourceChanged.bind(this));
this._inputSourceManager.reload(); this._inputSourceManager.reload();
}, },
_onDestroy() {
if (this._inputSourceManager) {
this._inputSourceManager.disconnect(this._inputSourceManagerSourcesChangedId);
this._inputSourceManager.disconnect(this._inputSourceManagerCurrentSourceChangedId);
this._inputSourceManager = null;
}
},
_sessionUpdated() { _sessionUpdated() {
// re-using "allowSettings" for the keyboard layout is a bit shady, // re-using "allowSettings" for the keyboard layout is a bit shady,
// but at least for now it is used as "allow popping up windows // but at least for now it is used as "allow popping up windows