[gnome-shell/wip/verdre/plug-leak] keyboard: Plug a leak of KeyboardControllers



commit 2d64b8bc382553ea45beaabaecfd36890228a7d0
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Tue Feb 18 15:05:57 2020 +0100

    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.

 js/ui/keyboard.js | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)
---
diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js
index 868a4b3d36..15d92c5924 100644
--- a/js/ui/keyboard.js
+++ b/js/ui/keyboard.js
@@ -1255,11 +1255,7 @@ class Keyboard extends St.BoxLayout {
 
         this._clearShowIdle();
 
-        this._keyboardController = null;
-        this._suggestions = null;
-        this._aspectContainer = null;
-        this._emojiSelection = null;
-        this._keypad = null;
+        this._keyboardController.destroy();
 
         Main.layoutManager.untrackChrome(this);
         Main.layoutManager.keyboardBox.remove_actor(this);
@@ -1844,13 +1840,20 @@ var KeyboardController = class {
                                                                    this._onSourcesModified.bind(this));
         this._currentSource = this._inputSourceManager.currentSource;
 
-        Main.inputMethod.connect('notify::content-purpose',
-                                 this._onContentPurposeHintsChanged.bind(this));
-        Main.inputMethod.connect('notify::content-hints',
-                                 this._onContentPurposeHintsChanged.bind(this));
-        Main.inputMethod.connect('input-panel-state', (o, state) => {
-            this.emit('panel-state', state);
-        });
+        this._notifyContentPurposeId = Main.inputMethod.connect(
+            'notify::content-purpose', this._onContentPurposeHintsChanged.bind(this));
+        this._notifyContentHintsId = Main.inputMethod.connect(
+            'notify::content-hints', this._onContentPurposeHintsChanged.bind(this));
+        this._notifyInputPanelStateId = Main.inputMethod.connect(
+            '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() {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]