From c23bed20b85e6882a221aa4d935969d0e7ad1f97 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sun, 13 Oct 2024 21:57:02 +0300 Subject: [PATCH] x11: don't forward key events to IME when it's disabled Fixes #3815. --- src/changelog/unreleased.md | 1 + src/platform_impl/linux/x11/event_processor.rs | 17 ++++++++++++++--- src/platform_impl/linux/x11/ime/mod.rs | 10 ++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index aae4a73bee..c1fbb8447b 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -188,3 +188,4 @@ changelog entry. - On macOS, fix `WindowEvent::Moved` sometimes being triggered unnecessarily on resize. - On MacOS, package manifest definitions of `LSUIElement` will no longer be overridden with the default activation policy, unless explicitly provided during initialization. +- On X11, key events forward to IME anyway, even when it's disabled. diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index e62dc77533..1be903fa32 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -142,8 +142,18 @@ impl EventProcessor { { let event_type = xev.get_type(); - if self.filter_event(xev) { - if event_type == xlib::KeyPress || event_type == xlib::KeyRelease { + // If we have IME disabled, don't try to `filter_event`, since only IME can consume them + // and forward back. This is not desired for e.g. games since some IMEs may delay the input + // and game can toggle IME back when e.g. typing into some field where latency won't really + // matter. + if event_type == xlib::KeyPress || event_type == xlib::KeyRelease { + let ime = self.target.ime.as_ref(); + let window = self.active_window.map(|window| window as XWindow); + let forward_to_ime = ime + .and_then(|ime| window.map(|window| ime.borrow().is_ime_allowed(window))) + .unwrap_or(false); + + if forward_to_ime && self.filter_event(xev) { let xev: &XKeyEvent = xev.as_ref(); if self.xmodmap.is_modifier(xev.keycode as u8) { // Don't grow the buffer past the `MAX_MOD_REPLAY_LEN`. This could happen @@ -156,7 +166,8 @@ impl EventProcessor { self.xfiltered_modifiers.push_front(xev.serial); } } - return; + } else { + self.filter_event(xev); } match event_type { diff --git a/src/platform_impl/linux/x11/ime/mod.rs b/src/platform_impl/linux/x11/ime/mod.rs index 5af333d67e..ab6702f1d8 100644 --- a/src/platform_impl/linux/x11/ime/mod.rs +++ b/src/platform_impl/linux/x11/ime/mod.rs @@ -225,6 +225,16 @@ impl Ime { // Create new context supporting IME input. let _ = self.create_context(window, allowed); } + + pub fn is_ime_allowed(&self, window: ffi::Window) -> bool { + if self.is_destroyed() { + false + } else if let Some(Some(context)) = self.inner.contexts.get(&window) { + context.is_allowed() + } else { + false + } + } } impl Drop for Ime {