Fix key input not working after loss of focus due to global shortcut

When a global shortcut, like ^-Cmd-Q on macOS to lock the screen, causes
a loss of window focus, we'll receive a key event from the windowing
system for the modifier, but we'll never receive the "Q" in this example
(as press or release). So later, when we regain focus, we'd assume that
our keyboard modifier state is still "pressed ^/Cmd", which is
incorrect. Therefore assume that a loss of window focus implies a reset
keyboard of keyboard modifier state.

Fixes #2098
This commit is contained in:
Simon Hausmann 2023-01-23 11:05:47 +01:00 committed by Simon Hausmann
parent 3290e58228
commit 33d68687c2
2 changed files with 38 additions and 0 deletions

View file

@ -464,6 +464,12 @@ impl WindowInner {
if let Some(focus_item) = self.focus_item.borrow().upgrade() {
focus_item.borrow().as_ref().focus_event(&event, &self.window_adapter(), &focus_item);
}
// If we lost focus due to for example a global shortcut, then when we regain focus
// should not assume that the modifiers are in the same state.
if !have_focus {
self.modifiers.take();
}
}
/// Take the focus_item out of this Window

View file

@ -172,5 +172,37 @@ assert_eq!(instance.get_alt_modifier(), false);
assert_eq!(instance.get_control_modifier(), false);
assert_eq!(instance.get_meta_modifier(), false);
slint_testing::send_keyboard_char(&instance, 'a', true);
slint_testing::send_keyboard_char(&instance, 'a', false);
assert_eq!(instance.get_shift_modifier(), false);
assert_eq!(instance.get_alt_modifier(), false);
assert_eq!(instance.get_control_modifier(), false);
assert_eq!(instance.get_meta_modifier(), false);
// Check that loss of windows focus and regaining it, resets the internal modifier
// state.
slint_testing::send_keyboard_char(&instance, Key::Control.into(), true);
slint_testing::send_keyboard_char(&instance, 'a', true);
slint_testing::send_keyboard_char(&instance, 'a', false);
assert_eq!(instance.get_shift_modifier(), false);
assert_eq!(instance.get_alt_modifier(), false);
assert_eq!(instance.get_control_modifier(), true);
assert_eq!(instance.get_meta_modifier(), false);
// Pretend that Ctrl-something results in a loss of focus, so we never receive the "something" key,
// but we observe a loss of focus.
// TODO: create public API for window focus gain/loss
let window_inner = slint::private_unstable_api::re_exports::WindowInner::from_pub(instance.window());
window_inner.set_active(false);
window_inner.set_focus(false);
window_inner.set_active(true);
window_inner.set_focus(true);
slint_testing::send_keyboard_char(&instance, 'a', true);
slint_testing::send_keyboard_char(&instance, 'a', false);
assert_eq!(instance.get_shift_modifier(), false);
assert_eq!(instance.get_alt_modifier(), false);
assert_eq!(instance.get_control_modifier(), false);
assert_eq!(instance.get_meta_modifier(), false);
```
*/