fix: Forward DeleteSurroundingText event in wayland backend

This commit is contained in:
KENZ 2026-03-28 14:27:37 +09:00 committed by Ashley Wulber
parent d0ef1f9e85
commit 594ed5cfbe
3 changed files with 35 additions and 2 deletions

View file

@ -396,6 +396,7 @@ impl SctkEventLoop {
pending_corner_radius: HashMap::new(),
text_input: None,
preedit: None,
pending_delete: None,
pending_commit: None,
},
_features: Default::default(),

View file

@ -499,6 +499,7 @@ pub struct SctkState {
pub(crate) text_input_manager: Option<TextInputManager>,
pub(crate) text_input: Option<Arc<ZwpTextInputV3>>,
pub(crate) preedit: Option<Preedit>,
pub(crate) pending_delete: Option<(usize, usize)>,
pub(crate) pending_commit: Option<String>,
}

View file

@ -91,18 +91,47 @@ impl Dispatch<ZwpTextInputV3, (), SctkState> for TextInputManager {
cursor_begin.map(|b| (b, cursor_end.unwrap_or(b)));
state.preedit = Some(Preedit { text, cursor_range });
}
TextInputEvent::DeleteSurroundingText {
before_length,
after_length,
} => {
state.pending_delete = Some((
before_length.try_into().unwrap(),
after_length.try_into().unwrap(),
));
}
TextInputEvent::CommitString { text } => {
state.preedit = None;
state.pending_commit = text;
}
TextInputEvent::Done { .. } => {
let id = WindowId::from_raw(kbd_focus.id().as_ptr() as usize);
// Protocol says:
// https://wayland.app/protocols/text-input-unstable-v3#zwp_text_input_v3:event:done
//
// The application must proceed by evaluating the changes in the following order:
//
// 1. Replace existing preedit string with the cursor.
state.sctk_events.push(SctkEvent::Winit(
id,
WindowEvent::Ime(Ime::Preedit(String::new(), None)),
));
// Commit string
// 2. Delete requested surrounding text.
if let Some((before_bytes, after_bytes)) =
state.pending_delete.take()
{
state.sctk_events.push(SctkEvent::Winit(
id,
WindowEvent::Ime(Ime::DeleteSurrounding {
before_bytes,
after_bytes,
}),
));
}
// 3. Insert commit string with the cursor at its end.
if let Some(text) = state.pending_commit.take() {
state.sctk_events.push(SctkEvent::Winit(
id,
@ -110,7 +139,9 @@ impl Dispatch<ZwpTextInputV3, (), SctkState> for TextInputManager {
));
}
// Update preedit string
// 4. Calculate surrounding text to send.
// 5. Insert new preedit text in cursor position.
// 6. Place cursor inside preedit text.
if let Some(preedit) = state.preedit.take() {
state.sctk_events.push(SctkEvent::Winit(
id,