From f11b240a1c1bdd343eb0134aa4c4e20d96b49c02 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sun, 10 Jul 2022 06:52:21 -0700 Subject: [PATCH] wayland: double-buffer ime events refs: #1772 --- window/src/os/wayland/inputhandler.rs | 34 +++++++++++++++++++-------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/window/src/os/wayland/inputhandler.rs b/window/src/os/wayland/inputhandler.rs index 4dedb3aca..72e1a5c48 100644 --- a/window/src/os/wayland/inputhandler.rs +++ b/window/src/os/wayland/inputhandler.rs @@ -15,36 +15,48 @@ use wayland_protocols::unstable::text_input::v3::client::zwp_text_input_v3::{ Event, ZwpTextInputV3, }; +#[derive(Default, Debug)] +struct PendingState { + pre_edit: Option, + commit: Option, +} + #[derive(Debug, Default)] struct Inner { input_by_seat: HashMap>, keyboard_to_seat: HashMap, surface_to_keyboard: HashMap, + pending_state: HashMap, } impl Inner { fn handle_event( &mut self, - _input: Main, + input: Main, event: Event, _ddata: DispatchData, _inner: &Arc>, ) { log::trace!("{event:?}"); let conn = WaylandConnection::get().unwrap().wayland(); + let mut pending_state = self.pending_state.entry(wl_id(&**input)).or_default(); match event { Event::PreeditString { text, cursor_begin: _, cursor_end: _, } => { - conn.dispatch_to_focused_window(WindowEvent::AdviseDeadKeyStatus(match text { - Some(text) => DeadKeyStatus::Composing(text), - None => DeadKeyStatus::None, - })); + pending_state.pre_edit = text; } Event::CommitString { text } => { - if let Some(text) = text { + pending_state.commit = text; + conn.dispatch_to_focused_window(WindowEvent::AdviseDeadKeyStatus( + DeadKeyStatus::None, + )); + } + Event::Done { serial } => { + *conn.last_serial.borrow_mut() = serial; + if let Some(text) = pending_state.commit.take() { conn.dispatch_to_focused_window(WindowEvent::KeyEvent(KeyEvent { key: KeyCode::composed(&text), modifiers: Modifiers::NONE, @@ -53,11 +65,13 @@ impl Inner { raw: None, })); } - conn.dispatch_to_focused_window(WindowEvent::AdviseDeadKeyStatus( - DeadKeyStatus::None, - )); + let status = if let Some(text) = pending_state.pre_edit.take() { + DeadKeyStatus::Composing(text) + } else { + DeadKeyStatus::None + }; + conn.dispatch_to_focused_window(WindowEvent::AdviseDeadKeyStatus(status)); } - Event::Done { serial: _ } => {} _ => {} } }