feat(input): port keyboard, keybinding and mouse input handling
Ports ZIG/src/input (except macOS keymaps) into ghostty-input: - key, key_mods (incl. RemapSet), the physical keycode table - key_encode: legacy, modifyOtherKeys and kitty keyboard protocol encoders, function key tables - Binding: all keybinding actions with their user-visible docs (for +list-actions), triggers, sets with sequences, chains, leader keys and key tables, and formatting back to config strings - command palette defaults, mouse, paste safety checks, kitty helpers, links, helpgen action docs Deviations (docs/rewrite/notes/ghostty-input.md): Mods.super is named super_; case folding uses char::to_lowercase plus Ghostty's special cases instead of uucode tables; chain parents are trigger paths instead of pointers; a Zig bug where chained leaves inside sequences corrupted the shared prefix when formatting is fixed (covered by a test). Integration left: building encode/paste Options from terminal modes, and implementing the EntryFormatter trait in ghostty-config. Test Plan: - cargo test -p ghostty-input (220 tests; 8 macOS-only skipped) - cargo clippy -p ghostty-input --all-targets -- -D warnings
This commit is contained in:
1 parent
3323c3f525
commit
3afe938b95
21 files changed
+13413
-1
No files matched your search
@@ -0,0 +1,56 @@
|
||||
//! Keyboard layouts (ZIG/src/input/keyboard.zig).
|
||||
|
||||
use crate::config::OptionAsAlt;
|
||||
|
||||
/// Keyboard layouts.
|
||||
///
|
||||
/// These aren't heavily used in Ghostty and having a fully comprehensive
|
||||
/// list is not important. We only need to distinguish between a few
|
||||
/// different layouts for some nice-to-have features, such as setting a default
|
||||
/// value for "macos-option-as-alt".
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Layout {
|
||||
/// Unknown, unmapped layout. Ghostty should not make any assumptions
|
||||
/// about the layout of the keyboard.
|
||||
Unknown,
|
||||
|
||||
// The remaining should be fairly self-explanatory:
|
||||
UsStandard,
|
||||
UsInternational,
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
/// Map an Apple keyboard layout ID to a value in this enum. The layout
|
||||
/// ID can be retrieved using Carbon's TIKeyboardLayoutGetInputSourceProperty
|
||||
/// function.
|
||||
///
|
||||
/// Even though our layout supports "unknown", we return None if we don't
|
||||
/// recognize the layout ID so callers can detect this scenario.
|
||||
pub fn map_apple_id(id: &str) -> Option<Layout> {
|
||||
match id {
|
||||
"com.apple.keylayout.US" => Some(Layout::UsStandard),
|
||||
"com.apple.keylayout.USInternational" => Some(Layout::UsInternational),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the default macos-option-as-alt value for this layout.
|
||||
///
|
||||
/// We apply some heuristics to change the default based on the keyboard
|
||||
/// layout if "macos-option-as-alt" is unset. We do this because on some
|
||||
/// keyboard layouts such as US standard layouts, users generally expect
|
||||
/// an input such as option-b to map to alt-b but macOS by default will
|
||||
/// convert it to the codepoint "∫".
|
||||
///
|
||||
/// This behavior however is desired on international layout where the
|
||||
/// option key is used for important, regularly used inputs.
|
||||
pub fn detect_option_as_alt(self) -> OptionAsAlt {
|
||||
match self {
|
||||
// On US standard, the option key is typically used as alt
|
||||
// and not as a modifier for other codepoints. For example,
|
||||
// option-B = ∫ but usually the user wants alt-B.
|
||||
Layout::UsStandard | Layout::UsInternational => OptionAsAlt::True,
|
||||
Layout::Unknown => OptionAsAlt::False,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user