@@ -5,11 +5,11 @@ use sctk::reexports::protocols::unstable::text_input::v3::client::zwp_text_input
5
5
Event as TextInputEvent , ZwpTextInputV3 ,
6
6
} ;
7
7
8
- use crate :: event:: WindowEvent ;
8
+ use crate :: event:: { WindowEvent , IME } ;
9
9
use crate :: platform_impl:: wayland;
10
10
use crate :: platform_impl:: wayland:: event_loop:: WinitState ;
11
11
12
- use super :: { TextInputHandler , TextInputInner } ;
12
+ use super :: { Preedit , TextInputHandler , TextInputInner } ;
13
13
14
14
#[ inline]
15
15
pub ( super ) fn handle_text_input (
@@ -38,6 +38,7 @@ pub(super) fn handle_text_input(
38
38
text_input : text_input. detach ( ) ,
39
39
} ;
40
40
window_handle. text_input_entered ( text_input_handler) ;
41
+ event_sink. push_window_event ( WindowEvent :: IME ( IME :: Enabled ) , window_id) ;
41
42
}
42
43
TextInputEvent :: Leave { surface } => {
43
44
// Always issue a disable.
@@ -58,19 +59,41 @@ pub(super) fn handle_text_input(
58
59
text_input : text_input. detach ( ) ,
59
60
} ;
60
61
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
+ } ) ;
61
77
}
62
78
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 ( ) ) ;
65
82
}
66
83
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,
69
86
_ => return ,
70
87
} ;
71
88
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) ;
74
97
}
75
98
}
76
99
_ => ( ) ,
0 commit comments