73 lines
2.9 KiB
Rust
73 lines
2.9 KiB
Rust
use galaxyui::keymap::Keystroke;
|
|
|
|
/// Whether this keystroke should dispatch an action in Warp despite the
|
|
/// [`galaxyui::event::Event::KeyDown::is_composing`] being true.
|
|
///
|
|
/// Generally, we ignore all `KeyDown` events if the `is_composing` field is true. However it's
|
|
/// possible to have keybinding conflicts between terminal apps which use the meta key and MacOS
|
|
/// "dead keys". Dead keys are used to add diacritical marks to other characters. They are
|
|
/// triggered by ⌥ and another letter. On the US layout, the dead keys are ⌥e, ⌥u, ⌥i, ⌥n, and ⌥`.
|
|
/// They are different for other layouts, e.g. the Croatian layout has ⌥k. Ideally, we could check
|
|
/// if a specific keystroke is a dead key. AFAICT the OS doesn't expose this, and it would be too
|
|
/// difficult to maintain a map of layouts to lists of dead keys. Therefore, this function just
|
|
/// checks if the keystroke is meta + one letter.
|
|
///
|
|
/// https://support.apple.com/guide/mac-help/enter-characters-with-accent-marks-on-mac-mh27474/mac#mchl45cdda7f
|
|
///
|
|
/// This function is intended to be used when handling [`galaxyui::event::Event::KeyDown`] when its
|
|
/// `is_composing` is true. Returning true _does not_ mean the keystroke is a dead key necessarily.
|
|
/// Interpreting it that way would result in false-positives. Rather, it means the app may dispatch
|
|
/// an action for the keystroke _despite_ the fact that `is_composing` is true.
|
|
/// Note that this is only relevant with [`crate::settings::ExtraMetaKeys`] enabled.
|
|
pub(super) fn handle_keystroke_despite_composing(keystroke: &Keystroke) -> bool {
|
|
// This conflict only occurs on MacOS.
|
|
if !cfg!(target_os = "macos") {
|
|
return false;
|
|
}
|
|
if keystroke.cmd || keystroke.ctrl || keystroke.shift || keystroke.alt || !keystroke.meta {
|
|
return false;
|
|
}
|
|
if keystroke.key.len() != 1 {
|
|
return false;
|
|
}
|
|
true
|
|
}
|
|
|
|
#[cfg(all(test, target_os = "macos"))]
|
|
mod tests {
|
|
use std::error;
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_handle_keystroke_despite_composing() -> Result<(), Box<dyn error::Error>> {
|
|
assert!(handle_keystroke_despite_composing(&Keystroke::parse(
|
|
"meta-i"
|
|
)?));
|
|
assert!(handle_keystroke_despite_composing(&Keystroke::parse(
|
|
"meta-u"
|
|
)?));
|
|
assert!(handle_keystroke_despite_composing(&Keystroke::parse(
|
|
"meta-`"
|
|
)?));
|
|
assert!(handle_keystroke_despite_composing(&Keystroke::parse(
|
|
"meta-n"
|
|
)?));
|
|
assert!(handle_keystroke_despite_composing(&Keystroke::parse(
|
|
"meta-e"
|
|
)?));
|
|
|
|
assert!(!handle_keystroke_despite_composing(&Keystroke::parse(
|
|
"alt-i"
|
|
)?));
|
|
assert!(!handle_keystroke_despite_composing(&Keystroke::parse(
|
|
"ctrl-i"
|
|
)?));
|
|
assert!(!handle_keystroke_despite_composing(&Keystroke::parse(
|
|
"meta-shift-I"
|
|
)?));
|
|
|
|
Ok(())
|
|
}
|
|
}
|