mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-30 20:58:00 -06:00
Type: input method composition (Japanese IME) in the Type tool
Typing with an input method (the macOS Japanese IME and the like) used to insert the raw keys (romaji came in as ASCII): egui's Ime events weren't handled. - Tools gain `ime_preedit` / `composing` / `ime_caret`; the Type tool lays the marked text out in place inside its typing session, underlined (the clause being converted thicker), and commits it through `text_input`. Character ranges from the IME convert to byte ranges in one place. A cancelled composition leaves no empty undo step; an empty clear with nothing marked never deletes the selection. - The UI sends Text and Ime events to the tool in order, sends IMEOutput every frame while text is edited (what lets egui-winit enable the IME and place its candidate window at the caret, or the converting clause), and holds back keys, Enter/Escape, clipboard, single-key shortcuts and menu commands (Undo, Cut, Select All… also from the native menu) while composing. A click, a tool switch or a style change ends the composition with the marked text kept as typed; on macOS the IME is told to discard it (NSTextInputContext.discardMarkedText) so it doesn't come back in the next input. - Undo during a typing session also ends the Type tool's session, so its caret and marked text follow the document. - Tests: tools (char → byte ranges, underlines and candidate position), engine (compose → commit is one step, cancel leaves no step, a click commits, Undo mid-composition is safe), ui-egui (synthetic Ime events: compose, commit, ⌘Z held back, IME output, click and app switch). Checked by hand on macOS 27 with the Japanese IME (romaji input, convert, commit, cancel, Undo/Redo after commit, click away, Latin mode, app switch). Not checked: Windows and Linux IMEs, the web build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7a39cb7b89
commit
66fa0a998a
@@ -42,12 +42,27 @@ impl eframe::App for App {
|
||||
}
|
||||
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
||||
self.0.ui(ui);
|
||||
#[cfg(target_os = "macos")]
|
||||
if self.0.take_ime_discard() {
|
||||
discard_marked_text();
|
||||
}
|
||||
}
|
||||
fn on_exit(&mut self) {
|
||||
save_prefs(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Tell the macOS input method to drop its composition (the Type tool kept the marked text as
|
||||
/// typed). winit's IME toggle only clears its own copy, so the IME would type it again.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn discard_marked_text() {
|
||||
if let Some(mtm) = objc2::MainThreadMarker::new()
|
||||
&& let Some(ic) = objc2_app_kit::NSTextInputContext::currentInputContext(mtm)
|
||||
{
|
||||
ic.discardMarkedText();
|
||||
}
|
||||
}
|
||||
|
||||
/// Where UI preferences live: ~/Library/Application Support/VectorCraft (macOS),
|
||||
/// %APPDATA%\VectorCraft (Windows), $XDG_CONFIG_HOME or ~/.config/vectorcraft (Linux).
|
||||
fn prefs_path() -> Option<std::path::PathBuf> {
|
||||
|
||||
Reference in New Issue
Block a user