Skip to content

Commit c152698

Browse files
committed
Add new IME event support for Wayland
1 parent 8d63220 commit c152698

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ features = [
8585
]
8686

8787
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
88-
wayland-client = { version = "0.29", default_features = false, features = ["use_system_lib"], optional = true }
89-
wayland-protocols = { version = "0.29", features = [ "staging_protocols"], optional = true }
88+
wayland-client = { version = "0.29.4", default_features = false, features = ["use_system_lib"], optional = true }
89+
wayland-protocols = { version = "0.29.4", features = [ "staging_protocols"], optional = true }
9090
sctk = { package = "smithay-client-toolkit", version = "0.15.1", default_features = false, features = ["calloop"], optional = true }
9191
mio = { version = "0.8", features = ["os-ext"], optional = true }
9292
x11-dl = { version = "2.18.5", optional = true }

src/platform_impl/linux/wayland/seat/text_input/handlers.rs

+31-8
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ use sctk::reexports::protocols::unstable::text_input::v3::client::zwp_text_input
55
Event as TextInputEvent, ZwpTextInputV3,
66
};
77

8-
use crate::event::WindowEvent;
8+
use crate::event::{WindowEvent, IME};
99
use crate::platform_impl::wayland;
1010
use crate::platform_impl::wayland::event_loop::WinitState;
1111

12-
use super::{TextInputHandler, TextInputInner};
12+
use super::{Preedit, TextInputHandler, TextInputInner};
1313

1414
#[inline]
1515
pub(super) fn handle_text_input(
@@ -38,6 +38,7 @@ pub(super) fn handle_text_input(
3838
text_input: text_input.detach(),
3939
};
4040
window_handle.text_input_entered(text_input_handler);
41+
event_sink.push_window_event(WindowEvent::IME(IME::Enabled), window_id);
4142
}
4243
TextInputEvent::Leave { surface } => {
4344
// Always issue a disable.
@@ -58,19 +59,41 @@ pub(super) fn handle_text_input(
5859
text_input: text_input.detach(),
5960
};
6061
window_handle.text_input_left(text_input_handler);
62+
event_sink.push_window_event(WindowEvent::IME(IME::Disabled), window_id);
63+
}
64+
TextInputEvent::PreeditString {
65+
text,
66+
cursor_begin,
67+
cursor_end,
68+
} => {
69+
let cursor_begin = usize::try_from(cursor_begin).ok();
70+
let cursor_end = usize::try_from(cursor_end).ok();
71+
let text = text.unwrap_or_default();
72+
inner.pending_preedit = Some(Preedit {
73+
text,
74+
cursor_begin,
75+
cursor_end,
76+
});
6177
}
6278
TextInputEvent::CommitString { text } => {
63-
// Update currenly commited string.
64-
inner.commit_string = text;
79+
// Update currenly commited string and reset previous preedit.
80+
inner.pending_preedit = None;
81+
inner.pending_commit = Some(text.unwrap_or_default());
6582
}
6683
TextInputEvent::Done { .. } => {
67-
let (window_id, text) = match (inner.target_window_id, inner.commit_string.take()) {
68-
(Some(window_id), Some(text)) => (window_id, text),
84+
let window_id = match inner.target_window_id {
85+
Some(window_id) => window_id,
6986
_ => return,
7087
};
7188

72-
for ch in text.chars() {
73-
event_sink.push_window_event(WindowEvent::ReceivedCharacter(ch), window_id);
89+
if let Some(text) = inner.pending_commit.take() {
90+
event_sink.push_window_event(WindowEvent::IME(IME::Commit(text)), window_id);
91+
}
92+
93+
// Push preedit string we've got after latest commit.
94+
if let Some(preedit) = inner.pending_preedit.take() {
95+
let event = IME::Preedit(preedit.text, preedit.cursor_begin, preedit.cursor_end);
96+
event_sink.push_window_event(WindowEvent::IME(event), window_id);
7497
}
7598
}
7699
_ => (),

src/platform_impl/linux/wayland/seat/text_input/mod.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,25 @@ struct TextInputInner {
5252
/// Currently focused surface.
5353
target_window_id: Option<WindowId>,
5454

55-
/// Pending string to commit.
56-
commit_string: Option<String>,
55+
/// Pending commit event which will be dispatched on `text_input_v3::Done`.
56+
pending_commit: Option<String>,
57+
58+
/// Pending preedit event which will be dispatched on `text_input_v3::Done`.
59+
pending_preedit: Option<Preedit>,
60+
}
61+
62+
struct Preedit {
63+
text: String,
64+
cursor_begin: Option<usize>,
65+
cursor_end: Option<usize>,
5766
}
5867

5968
impl TextInputInner {
6069
fn new() -> Self {
6170
Self {
6271
target_window_id: None,
63-
commit_string: None,
72+
pending_commit: None,
73+
pending_preedit: None,
6474
}
6575
}
6676
}

0 commit comments

Comments
 (0)