parent
021fd23c34
commit
b1209bc253
2 changed files with 21 additions and 3 deletions
|
|
@ -31,6 +31,7 @@ Unreleased` header.
|
||||||
- **Breaking:** Rename `VideoMode` to `VideoModeHandle` to represent that it doesn't hold static data.
|
- **Breaking:** Rename `VideoMode` to `VideoModeHandle` to represent that it doesn't hold static data.
|
||||||
- **Breaking:** No longer export `platform::x11::XNotSupported`.
|
- **Breaking:** No longer export `platform::x11::XNotSupported`.
|
||||||
- **Breaking:** Renamed `platform::x11::XWindowType` to `platform::x11::WindowType`.
|
- **Breaking:** Renamed `platform::x11::XWindowType` to `platform::x11::WindowType`.
|
||||||
|
- On macOS, report correct logical key when Ctrl or Cmd is pressed.
|
||||||
|
|
||||||
# 0.29.8
|
# 0.29.8
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ pub struct KeyEventExtra {
|
||||||
pub key_without_modifiers: Key,
|
pub key_without_modifiers: Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ignores ALL modifiers.
|
||||||
pub fn get_modifierless_char(scancode: u16) -> Key {
|
pub fn get_modifierless_char(scancode: u16) -> Key {
|
||||||
let mut string = [0; 16];
|
let mut string = [0; 16];
|
||||||
let input_source;
|
let input_source;
|
||||||
|
|
@ -86,6 +87,7 @@ pub fn get_modifierless_char(scancode: u16) -> Key {
|
||||||
Key::Character(SmolStr::new(chars))
|
Key::Character(SmolStr::new(chars))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ignores all modifiers except for SHIFT (yes, even ALT is ignored).
|
||||||
fn get_logical_key_char(ns_event: &NSEvent, modifierless_chars: &str) -> Key {
|
fn get_logical_key_char(ns_event: &NSEvent, modifierless_chars: &str) -> Key {
|
||||||
let string = unsafe { ns_event.charactersIgnoringModifiers() }
|
let string = unsafe { ns_event.charactersIgnoringModifiers() }
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
|
|
@ -113,6 +115,13 @@ pub(crate) fn create_key_event(
|
||||||
let scancode = unsafe { ns_event.keyCode() };
|
let scancode = unsafe { ns_event.keyCode() };
|
||||||
let mut physical_key = key_override.unwrap_or_else(|| scancode_to_physicalkey(scancode as u32));
|
let mut physical_key = key_override.unwrap_or_else(|| scancode_to_physicalkey(scancode as u32));
|
||||||
|
|
||||||
|
// NOTE: The logical key should heed both SHIFT and ALT if possible.
|
||||||
|
// For instance:
|
||||||
|
// * Pressing the A key: logical key should be "a"
|
||||||
|
// * Pressing SHIFT A: logical key should be "A"
|
||||||
|
// * Pressing CTRL SHIFT A: logical key should also be "A"
|
||||||
|
// This is not easy to tease out of `NSEvent`, but we do our best.
|
||||||
|
|
||||||
let text_with_all_modifiers: Option<SmolStr> = if key_override.is_some() {
|
let text_with_all_modifiers: Option<SmolStr> = if key_override.is_some() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -132,21 +141,29 @@ pub(crate) fn create_key_event(
|
||||||
|
|
||||||
let key_from_code = code_to_key(physical_key, scancode);
|
let key_from_code = code_to_key(physical_key, scancode);
|
||||||
let (logical_key, key_without_modifiers) = if matches!(key_from_code, Key::Unidentified(_)) {
|
let (logical_key, key_without_modifiers) = if matches!(key_from_code, Key::Unidentified(_)) {
|
||||||
|
// `get_modifierless_char/key_without_modifiers` ignores ALL modifiers.
|
||||||
let key_without_modifiers = get_modifierless_char(scancode);
|
let key_without_modifiers = get_modifierless_char(scancode);
|
||||||
|
|
||||||
let modifiers = unsafe { ns_event.modifierFlags() };
|
let modifiers = unsafe { ns_event.modifierFlags() };
|
||||||
let has_ctrl = flags_contains(modifiers, NSEventModifierFlagControl);
|
let has_ctrl = flags_contains(modifiers, NSEventModifierFlagControl);
|
||||||
|
let has_cmd = flags_contains(modifiers, NSEventModifierFlagCommand);
|
||||||
|
|
||||||
let logical_key = match text_with_all_modifiers.as_ref() {
|
let logical_key = match text_with_all_modifiers.as_ref() {
|
||||||
// Only checking for ctrl here, not checking for alt because we DO want to
|
// Only checking for ctrl and cmd here, not checking for alt because we DO want to
|
||||||
// include its effect in the key. For example if -on the Germay layout- one
|
// include its effect in the key. For example if -on the Germay layout- one
|
||||||
// presses alt+8, the logical key should be "{"
|
// presses alt+8, the logical key should be "{"
|
||||||
// Also not checking if this is a release event because then this issue would
|
// Also not checking if this is a release event because then this issue would
|
||||||
// still affect the key release.
|
// still affect the key release.
|
||||||
Some(text) if !has_ctrl => Key::Character(text.clone()),
|
Some(text) if !has_ctrl && !has_cmd => {
|
||||||
|
// Character heeding both SHIFT and ALT.
|
||||||
|
Key::Character(text.clone())
|
||||||
|
}
|
||||||
|
|
||||||
_ => match key_without_modifiers.as_ref() {
|
_ => match key_without_modifiers.as_ref() {
|
||||||
|
// Character heeding just SHIFT, ignoring ALT.
|
||||||
Key::Character(ch) => get_logical_key_char(ns_event, ch),
|
Key::Character(ch) => get_logical_key_char(ns_event, ch),
|
||||||
// Don't try to get text for events which likely don't have it.
|
|
||||||
|
// Character ignoring ALL modifiers.
|
||||||
_ => key_without_modifiers.clone(),
|
_ => key_without_modifiers.clone(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue