mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-14 19:27:04 -04:00
macOS: Space in Apple Korean with no syllable in progress types one space (winit#4478) (#679)
* macOS: IME text committed after the marked text is cleared isn't lost (winit#4650)
winit 0.30.13 reports insertText as Ime::Commit only while marked text is
left, and after any commit it swallows the next key. Real paths where that
loses text:
- input methods that end a composition with unmarkText, then insertText
(rust-windowing/winit#3925): the committed text was dropped;
- Apple Korean 2-Set, for the key typed after a syllable: on 한 then 5 it
calls setMarkedText("한"), insertText("한"), setMarkedText(""),
insertText("5"), so the 5 (or ;, or any key that ends the syllable) was
dropped;
- a commit made outside a key press (a candidate clicked with the mouse,
dictation): no key follows to reset the state, so the next key (for
example Backspace) was swallowed.
vendor/winit now commits when a composition was started (pending_commit,
set in setMarkedText, cleared by the commit and when IME is disallowed);
other insertText calls still reach the app as KeyboardInput. A commit
outside keyDown clears the marked text and returns to the ground state.
validAttributesForMarkedText lists the underline and marked-clause
attributes, which some input methods need before they compose.
This is rust-windowing/winit#4650, the 0.30 backport of #4651 (merged on
winit master), plus the part of #4748 that fixes #4651's out-of-key-press
case (#4748's other parts are not included). One correction: upstream
spells the underline attribute "NSUnderlineStyle", but AppKit's
NSUnderlineStyleAttributeName is "NSUnderline" (printed on macOS 14), so
the AppKit value is used.
Checked with the real input methods on macOS 14.7.1 (a scratch winit app fed
key events through AppKit): with the patch 한+5 and 한+; commit the 5 and ;,
unmarkText-then-insertText commits, and Backspace after a commit outside a
key press is delivered; ABC typing, held keys, Japanese (日本, あ), Cangjie
(日) and Korean composition give the same events as before. A test fails if
a re-vendored winit loses the patch.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* macOS: Space in Apple Korean with no syllable in progress types one space (winit#4478)
With Apple Korean 2-Set on macOS 14, Space with no syllable in progress
(a second space, or a space after a digit or punctuation) makes AppKit
call setMarkedText(" "), insertText(" "), then setMarkedText(""). winit
reports the insertText as Ime::Commit(" "), but the trailing empty
setMarkedText returns its state to the ground state, so keyDown also sends
the key as KeyboardInput with text " ". egui inserts both, and PdfCraft's
text fields got two spaces (the double space of alacritty/alacritty#8079).
vendor/winit now records that the key being handled committed IME text and
then doesn't also send it as KeyboardInput, unless AppKit forwards it as a
command through doCommandBySelector (Enter after a syllable still commits
the syllable and sends Enter). keyDown consumes the record on every key,
so keys typed after IME is disallowed are unaffected.
rust-windowing/winit#4478 aims at the same double space, but its changes
(clearing the marked text on commit, forwarding a later insertText, and
dropping doCommandBySelector's guard) don't reach this call order, and the
key loss it also fixes is already fixed by the previous change
(pending_commit). This is the narrow form for the call order observed
here; it should go upstream with #4478.
Checked with the real input methods on macOS 14.7.1 (scratch winit app, on top
of the previous change): the duplicate KeyboardInput Space is gone and
nothing else changes (Korean syllables, 한+Enter, 한+5, Japanese, Cangjie,
ABC, held keys, keys after IME is disallowed). A test fails if a
re-vendored winit loses the patch.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Keep #678's emoji-picker branch: view.rs is main's plus this PR's Space fix (54b3d3c)
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
This commit is contained in:
3 files changed
+29
-1
No files matched your search
@@ -0,0 +1,17 @@
|
||||
//! vendor/winit patch (9) (vendor/README.md).
|
||||
|
||||
#[test]
|
||||
fn winit_sends_a_key_committed_through_macos_ime_only_once() {
|
||||
// Apple Korean answers Space with no syllable in progress with `setMarkedText(" ")`,
|
||||
// `insertText(" ")` and `setMarkedText("")`. The last call resets winit 0.30.13's IME state, so
|
||||
// the key went to the app both as `Ime::Commit(" ")` and as `KeyboardInput` with text " ", and
|
||||
// PdfCraft's text fields got two spaces. vendor/winit doesn't send `KeyboardInput` for a key
|
||||
// whose text was committed, unless AppKit forwards it as a command (Enter) (the goal of
|
||||
// rust-windowing/winit#4478). A re-vendored copy without the patch would silently bring the bug
|
||||
// back: re-apply the patch, or drop the copy once a winit 0.30 release has the fix.
|
||||
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
|
||||
let view = std::fs::read_to_string(root.join("vendor/winit/src/platform_impl/macos/view.rs")).unwrap();
|
||||
assert!(view.contains("self.ivars().committed_in_key_down.set(true);"), "a commit in keyDown isn't recorded");
|
||||
let consumed = "let had_ime_input = self.ivars().committed_in_key_down.replace(false) || had_ime_input;";
|
||||
assert!(view.contains(consumed), "a key committed through IME is sent again as KeyboardInput");
|
||||
}
|
||||
Reference in new issue
Block a user