Skip to content

Commit 66283a7

Browse files
authored
wayland: reduce amount of empty preedits
If we send empty preedit before, don't send it again.
1 parent 3be30af commit 66283a7

File tree

1 file changed

+29
-3
lines changed
  • winit-wayland/src/seat/text_input

1 file changed

+29
-3
lines changed

winit-wayland/src/seat/text_input/mod.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ impl Dispatch<ZwpTextInputV3, TextInputData, WinitState> for TextInputState {
8484
},
8585
TextInputEvent::Leave { surface } => {
8686
text_input_data.surface = None;
87+
text_input_data.last_preedit_empty = true;
8788

8889
// Always issue a disable.
8990
text_input.disable();
@@ -129,6 +130,13 @@ impl Dispatch<ZwpTextInputV3, TextInputData, WinitState> for TextInputState {
129130
None => return,
130131
};
131132

133+
// Just in case some IME sends an event for the disabled window.
134+
if let Some(window) = windows.get(&window_id) {
135+
if window.lock().unwrap().text_input_state().is_none() {
136+
return;
137+
}
138+
};
139+
132140
// The events are sent to the user separately, so
133141
// CAUTION: events must always arrive in the order compatible with the application
134142
// order specified by the text-input-v3 protocol:
@@ -153,14 +161,17 @@ impl Dispatch<ZwpTextInputV3, TextInputData, WinitState> for TextInputState {
153161
);
154162
}
155163

156-
// Clear preedit, unless all we'll be doing next is sending a new preedit.
164+
// Clear preedit, unless all we'll be doing next is sending a new preedit and
165+
// the last preedit wasn't empty.
157166
if text_input_data.pending_commit.is_some()
158-
|| text_input_data.pending_preedit.is_none()
167+
|| (text_input_data.pending_preedit.is_none()
168+
&& !text_input_data.last_preedit_empty)
159169
{
160170
state.events_sink.push_window_event(
161171
WindowEvent::Ime(Ime::Preedit(String::new(), None)),
162172
window_id,
163173
);
174+
text_input_data.last_preedit_empty = true;
164175
}
165176

166177
// Send `Commit`.
@@ -175,6 +186,7 @@ impl Dispatch<ZwpTextInputV3, TextInputData, WinitState> for TextInputState {
175186
let cursor_range =
176187
preedit.cursor_begin.map(|b| (b, preedit.cursor_end.unwrap_or(b)));
177188

189+
text_input_data.last_preedit_empty = false;
178190
state.events_sink.push_window_event(
179191
WindowEvent::Ime(Ime::Preedit(preedit.text, cursor_range)),
180192
window_id,
@@ -238,7 +250,6 @@ pub struct TextInputData {
238250
inner: std::sync::Mutex<TextInputDataInner>,
239251
}
240252

241-
#[derive(Default)]
242253
pub struct TextInputDataInner {
243254
/// The `WlSurface` we're performing input to.
244255
surface: Option<WlSurface>,
@@ -251,6 +262,21 @@ pub struct TextInputDataInner {
251262

252263
/// The text around the cursor to delete on `done`
253264
pending_delete: Option<DeleteSurroundingText>,
265+
266+
/// Last preedit empty.
267+
last_preedit_empty: bool,
268+
}
269+
270+
impl Default for TextInputDataInner {
271+
fn default() -> Self {
272+
Self {
273+
surface: None,
274+
pending_commit: None,
275+
pending_preedit: None,
276+
pending_delete: None,
277+
last_preedit_empty: true,
278+
}
279+
}
254280
}
255281

256282
/// The state of the preedit.

0 commit comments

Comments
 (0)