keyboard: Plug a leak of KeyboardControllers

To make sure the GC really disposes the KeyboardController object we
need to remove all references to the object, which means we have to
disconnect signals the object connects to, too.

This also fixes a bug where keys remain pressed forever and thus also
break that key on real keyboards. It happens if the OSK gets destroyed
during an OSK-key is being held so the StButton of the key is not
released. That means the key remains pressed in the
MetaVirtualInputDevice that we are now leaking because
KeyboardController isn't garbage collected.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1015
This commit is contained in:
Jonas Dreßler 2020-02-18 15:05:57 +01:00 committed by Florian Müllner
parent fbfe5a1988
commit 45bc8ae292

View File

@ -1255,11 +1255,7 @@ class Keyboard extends St.BoxLayout {
this._clearShowIdle(); this._clearShowIdle();
this._keyboardController = null; this._keyboardController.destroy();
this._suggestions = null;
this._aspectContainer = null;
this._emojiSelection = null;
this._keypad = null;
Main.layoutManager.untrackChrome(this); Main.layoutManager.untrackChrome(this);
Main.layoutManager.keyboardBox.remove_actor(this); Main.layoutManager.keyboardBox.remove_actor(this);
@ -1844,13 +1840,20 @@ var KeyboardController = class {
this._onSourcesModified.bind(this)); this._onSourcesModified.bind(this));
this._currentSource = this._inputSourceManager.currentSource; this._currentSource = this._inputSourceManager.currentSource;
Main.inputMethod.connect('notify::content-purpose', this._notifyContentPurposeId = Main.inputMethod.connect(
this._onContentPurposeHintsChanged.bind(this)); 'notify::content-purpose', this._onContentPurposeHintsChanged.bind(this));
Main.inputMethod.connect('notify::content-hints', this._notifyContentHintsId = Main.inputMethod.connect(
this._onContentPurposeHintsChanged.bind(this)); 'notify::content-hints', this._onContentPurposeHintsChanged.bind(this));
Main.inputMethod.connect('input-panel-state', (o, state) => { this._notifyInputPanelStateId = Main.inputMethod.connect(
this.emit('panel-state', state); 'input-panel-state', (o, state) => this.emit('panel-state', state));
}); }
destroy() {
this._inputSourceManager.disconnect(this._sourceChangedId);
this._inputSourceManager.disconnect(this._sourcesModifiedId);
Main.inputMethod.disconnect(this._notifyContentPurposeId);
Main.inputMethod.disconnect(this._notifyContentHintsId);
Main.inputMethod.disconnect(this._notifyInputPanelStateId);
} }
_onSourcesModified() { _onSourcesModified() {