mirror of
https://github.com/rust-windowing/winit.git
synced 2026-09-01 06:10:07 -04:00
wayland: clear IME preedit only when necessary
When all we'll be doing is setting a new preedit, the preedit doesn't have to be explicitly cleared first. This change is perhaps debatable. The direct reason for this is to make it easier to work around quirks/bugs: in Masonry we've found IBus appears to resend the IME preedit in response to `Window::set_ime_cursor_area` (`zwp_text_input_v3::set_cursor_rectangle`). Because currently the preedit is first cleared, a new IME cursor area is sent, which again causes IBus to resend the preedit. This can loop for a while. The Wayland protocol is mechanically quite prescriptive, it says for zwp_text_input_v3:event:done. > 1. Replace existing preedit string with the cursor. > 2. Delete requested surrounding text. > 3. Insert commit string with the cursor at its end. > 4. Calculate surrounding text to send. > 5. Insert new preedit text in cursor position. > 6. Place cursor inside preedit text. Winit currently doesn't do surrounding text, so 2. and 4. can be ignored. In Winit's IME model, without a commit, sending just the `Ime::Preedit` event without explicitly clearing is arguably still equivalent to doing 1., 5., and 6.
This commit is contained in:
committed by
Kirill Chibisov
parent
090498a4a6
commit
abfe90bddb
@@ -39,3 +39,7 @@ The migration guide could reference other migration examples in the current
|
|||||||
changelog entry.
|
changelog entry.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- On Wayland, no longer send an explicit clearing `Ime::Preedit` just prior to a new `Ime::Preedit`.
|
||||||
|
|||||||
@@ -121,11 +121,15 @@ impl Dispatch<ZwpTextInputV3, TextInputData, WinitState> for TextInputState {
|
|||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clear preedit at the start of `Done`.
|
// Clear preedit, unless all we'll be doing next is sending a new preedit.
|
||||||
state.events_sink.push_window_event(
|
if text_input_data.pending_commit.is_some()
|
||||||
WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
|| text_input_data.pending_preedit.is_none()
|
||||||
window_id,
|
{
|
||||||
);
|
state.events_sink.push_window_event(
|
||||||
|
WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||||
|
window_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Send `Commit`.
|
// Send `Commit`.
|
||||||
if let Some(text) = text_input_data.pending_commit.take() {
|
if let Some(text) = text_input_data.pending_commit.take() {
|
||||||
|
|||||||
Reference in New Issue
Block a user