Skip to main content

fission_core/input/
editing_convention.rs

1use crate::event::{MOD_ALT, MOD_CTRL, MOD_SUPER};
2
3/// Host text-editing conventions used by platform input controllers.
4///
5/// This is supplied by the runtime rather than inferred from the Rust target:
6/// a WebAssembly application can be running on either an Apple or non-Apple
7/// host.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
9pub enum TextEditingConvention {
10    /// Control is the primary shortcut and word-navigation modifier.
11    #[default]
12    Standard,
13    /// Command is the primary shortcut, Option navigates by word, and the
14    /// conventional Control-based line-editing commands are available.
15    Apple,
16}
17
18impl TextEditingConvention {
19    pub const fn is_apple(self) -> bool {
20        matches!(self, Self::Apple)
21    }
22
23    pub const fn primary_shortcut_modifier(self) -> u8 {
24        match self {
25            Self::Standard => MOD_CTRL,
26            Self::Apple => MOD_SUPER,
27        }
28    }
29
30    pub const fn has_primary_shortcut(self, modifiers: u8) -> bool {
31        (modifiers & self.primary_shortcut_modifier()) != 0
32    }
33
34    pub const fn has_word_modifier(self, modifiers: u8) -> bool {
35        match self {
36            Self::Standard => (modifiers & MOD_CTRL) != 0,
37            Self::Apple => (modifiers & MOD_ALT) != 0,
38        }
39    }
40
41    /// Ctrl+Alt represents AltGr on common non-Apple keyboard layouts. The
42    /// resulting character is text input, not a Control shortcut.
43    pub const fn is_alt_gr(self, modifiers: u8) -> bool {
44        matches!(self, Self::Standard)
45            && (modifiers & (MOD_CTRL | MOD_ALT)) == (MOD_CTRL | MOD_ALT)
46            && (modifiers & MOD_SUPER) == 0
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn conventions_define_host_shortcuts_without_compile_target_checks() {
56        assert!(TextEditingConvention::Apple.has_primary_shortcut(MOD_SUPER));
57        assert!(!TextEditingConvention::Apple.has_primary_shortcut(MOD_CTRL));
58        assert!(TextEditingConvention::Apple.has_word_modifier(MOD_ALT));
59
60        assert!(TextEditingConvention::Standard.has_primary_shortcut(MOD_CTRL));
61        assert!(!TextEditingConvention::Standard.has_primary_shortcut(MOD_SUPER));
62        assert!(TextEditingConvention::Standard.has_word_modifier(MOD_CTRL));
63    }
64
65    #[test]
66    fn only_standard_ctrl_alt_is_alt_gr() {
67        assert!(TextEditingConvention::Standard.is_alt_gr(MOD_CTRL | MOD_ALT));
68        assert!(!TextEditingConvention::Apple.is_alt_gr(MOD_CTRL | MOD_ALT));
69        assert!(!TextEditingConvention::Standard.is_alt_gr(MOD_CTRL));
70        assert!(!TextEditingConvention::Standard.is_alt_gr(MOD_CTRL | MOD_ALT | MOD_SUPER));
71    }
72}