mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
Implement windows focus key press/release on Windows (#1307)
* X11: Sync key press/release with window focus * When a window loses focus, key release events are issued for all pressed keys * When a window gains focus, key press events are issued for all pressed keys * Adds `is_synthetic` field to `WindowEvent` variant `KeyboardInput` to indicate that these events are synthetic. * Adds `is_synthetic: false` to `WindowEvent::KeyboardInput` events issued on all other platforms * Implement windows focus key press/release on Windows * Docs Co-authored-by: Murarth <murarth@gmail.com>
This commit is contained in:
parent
5d99316c96
commit
cc206d31b7
|
@ -32,6 +32,9 @@
|
||||||
- On X11, generate synthetic key events for keys held when a window gains or loses focus.
|
- On X11, generate synthetic key events for keys held when a window gains or loses focus.
|
||||||
- On X11, issue a `CursorMoved` event when a `Touch` event occurs,
|
- On X11, issue a `CursorMoved` event when a `Touch` event occurs,
|
||||||
as X11 implicitly moves the cursor for such events.
|
as X11 implicitly moves the cursor for such events.
|
||||||
|
- Add `is_synthetic` field to `WindowEvent` variant `KeyboardInput`,
|
||||||
|
indicating that the event is generated by winit.
|
||||||
|
- On X11 and Windows, generate synthetic key events for keys held when a window gains or loses focus.
|
||||||
|
|
||||||
# 0.20.0 Alpha 4 (2019-10-18)
|
# 0.20.0 Alpha 4 (2019-10-18)
|
||||||
|
|
||||||
|
|
|
@ -150,9 +150,10 @@ pub enum WindowEvent {
|
||||||
/// If `true`, the event was generated synthetically by winit
|
/// If `true`, the event was generated synthetically by winit
|
||||||
/// in one of the following circumstances:
|
/// in one of the following circumstances:
|
||||||
///
|
///
|
||||||
/// * **X11**: Synthetic key press events are generated for all keys pressed
|
/// * Synthetic key press events are generated for all keys pressed
|
||||||
/// when a window gains focus. Likewise, synthetic key release events
|
/// when a window gains focus. Likewise, synthetic key release events
|
||||||
/// are generated for all keys pressed when a window goes out of focus.
|
/// are generated for all keys pressed when a window goes out of focus.
|
||||||
|
/// ***Currently, this is only functional on X11 and Windows***
|
||||||
///
|
///
|
||||||
/// Otherwise, this value is always `false`.
|
/// Otherwise, this value is always `false`.
|
||||||
is_synthetic: bool,
|
is_synthetic: bool,
|
||||||
|
|
|
@ -27,6 +27,16 @@ pub fn get_key_mods() -> ModifiersState {
|
||||||
mods
|
mods
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_pressed_keys() -> impl Iterator<Item = c_int> {
|
||||||
|
let mut keyboard_state = vec![0u8; 256];
|
||||||
|
unsafe { winuser::GetKeyboardState(keyboard_state.as_mut_ptr()) };
|
||||||
|
keyboard_state
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, p)| (*p & (1 << 7)) != 0) // whether or not a key is pressed is communicated via the high-order bit
|
||||||
|
.map(|(i, _)| i as c_int)
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn get_char(keyboard_state: &[u8; 256], v_key: u32, hkl: HKL) -> Option<char> {
|
unsafe fn get_char(keyboard_state: &[u8; 256], v_key: u32, hkl: HKL) -> Option<char> {
|
||||||
let mut unicode_bytes = [0u16; 5];
|
let mut unicode_bytes = [0u16; 5];
|
||||||
let len = winuser::ToUnicodeEx(
|
let len = winuser::ToUnicodeEx(
|
||||||
|
|
|
@ -1421,7 +1421,27 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
}
|
}
|
||||||
|
|
||||||
winuser::WM_SETFOCUS => {
|
winuser::WM_SETFOCUS => {
|
||||||
use crate::event::WindowEvent::Focused;
|
use crate::event::{ElementState::Released, WindowEvent::Focused};
|
||||||
|
for windows_keycode in event::get_pressed_keys() {
|
||||||
|
let scancode =
|
||||||
|
winuser::MapVirtualKeyA(windows_keycode as _, winuser::MAPVK_VK_TO_VSC);
|
||||||
|
let virtual_keycode = event::vkey_to_winit_vkey(windows_keycode);
|
||||||
|
|
||||||
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
|
window_id: RootWindowId(WindowId(window)),
|
||||||
|
event: WindowEvent::KeyboardInput {
|
||||||
|
device_id: DEVICE_ID,
|
||||||
|
input: KeyboardInput {
|
||||||
|
scancode,
|
||||||
|
virtual_keycode,
|
||||||
|
state: Released,
|
||||||
|
modifiers: event::get_key_mods(),
|
||||||
|
},
|
||||||
|
is_synthetic: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: RootWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: Focused(true),
|
event: Focused(true),
|
||||||
|
@ -1431,7 +1451,27 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
}
|
}
|
||||||
|
|
||||||
winuser::WM_KILLFOCUS => {
|
winuser::WM_KILLFOCUS => {
|
||||||
use crate::event::WindowEvent::Focused;
|
use crate::event::{ElementState::Released, WindowEvent::Focused};
|
||||||
|
for windows_keycode in event::get_pressed_keys() {
|
||||||
|
let scancode =
|
||||||
|
winuser::MapVirtualKeyA(windows_keycode as _, winuser::MAPVK_VK_TO_VSC);
|
||||||
|
let virtual_keycode = event::vkey_to_winit_vkey(windows_keycode);
|
||||||
|
|
||||||
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
|
window_id: RootWindowId(WindowId(window)),
|
||||||
|
event: WindowEvent::KeyboardInput {
|
||||||
|
device_id: DEVICE_ID,
|
||||||
|
input: KeyboardInput {
|
||||||
|
scancode,
|
||||||
|
virtual_keycode,
|
||||||
|
state: Released,
|
||||||
|
modifiers: event::get_key_mods(),
|
||||||
|
},
|
||||||
|
is_synthetic: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: RootWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: Focused(false),
|
event: Focused(false),
|
||||||
|
|
Loading…
Reference in a new issue