Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions winit-appkit/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,24 @@ define_class!(

let is_control = string.chars().next().is_some_and(|c| c.is_control());

// Commit only if we have marked text.
if self.hasMarkedText() && self.is_ime_enabled() && !is_control {
self.queue_event(WindowEvent::Ime(Ime::Preedit(String::new(), None)));
// Commit the text whenever the IME is enabled and the string is
// not a control character. The original guard `hasMarkedText()`
// was too strict: some input methods (e.g. macOS Chinese
// Simplified Pinyin) convert punctuation keys by calling
// `insertText:` *without* a prior `setMarkedText:`, so
// `hasMarkedText()` is `false` even though the text is the
// IME-converted result (e.g. `,` → `,`).
//
// Without this change winit silently drops the converted
// character and the raw ASCII key from `NSEvent.characters`
// reaches the application instead.
//
// When `hasMarkedText()` is `true` we still clear the preedit
// first, preserving the existing preedit-then-commit sequence.
if self.is_ime_enabled() && !is_control {
if self.hasMarkedText() {
self.queue_event(WindowEvent::Ime(Ime::Preedit(String::new(), None)));
}
self.queue_event(WindowEvent::Ime(Ime::Commit(string)));
self.ivars().ime_state.set(ImeState::Committed);
}
Expand Down
2 changes: 1 addition & 1 deletion winit-x11/src/event_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1757,7 +1757,7 @@ impl EventProcessor {
.find(|prev_monitor| prev_monitor.name == new_monitor.name)
.map(|prev_monitor| prev_monitor.scale_factor);
if Some(new_monitor.scale_factor) != maybe_prev_scale_factor {
for window in self.target.windows.borrow().iter().filter_map(|(_, w)| w.upgrade()) {
for window in self.target.windows.borrow().values().filter_map(|w| w.upgrade()) {
window.refresh_dpi_for_monitor(
&new_monitor,
maybe_prev_scale_factor,
Expand Down
10 changes: 9 additions & 1 deletion winit/src/changelog/v0.31.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
## 0.31.0-beta.2

### Added
### Fixed

- On macOS, `insertText:replacementRange:` now always emits `Ime::Commit`
when the IME is enabled, even when `hasMarkedText()` is `false`. This
fixes Chinese (and potentially other CJK) punctuation input: the macOS
Chinese Simplified Pinyin IME converts punctuation keys (e.g. `,` →
`,`) via a direct `insertText:` call without a prior `setMarkedText:`,
causing the converted character to be silently dropped and the raw ASCII
key to reach the application instead.

- Add `EventLoopExtRegister::register_app` for being explicit about how the event loop runs on Web.
- Add `EventLoopExtNeverReturn::run_app_never_return` for being explicit about how the event loop runs on iOS.
Expand Down
Loading