From f5996a9232e672d10bf681d5a4f953ab0178172a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 7 Nov 2019 19:06:15 +0100 Subject: [PATCH] inputMethod: Compare ibus context before processing key event result In the xwayland-on-demand scenario, it may happen that Xwayland is shutdown (causing a restart of ibus-daemon to drop ibus-x11) while we are typing. If we have a bit of bad luck, this will cause the IBusInputContext to be disposed (due to its bus "closing") at a time when we have an ibus_input_context_process_key_event_async() request on the fly. As the object is disposed in between this would tickle JS (rightfully complaining that it's been disposed under its feet) and make us pass an actually NULL IBusInputContext to the corresponding _finish() function (despite the IBusInputContext being still held alive by some other refs). This will assert and abort in ibus_input_context_process_key_event_async_finish() then. To handle this, listen for IBusInputContext::destroy, and reset our internal state, this way we can compare on the JS side that the IBusInputContext is indeed an up-to-date one. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/813 --- js/misc/inputMethod.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/misc/inputMethod.js b/js/misc/inputMethod.js index 42bf7f632..545cea63a 100644 --- a/js/misc/inputMethod.js +++ b/js/misc/inputMethod.js @@ -69,6 +69,7 @@ class InputMethod extends Clutter.InputMethod { this._context.connect('show-preedit-text', this._onShowPreeditText.bind(this)); this._context.connect('hide-preedit-text', this._onHidePreeditText.bind(this)); this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this)); + this._context.connect('destroy', this._clear.bind(this)); this._updateCapabilities(); } @@ -264,6 +265,9 @@ class InputMethod extends Clutter.InputMethod { event.get_key_code() - 8, // Convert XKB keycodes to evcodes state, -1, this._cancellable, (context, res) => { + if (context != this._context) + return; + try { let retval = context.process_key_event_async_finish(res); this.notify_key_event(event, retval);