Skip to main content

teksilo_core/
ime.rs

1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! Input-method-editor (IME) descriptors attached to widget nodes.
5//!
6//! A focusable node carries an optional [`ImeContext`]. Its **presence**
7//! declares "this node is a text-input surface" — the platform layer enables
8//! the OS input method while the node is focused. Its **absence** (the
9//! default for every node) means no OS IME: enabling IME changes how text
10//! arrives (printable text routes through `Ime::Commit` and `KeyboardInput`
11//! is suppressed during preedit), so the safe, common-case default is off.
12//!
13//! This module is deliberately winit-free — [`ImePurpose`] mirrors winit's
14//! enum of the same name so `teksilo-core` stays decoupled from the windowing
15//! backend; `teksilo-app` maps between the two at the platform boundary.
16
17/// Hint describing what an IME-enabled field is used for. Lets the platform
18/// optimize the input method — e.g. suppress the learning dictionary /
19/// candidate history for passwords, or surface terminal-specific keys.
20///
21/// Mirrors `winit::window::ImePurpose`.
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
23pub enum ImePurpose {
24    /// No special hint (ordinary text entry).
25    #[default]
26    Normal,
27    /// Password entry. The platform suppresses IME history/learning; the
28    /// widget masks the preedit and never exposes composing text to AT.
29    Password,
30    /// Terminal entry (e.g. extra on-screen-keyboard keys on Wayland).
31    Terminal,
32}
33
34/// Per-node IME descriptor. Presence = "this focusable node is a text-input
35/// surface" (OS IME enabled while focused); absence (the node default) = no
36/// OS IME. Carried on `WidgetNode`, set via `WidgetBuilder::ime_input`.
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct ImeContext {
39    /// Purpose hint forwarded to the platform IME.
40    pub purpose: ImePurpose,
41}
42
43impl ImeContext {
44    /// An ordinary text-input surface (`ImePurpose::Normal`).
45    pub fn text() -> Self {
46        Self {
47            purpose: ImePurpose::Normal,
48        }
49    }
50
51    /// A password surface (`ImePurpose::Password`). IME stays enabled so
52    /// non-Latin users can compose passwords; the widget is responsible for
53    /// masking the preedit on screen and hiding it from assistive tech.
54    pub fn password() -> Self {
55        Self {
56            purpose: ImePurpose::Password,
57        }
58    }
59}