On macOS, fix assertion when pressing Fn key

This commit is contained in:
Kirill Chibisov 2023-11-17 15:56:03 +04:00 committed by GitHub
parent 14140607d1
commit 7bed5eecfd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 91 deletions

View file

@ -16,6 +16,7 @@ Unreleased` header.
- On Windows, fix `set_control_flow` in `AboutToWait` not being taken in account. - On Windows, fix `set_control_flow` in `AboutToWait` not being taken in account.
- On macOS, send a `Resized` event after each `ScaleFactorChanged` event. - On macOS, send a `Resized` event after each `ScaleFactorChanged` event.
- On Wayland, fix `wl_surface` being destroyed before associated objects. - On Wayland, fix `wl_surface` being destroyed before associated objects.
- On macOS, fix assertion when pressing `Fn` key.
# 0.29.3 # 0.29.3

View file

@ -156,13 +156,11 @@ pub(crate) fn create_key_event(
// 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 => Key::Character(text.clone()),
_ => { _ => match key_without_modifiers.as_ref() {
let modifierless_chars = match key_without_modifiers.as_ref() { Key::Character(ch) => get_logical_key_char(ns_event, ch),
Key::Character(ch) => ch, // Don't try to get text for events which likely don't have it.
_ => "", _ => key_without_modifiers.clone(),
}; },
get_logical_key_char(ns_event, modifierless_chars)
}
}; };
(logical_key, key_without_modifiers) (logical_key, key_without_modifiers)

View file

@ -74,8 +74,8 @@ enum ImeState {
bitflags! { bitflags! {
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
struct ModLocationMask: u8 { struct ModLocationMask: u8 {
const LEFT = 1; const LEFT = 0b0001;
const RIGHT = 2; const RIGHT = 0b0010;
} }
} }
impl ModLocationMask { impl ModLocationMask {
@ -88,13 +88,13 @@ impl ModLocationMask {
} }
} }
fn key_to_modifier(key: &Key) -> ModifiersState { fn key_to_modifier(key: &Key) -> Option<ModifiersState> {
match key { match key {
Key::Named(NamedKey::Alt) => ModifiersState::ALT, Key::Named(NamedKey::Alt) => Some(ModifiersState::ALT),
Key::Named(NamedKey::Control) => ModifiersState::CONTROL, Key::Named(NamedKey::Control) => Some(ModifiersState::CONTROL),
Key::Named(NamedKey::Super) => ModifiersState::SUPER, Key::Named(NamedKey::Super) => Some(ModifiersState::SUPER),
Key::Named(NamedKey::Shift) => ModifiersState::SHIFT, Key::Named(NamedKey::Shift) => Some(ModifiersState::SHIFT),
_ => unreachable!(), _ => None,
} }
} }
@ -924,6 +924,7 @@ impl WinitView {
// event, thus we can't generate regular presses based on that. The `ModifiersChanged` // event, thus we can't generate regular presses based on that. The `ModifiersChanged`
// later will work though, since the flags are attached to the event and contain valid // later will work though, since the flags are attached to the event and contain valid
// information. // information.
'send_event: {
if is_flags_changed_event && ns_event.key_code() != 0 { if is_flags_changed_event && ns_event.key_code() != 0 {
let scancode = ns_event.key_code(); let scancode = ns_event.key_code();
let physical_key = PhysicalKey::from_scancode(scancode as u32); let physical_key = PhysicalKey::from_scancode(scancode as u32);
@ -932,7 +933,11 @@ impl WinitView {
let mut event = create_key_event(ns_event, false, false, Some(physical_key)); let mut event = create_key_event(ns_event, false, false, Some(physical_key));
let key = code_to_key(physical_key, scancode); let key = code_to_key(physical_key, scancode);
let event_modifier = key_to_modifier(&key); // Ignore processing of unkown modifiers because we can't determine whether
// it was pressed or release reliably.
let Some(event_modifier) = key_to_modifier(&key) else {
break 'send_event;
};
event.physical_key = physical_key; event.physical_key = physical_key;
event.logical_key = key.clone(); event.logical_key = key.clone();
event.location = code_to_location(physical_key); event.location = code_to_location(physical_key);
@ -974,7 +979,6 @@ impl WinitView {
} }
*phys_mod = ModLocationMask::empty(); *phys_mod = ModLocationMask::empty();
} else { } else {
// is_active
if *phys_mod == location_mask { if *phys_mod == location_mask {
// Here we hit a contradiction: // Here we hit a contradiction:
// The modifier state was "changed" to active, // The modifier state was "changed" to active,
@ -1011,6 +1015,7 @@ impl WinitView {
self.queue_event(event); self.queue_event(event);
} }
} }
}
if prev_modifiers == current_modifiers { if prev_modifiers == current_modifiers {
return; return;