From c5a422eed6050bc3df8a1d0bbcae083c028c6889 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sun, 31 Dec 2023 07:43:02 +0400 Subject: [PATCH] On X11, fix IME input lagging behind IME events and requests where drained on one-by-one basis, however we should drain all of them at once and send to user. Links: https://github.com/alacritty/alacritty/issues/7514 --- CHANGELOG.md | 1 + .../linux/x11/event_processor.rs | 77 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05011395..34b79640 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Unreleased` header. # Unreleased +- On X11, fix IME input lagging behind. - On X11, fix `ModifiersChanged` not sent from xdotool-like input - On X11, keymap not updated from xmodmap. - On X11, reduce the amount of time spent fetching screen resources. diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index 8f766f06..ce6413a9 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -1311,7 +1311,7 @@ impl EventProcessor { } // Handle IME requests. - if let Ok(request) = self.ime_receiver.try_recv() { + while let Ok(request) = self.ime_receiver.try_recv() { let mut ime = wt.ime.borrow_mut(); match request { ImeRequest::Position(window_id, x, y) => { @@ -1323,47 +1323,46 @@ impl EventProcessor { } } - let (window, event) = match self.ime_event_receiver.try_recv() { - Ok((window, event)) => (window as xproto::Window, event), - Err(_) => return, - }; - - match event { - ImeEvent::Enabled => { - callback(Event::WindowEvent { - window_id: mkwid(window), - event: WindowEvent::Ime(Ime::Enabled), - }); - } - ImeEvent::Start => { - self.is_composing = true; - callback(Event::WindowEvent { - window_id: mkwid(window), - event: WindowEvent::Ime(Ime::Preedit("".to_owned(), None)), - }); - } - ImeEvent::Update(text, position) => { - if self.is_composing { + // Drain IME events. + while let Ok((window, event)) = self.ime_event_receiver.try_recv() { + let window_id = mkwid(window as xproto::Window); + match event { + ImeEvent::Enabled => { callback(Event::WindowEvent { - window_id: mkwid(window), - event: WindowEvent::Ime(Ime::Preedit(text, Some((position, position)))), + window_id, + event: WindowEvent::Ime(Ime::Enabled), + }); + } + ImeEvent::Start => { + self.is_composing = true; + callback(Event::WindowEvent { + window_id, + event: WindowEvent::Ime(Ime::Preedit("".to_owned(), None)), + }); + } + ImeEvent::Update(text, position) => { + if self.is_composing { + callback(Event::WindowEvent { + window_id, + event: WindowEvent::Ime(Ime::Preedit(text, Some((position, position)))), + }); + } + } + ImeEvent::End => { + self.is_composing = false; + // Issue empty preedit on `Done`. + callback(Event::WindowEvent { + window_id, + event: WindowEvent::Ime(Ime::Preedit(String::new(), None)), + }); + } + ImeEvent::Disabled => { + self.is_composing = false; + callback(Event::WindowEvent { + window_id, + event: WindowEvent::Ime(Ime::Disabled), }); } - } - ImeEvent::End => { - self.is_composing = false; - // Issue empty preedit on `Done`. - callback(Event::WindowEvent { - window_id: mkwid(window), - event: WindowEvent::Ime(Ime::Preedit(String::new(), None)), - }); - } - ImeEvent::Disabled => { - self.is_composing = false; - callback(Event::WindowEvent { - window_id: mkwid(window), - event: WindowEvent::Ime(Ime::Disabled), - }); } } }