mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
parent
dec728cfa2
commit
fddfb2e2d6
|
@ -16,6 +16,7 @@
|
|||
- macOS keyboard handling has been overhauled, allowing for the use of dead keys, IME, etc. Right modifier keys are also no longer reported as being left.
|
||||
- Added the `Window::set_ime_spot(x: i32, y: i32)` method, which is implemented on X11 and macOS.
|
||||
- **Breaking**: `os::unix::WindowExt::send_xim_spot(x: i16, y: i16)` no longer exists. Switch to the new `Window::set_ime_spot(x: i32, y: i32)`, which has equivalent functionality.
|
||||
- Fixed detection of `Pause` and `Scroll` keys on Windows.
|
||||
|
||||
# Version 0.14.0 (2018-05-09)
|
||||
|
||||
|
|
|
@ -205,31 +205,49 @@ pub fn vkey_to_winit_vkey(vkey: c_int) -> Option<VirtualKeyCode> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn vkey_left_right(vkey: c_int, scancode: UINT, extended: bool) -> c_int {
|
||||
match vkey {
|
||||
winuser::VK_SHIFT => unsafe { winuser::MapVirtualKeyA(
|
||||
scancode,
|
||||
winuser::MAPVK_VSC_TO_VK_EX,
|
||||
) as _ },
|
||||
winuser::VK_CONTROL => if extended {
|
||||
winuser::VK_RCONTROL
|
||||
} else {
|
||||
winuser::VK_LCONTROL
|
||||
},
|
||||
winuser::VK_MENU => if extended {
|
||||
winuser::VK_RMENU
|
||||
} else {
|
||||
winuser::VK_LMENU
|
||||
},
|
||||
_ => vkey,
|
||||
}
|
||||
pub fn handle_extended_keys(vkey: c_int, mut scancode: UINT, extended: bool) -> Option<(c_int, UINT)> {
|
||||
// Welcome to hell https://blog.molecular-matters.com/2011/09/05/properly-handling-keyboard-input/
|
||||
let vkey = match vkey {
|
||||
winuser::VK_SHIFT => unsafe { winuser::MapVirtualKeyA(
|
||||
scancode,
|
||||
winuser::MAPVK_VSC_TO_VK_EX,
|
||||
) as _ },
|
||||
winuser::VK_CONTROL => if extended {
|
||||
winuser::VK_RCONTROL
|
||||
} else {
|
||||
winuser::VK_LCONTROL
|
||||
},
|
||||
winuser::VK_MENU => if extended {
|
||||
winuser::VK_RMENU
|
||||
} else {
|
||||
winuser::VK_LMENU
|
||||
},
|
||||
_ => match scancode {
|
||||
// This is only triggered when using raw input. Without this check, we get two events whenever VK_PAUSE is
|
||||
// pressed, the first one having scancode 0x1D but vkey VK_PAUSE...
|
||||
0x1D if vkey == winuser::VK_PAUSE => return None,
|
||||
// ...and the second having scancode 0x45 but an unmatched vkey!
|
||||
0x45 => winuser::VK_PAUSE,
|
||||
// VK_PAUSE and VK_SCROLL have the same scancode when using modifiers, alongside incorrect vkey values.
|
||||
0x46 => {
|
||||
if extended {
|
||||
scancode = 0x45;
|
||||
winuser::VK_PAUSE
|
||||
} else {
|
||||
winuser::VK_SCROLL
|
||||
}
|
||||
},
|
||||
_ => vkey,
|
||||
},
|
||||
};
|
||||
Some((vkey, scancode))
|
||||
}
|
||||
|
||||
pub fn vkeycode_to_element(wparam: WPARAM, lparam: LPARAM) -> (ScanCode, Option<VirtualKeyCode>) {
|
||||
pub fn process_key_params(wparam: WPARAM, lparam: LPARAM) -> Option<(ScanCode, Option<VirtualKeyCode>)> {
|
||||
let scancode = ((lparam >> 16) & 0xff) as UINT;
|
||||
let extended = (lparam & 0x01000000) != 0;
|
||||
let vkey = vkey_left_right(wparam as _, scancode, extended);
|
||||
(scancode, vkey_to_winit_vkey(vkey))
|
||||
handle_extended_keys(wparam as _, scancode, extended)
|
||||
.map(|(vkey, scancode)| (scancode, vkey_to_winit_vkey(vkey)))
|
||||
}
|
||||
|
||||
// This is needed as windows doesn't properly distinguish
|
||||
|
|
|
@ -34,7 +34,7 @@ use winapi::um::winnt::{LONG, SHORT};
|
|||
|
||||
use events::DeviceEvent;
|
||||
use platform::platform::{event, Cursor, WindowId, DEVICE_ID, wrap_device_id, util};
|
||||
use platform::platform::event::{vkey_to_winit_vkey, vkey_left_right};
|
||||
use platform::platform::event::{handle_extended_keys, process_key_params, vkey_to_winit_vkey};
|
||||
use platform::platform::raw_input::*;
|
||||
use platform::platform::window::adjust_size;
|
||||
|
||||
|
@ -586,26 +586,27 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
if msg == winuser::WM_SYSKEYDOWN && wparam as i32 == winuser::VK_F4 {
|
||||
winuser::DefWindowProcW(window, msg, wparam, lparam)
|
||||
} else {
|
||||
let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam);
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: WindowEvent::KeyboardInput {
|
||||
device_id: DEVICE_ID,
|
||||
input: KeyboardInput {
|
||||
state: Pressed,
|
||||
scancode: scancode,
|
||||
virtual_keycode: vkey,
|
||||
modifiers: event::get_key_mods(),
|
||||
}
|
||||
}
|
||||
});
|
||||
// Windows doesn't emit a delete character by default, but in order to make it
|
||||
// consistent with the other platforms we'll emit a delete character here.
|
||||
if vkey == Some(VirtualKeyCode::Delete) {
|
||||
if let Some((scancode, vkey)) = process_key_params(wparam, lparam) {
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: WindowEvent::ReceivedCharacter('\u{7F}'),
|
||||
event: WindowEvent::KeyboardInput {
|
||||
device_id: DEVICE_ID,
|
||||
input: KeyboardInput {
|
||||
state: Pressed,
|
||||
scancode: scancode,
|
||||
virtual_keycode: vkey,
|
||||
modifiers: event::get_key_mods(),
|
||||
}
|
||||
}
|
||||
});
|
||||
// Windows doesn't emit a delete character by default, but in order to make it
|
||||
// consistent with the other platforms we'll emit a delete character here.
|
||||
if vkey == Some(VirtualKeyCode::Delete) {
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: WindowEvent::ReceivedCharacter('\u{7F}'),
|
||||
});
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
|
@ -613,19 +614,20 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
|
||||
winuser::WM_KEYUP | winuser::WM_SYSKEYUP => {
|
||||
use events::ElementState::Released;
|
||||
let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam);
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: WindowEvent::KeyboardInput {
|
||||
device_id: DEVICE_ID,
|
||||
input: KeyboardInput {
|
||||
state: Released,
|
||||
scancode: scancode,
|
||||
virtual_keycode: vkey,
|
||||
modifiers: event::get_key_mods(),
|
||||
},
|
||||
}
|
||||
});
|
||||
if let Some((scancode, vkey)) = process_key_params(wparam, lparam) {
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: WindowEvent::KeyboardInput {
|
||||
device_id: DEVICE_ID,
|
||||
input: KeyboardInput {
|
||||
state: Released,
|
||||
scancode: scancode,
|
||||
virtual_keycode: vkey,
|
||||
modifiers: event::get_key_mods(),
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
0
|
||||
},
|
||||
|
||||
|
@ -836,23 +838,25 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
};
|
||||
|
||||
let scancode = keyboard.MakeCode as _;
|
||||
let extended = util::has_flag(keyboard.Flags, winuser::RI_KEY_E0 as _);
|
||||
let vkey = vkey_left_right(
|
||||
let extended = util::has_flag(keyboard.Flags, winuser::RI_KEY_E0 as _)
|
||||
| util::has_flag(keyboard.Flags, winuser::RI_KEY_E1 as _);
|
||||
if let Some((vkey, scancode)) = handle_extended_keys(
|
||||
keyboard.VKey as _,
|
||||
scancode,
|
||||
extended,
|
||||
);
|
||||
let virtual_keycode = vkey_to_winit_vkey(vkey);
|
||||
) {
|
||||
let virtual_keycode = vkey_to_winit_vkey(vkey);
|
||||
|
||||
send_event(Event::DeviceEvent {
|
||||
device_id,
|
||||
event: Key(KeyboardInput {
|
||||
scancode,
|
||||
state,
|
||||
virtual_keycode,
|
||||
modifiers: event::get_key_mods(),
|
||||
}),
|
||||
});
|
||||
send_event(Event::DeviceEvent {
|
||||
device_id,
|
||||
event: Key(KeyboardInput {
|
||||
scancode,
|
||||
state,
|
||||
virtual_keycode,
|
||||
modifiers: event::get_key_mods(),
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue