mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 13:31:29 +11:00
Send empty Ime::Preedit
before the Ime::Commit
This should help downstream to automatically clear it.
This commit is contained in:
parent
ba49db2cb9
commit
5d2aca90bd
|
@ -25,6 +25,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
- On Windows, fixed ALT+Space shortcut to open window menu.
|
- On Windows, fixed ALT+Space shortcut to open window menu.
|
||||||
- On Wayland, fixed `Ime::Preedit` not being sent on IME reset.
|
- On Wayland, fixed `Ime::Preedit` not being sent on IME reset.
|
||||||
- Fixed unbound version specified for `raw-window-handle` leading to compilation failures.
|
- Fixed unbound version specified for `raw-window-handle` leading to compilation failures.
|
||||||
|
- Empty `Ime::Preedit` event will be sent before `Ime::Commit` to help clearing preedit.
|
||||||
|
|
||||||
# 0.27.2 (2022-8-12)
|
# 0.27.2 (2022-8-12)
|
||||||
|
|
||||||
|
|
19
src/event.rs
19
src/event.rs
|
@ -841,8 +841,9 @@ pub struct KeyboardInput {
|
||||||
/// the character you want to apply the accent to. This will generate the following event sequence:
|
/// the character you want to apply the accent to. This will generate the following event sequence:
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// // Press "`" key
|
/// // Press "`" key
|
||||||
/// Ime::Preedit("`", Some(0), Some(0))
|
/// Ime::Preedit("`", Some((0, 0)))
|
||||||
/// // Press "E" key
|
/// // Press "E" key
|
||||||
|
/// Ime::Preedit("", None) // Synthetic event generated by winit to clear preedit.
|
||||||
/// Ime::Commit("é")
|
/// Ime::Commit("é")
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
@ -853,14 +854,15 @@ pub struct KeyboardInput {
|
||||||
/// sequence could be obtained:
|
/// sequence could be obtained:
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// // Press "A" key
|
/// // Press "A" key
|
||||||
/// Ime::Preedit("a", Some(1), Some(1))
|
/// Ime::Preedit("a", Some((1, 1)))
|
||||||
/// // Press "B" key
|
/// // Press "B" key
|
||||||
/// Ime::Preedit("a b", Some(3), Some(3))
|
/// Ime::Preedit("a b", Some((3, 3)))
|
||||||
/// // Press left arrow key
|
/// // Press left arrow key
|
||||||
/// Ime::Preedit("a b", Some(1), Some(1))
|
/// Ime::Preedit("a b", Some((1, 1)))
|
||||||
/// // Press space key
|
/// // Press space key
|
||||||
/// Ime::Preedit("啊b", Some(3), Some(3))
|
/// Ime::Preedit("啊b", Some((3, 3)))
|
||||||
/// // Press space key
|
/// // Press space key
|
||||||
|
/// Ime::Preedit("", None) // Synthetic event generated by winit to clear preedit.
|
||||||
/// Ime::Commit("啊不")
|
/// Ime::Commit("啊不")
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -876,20 +878,21 @@ pub enum Ime {
|
||||||
/// Notifies when a new composing text should be set at the cursor position.
|
/// Notifies when a new composing text should be set at the cursor position.
|
||||||
///
|
///
|
||||||
/// The value represents a pair of the preedit string and the cursor begin position and end
|
/// The value represents a pair of the preedit string and the cursor begin position and end
|
||||||
/// position. When it's `None`, the cursor should be hidden.
|
/// position. When it's `None`, the cursor should be hidden. When `String` is an empty string
|
||||||
|
/// this indicates that preedit was cleared.
|
||||||
///
|
///
|
||||||
/// The cursor position is byte-wise indexed.
|
/// The cursor position is byte-wise indexed.
|
||||||
Preedit(String, Option<(usize, usize)>),
|
Preedit(String, Option<(usize, usize)>),
|
||||||
|
|
||||||
/// Notifies when text should be inserted into the editor widget.
|
/// Notifies when text should be inserted into the editor widget.
|
||||||
///
|
///
|
||||||
/// Any pending [`Preedit`](Self::Preedit) must be cleared.
|
/// Right before this event winit will send empty [`Self::Preedit`] event.
|
||||||
Commit(String),
|
Commit(String),
|
||||||
|
|
||||||
/// Notifies when the IME was disabled.
|
/// Notifies when the IME was disabled.
|
||||||
///
|
///
|
||||||
/// After receiving this event you won't get any more [`Preedit`](Self::Preedit) or
|
/// After receiving this event you won't get any more [`Preedit`](Self::Preedit) or
|
||||||
/// [`Commit`](Self::Commit) events until the next [`Enabled`](Self::Enabled) event. You can
|
/// [`Commit`](Self::Commit) events until the next [`Enabled`](Self::Enabled) event. You should
|
||||||
/// also stop issuing IME related requests like [`Window::set_ime_position`] and clear pending
|
/// also stop issuing IME related requests like [`Window::set_ime_position`] and clear pending
|
||||||
/// preedit text.
|
/// preedit text.
|
||||||
Disabled,
|
Disabled,
|
||||||
|
|
|
@ -88,25 +88,28 @@ pub(super) fn handle_text_input(
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Clear preedit at the start of `Done`.
|
||||||
|
event_sink.push_window_event(
|
||||||
|
WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||||
|
window_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Send `Commit`.
|
||||||
if let Some(text) = inner.pending_commit.take() {
|
if let Some(text) = inner.pending_commit.take() {
|
||||||
event_sink.push_window_event(WindowEvent::Ime(Ime::Commit(text)), window_id);
|
event_sink.push_window_event(WindowEvent::Ime(Ime::Commit(text)), window_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always send preedit on `Done` events.
|
// Send preedit.
|
||||||
let (text, range) = inner
|
if let Some(preedit) = inner.pending_preedit.take() {
|
||||||
.pending_preedit
|
let cursor_range = preedit
|
||||||
.take()
|
.cursor_begin
|
||||||
.map(|preedit| {
|
.map(|b| (b, preedit.cursor_end.unwrap_or(b)));
|
||||||
let cursor_range = preedit
|
|
||||||
.cursor_begin
|
|
||||||
.map(|b| (b, preedit.cursor_end.unwrap_or(b)));
|
|
||||||
|
|
||||||
(preedit.text, cursor_range)
|
event_sink.push_window_event(
|
||||||
})
|
WindowEvent::Ime(Ime::Preedit(preedit.text, cursor_range)),
|
||||||
.unwrap_or_default();
|
window_id,
|
||||||
|
);
|
||||||
let event = Ime::Preedit(text, range);
|
}
|
||||||
event_sink.push_window_event(WindowEvent::Ime(event), window_id);
|
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,6 +621,12 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
// If we're composing right now, send the string we've got from X11 via
|
// If we're composing right now, send the string we've got from X11 via
|
||||||
// Ime::Commit.
|
// Ime::Commit.
|
||||||
if self.is_composing && keycode == 0 && !written.is_empty() {
|
if self.is_composing && keycode == 0 && !written.is_empty() {
|
||||||
|
let event = Event::WindowEvent {
|
||||||
|
window_id,
|
||||||
|
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||||
|
};
|
||||||
|
callback(event);
|
||||||
|
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
window_id,
|
window_id,
|
||||||
event: WindowEvent::Ime(Ime::Commit(written)),
|
event: WindowEvent::Ime(Ime::Commit(written)),
|
||||||
|
|
|
@ -431,6 +431,10 @@ declare_class!(
|
||||||
let is_control = string.chars().next().map_or(false, |c| c.is_control());
|
let is_control = string.chars().next().map_or(false, |c| c.is_control());
|
||||||
|
|
||||||
if self.is_ime_enabled() && !is_control {
|
if self.is_ime_enabled() && !is_control {
|
||||||
|
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
|
window_id: self.window_id(),
|
||||||
|
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||||
|
}));
|
||||||
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent {
|
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: self.window_id(),
|
window_id: self.window_id(),
|
||||||
event: WindowEvent::Ime(Ime::Commit(string)),
|
event: WindowEvent::Ime(Ime::Commit(string)),
|
||||||
|
|
|
@ -1262,6 +1262,10 @@ unsafe fn public_window_callback_inner<T: 'static>(
|
||||||
if let Some(text) = ime_context.get_composed_text() {
|
if let Some(text) = ime_context.get_composed_text() {
|
||||||
userdata.window_state_lock().ime_state = ImeState::Enabled;
|
userdata.window_state_lock().ime_state = ImeState::Enabled;
|
||||||
|
|
||||||
|
userdata.send_event(Event::WindowEvent {
|
||||||
|
window_id: RootWindowId(WindowId(window)),
|
||||||
|
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||||
|
});
|
||||||
userdata.send_event(Event::WindowEvent {
|
userdata.send_event(Event::WindowEvent {
|
||||||
window_id: RootWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: WindowEvent::Ime(Ime::Commit(text)),
|
event: WindowEvent::Ime(Ime::Commit(text)),
|
||||||
|
@ -1298,6 +1302,10 @@ unsafe fn public_window_callback_inner<T: 'static>(
|
||||||
// trying receiving composing result and commit if exists.
|
// trying receiving composing result and commit if exists.
|
||||||
let ime_context = ImeContext::current(window);
|
let ime_context = ImeContext::current(window);
|
||||||
if let Some(text) = ime_context.get_composed_text() {
|
if let Some(text) = ime_context.get_composed_text() {
|
||||||
|
userdata.send_event(Event::WindowEvent {
|
||||||
|
window_id: RootWindowId(WindowId(window)),
|
||||||
|
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||||
|
});
|
||||||
userdata.send_event(Event::WindowEvent {
|
userdata.send_event(Event::WindowEvent {
|
||||||
window_id: RootWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: WindowEvent::Ime(Ime::Commit(text)),
|
event: WindowEvent::Ime(Ime::Commit(text)),
|
||||||
|
|
Loading…
Reference in a new issue