windows: Fix ModifiersChanged event (#30617)

Follow-up #30574

Release Notes:

- N/A
This commit is contained in:
张小白 2025-05-13 17:05:24 +08:00 committed by GitHub
parent 8fdf309a4a
commit 29da105dd5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -341,18 +341,32 @@ fn handle_syskeydown_msg(
lparam: LPARAM, lparam: LPARAM,
state_ptr: Rc<WindowsWindowStatePtr>, state_ptr: Rc<WindowsWindowStatePtr>,
) -> Option<isize> { ) -> Option<isize> {
// we need to call `DefWindowProcW`, or we will lose the system-wide `Alt+F4`, `Alt+{other keys}` let mut lock = state_ptr.state.borrow_mut();
// shortcuts. let vkey = wparam.loword();
let keystroke = parse_syskeydown_msg_keystroke(wparam)?; let input = if is_modifier(VIRTUAL_KEY(vkey)) {
let mut func = state_ptr.state.borrow_mut().callbacks.input.take()?; let modifiers = current_modifiers();
let event = KeyDownEvent { if let Some(prev_modifiers) = lock.last_reported_modifiers {
keystroke, if prev_modifiers == modifiers {
is_held: lparam.0 & (0x1 << 30) > 0, return Some(0);
}
}
lock.last_reported_modifiers = Some(modifiers);
PlatformInput::ModifiersChanged(ModifiersChangedEvent { modifiers })
} else {
let keystroke = parse_syskeydown_msg_keystroke(wparam)?;
PlatformInput::KeyDown(KeyDownEvent {
keystroke,
is_held: lparam.0 & (0x1 << 30) > 0,
})
}; };
let result = if !func(PlatformInput::KeyDown(event)).propagate { let mut func = lock.callbacks.input.take()?;
drop(lock);
let result = if !func(input).propagate {
state_ptr.state.borrow_mut().system_key_handled = true; state_ptr.state.borrow_mut().system_key_handled = true;
Some(0) Some(0)
} else { } else {
// we need to call `DefWindowProcW`, or we will lose the system-wide `Alt+F4`, `Alt+{other keys}`
// shortcuts.
None None
}; };
state_ptr.state.borrow_mut().callbacks.input = Some(func); state_ptr.state.borrow_mut().callbacks.input = Some(func);
@ -361,15 +375,29 @@ fn handle_syskeydown_msg(
} }
fn handle_syskeyup_msg(wparam: WPARAM, state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> { fn handle_syskeyup_msg(wparam: WPARAM, state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
// we need to call `DefWindowProcW`, or we will lose the system-wide `Alt+F4`, `Alt+{other keys}` let mut lock = state_ptr.state.borrow_mut();
// shortcuts. let vkey = wparam.loword();
let keystroke = parse_syskeydown_msg_keystroke(wparam)?; let input = if is_modifier(VIRTUAL_KEY(vkey)) {
let mut func = state_ptr.state.borrow_mut().callbacks.input.take()?; let modifiers = current_modifiers();
let event = KeyUpEvent { keystroke }; if let Some(prev_modifiers) = lock.last_reported_modifiers {
let result = if func(PlatformInput::KeyUp(event)).default_prevented { if prev_modifiers == modifiers {
return Some(0);
}
}
lock.last_reported_modifiers = Some(modifiers);
PlatformInput::ModifiersChanged(ModifiersChangedEvent { modifiers })
} else {
let keystroke = parse_syskeydown_msg_keystroke(wparam)?;
PlatformInput::KeyUp(KeyUpEvent { keystroke })
};
let mut func = lock.callbacks.input.take()?;
drop(lock);
let result = if !func(input).propagate {
Some(0) Some(0)
} else { } else {
Some(1) // we need to call `DefWindowProcW`, or we will lose the system-wide `Alt+F4`, `Alt+{other keys}`
// shortcuts.
None
}; };
state_ptr.state.borrow_mut().callbacks.input = Some(func); state_ptr.state.borrow_mut().callbacks.input = Some(func);
@ -421,17 +449,23 @@ fn handle_keyup_msg(wparam: WPARAM, state_ptr: Rc<WindowsWindowStatePtr>) -> Opt
return Some(1); return Some(1);
}; };
let mut lock = state_ptr.state.borrow_mut(); let mut lock = state_ptr.state.borrow_mut();
let Some(mut func) = lock.callbacks.input.take() else {
return Some(1);
};
drop(lock);
let event = match keystroke_or_modifier { let event = match keystroke_or_modifier {
KeystrokeOrModifier::Keystroke(keystroke) => PlatformInput::KeyUp(KeyUpEvent { keystroke }), KeystrokeOrModifier::Keystroke(keystroke) => PlatformInput::KeyUp(KeyUpEvent { keystroke }),
KeystrokeOrModifier::Modifier(modifiers) => { KeystrokeOrModifier::Modifier(modifiers) => {
if let Some(prev_modifiers) = lock.last_reported_modifiers {
if prev_modifiers == modifiers {
return Some(0);
}
}
lock.last_reported_modifiers = Some(modifiers);
PlatformInput::ModifiersChanged(ModifiersChangedEvent { modifiers }) PlatformInput::ModifiersChanged(ModifiersChangedEvent { modifiers })
} }
}; };
let Some(mut func) = lock.callbacks.input.take() else {
return Some(1);
};
drop(lock);
let result = if func(event).default_prevented { let result = if func(event).default_prevented {
Some(0) Some(0)