From 5a0bc016e77c3d69e0539899a3dc3f105302d1a1 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Wed, 12 Sep 2018 20:04:16 +0300 Subject: [PATCH] Add support for F16-F24 (#641) * Added support for F16-F19 keys. * Documented support for F16-F19 keys * Added support for F20 key * Added support for F21-F24 on platforms except macOs * Added support for F21-F24 on macOs * Documented addition of F16-F24 keys * Added missing ref qualifier * Fixed compilation error on 1.24.1 * Refactored methods in macOs events_loop and view files --- CHANGELOG.md | 2 +- src/events.rs | 9 ++++++ src/platform/emscripten/mod.rs | 14 ++++++--- src/platform/linux/wayland/keyboard.rs | 9 ++++++ src/platform/linux/x11/events.rs | 18 +++++------ src/platform/macos/events_loop.rs | 27 +++++++++++++--- src/platform/macos/view.rs | 43 ++++++++++++++++++-------- src/platform/windows/event.rs | 4 +-- 8 files changed, 91 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bed85784..5e345620 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # Unreleased - +- Added support for F16-F24 keys. - Fixed graphical glitches when resizing on Wayland. - On Windows, fix freezes when performing certain actions after a window resize has been triggered. Reintroduces some visual artifacts when resizing. - Updated window manager hints under X11 to v1.5 of [Extended Window Manager Hints](https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html#idm140200472629520). diff --git a/src/events.rs b/src/events.rs index 5a90a373..0edb501d 100644 --- a/src/events.rs +++ b/src/events.rs @@ -317,6 +317,15 @@ pub enum VirtualKeyCode { F13, F14, F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, /// Print Screen/SysRq. Snapshot, diff --git a/src/platform/emscripten/mod.rs b/src/platform/emscripten/mod.rs index 392e22cf..a3d25ef1 100644 --- a/src/platform/emscripten/mod.rs +++ b/src/platform/emscripten/mod.rs @@ -810,11 +810,15 @@ fn key_translate_virt(input: [ffi::EM_UTF8; ffi::EM_HTML5_SHORT_STRING_LEN_BYTES "F13" => Some(F13), "F14" => Some(F14), "F15" => Some(F15), - "F16" => None, - "F17" => None, - "F18" => None, - "F19" => None, - "F20" => None, + "F16" => Some(F16), + "F17" => Some(F17), + "F18" => Some(F18), + "F19" => Some(F19), + "F20" => Some(F20), + "F21" => Some(F21), + "F22" => Some(F22), + "F23" => Some(F23), + "F24" => Some(F24), "Soft1" => None, "Soft2" => None, "Soft3" => None, diff --git a/src/platform/linux/wayland/keyboard.rs b/src/platform/linux/wayland/keyboard.rs index 471aa4f1..e1001178 100644 --- a/src/platform/linux/wayland/keyboard.rs +++ b/src/platform/linux/wayland/keyboard.rs @@ -226,6 +226,15 @@ fn keysym_to_vkey(keysym: u32) -> Option { keysyms::XKB_KEY_F13 => Some(VirtualKeyCode::F13), keysyms::XKB_KEY_F14 => Some(VirtualKeyCode::F14), keysyms::XKB_KEY_F15 => Some(VirtualKeyCode::F15), + keysyms::XKB_KEY_F16 => Some(VirtualKeyCode::F16), + keysyms::XKB_KEY_F17 => Some(VirtualKeyCode::F17), + keysyms::XKB_KEY_F18 => Some(VirtualKeyCode::F18), + keysyms::XKB_KEY_F19 => Some(VirtualKeyCode::F19), + keysyms::XKB_KEY_F20 => Some(VirtualKeyCode::F20), + keysyms::XKB_KEY_F21 => Some(VirtualKeyCode::F21), + keysyms::XKB_KEY_F22 => Some(VirtualKeyCode::F22), + keysyms::XKB_KEY_F23 => Some(VirtualKeyCode::F23), + keysyms::XKB_KEY_F24 => Some(VirtualKeyCode::F24), // flow control keysyms::XKB_KEY_Print => Some(VirtualKeyCode::Snapshot), keysyms::XKB_KEY_Scroll_Lock => Some(VirtualKeyCode::Scroll), diff --git a/src/platform/linux/x11/events.rs b/src/platform/linux/x11/events.rs index e76fb777..037ee4c4 100644 --- a/src/platform/linux/x11/events.rs +++ b/src/platform/linux/x11/events.rs @@ -117,23 +117,23 @@ pub fn keysym_to_element(keysym: libc::c_uint) -> Option { //ffi::XK_L4 => events::VirtualKeyCode::L4, ffi::XK_F15 => events::VirtualKeyCode::F15, //ffi::XK_L5 => events::VirtualKeyCode::L5, - //ffi::XK_F16 => events::VirtualKeyCode::F16, + ffi::XK_F16 => events::VirtualKeyCode::F16, //ffi::XK_L6 => events::VirtualKeyCode::L6, - //ffi::XK_F17 => events::VirtualKeyCode::F17, + ffi::XK_F17 => events::VirtualKeyCode::F17, //ffi::XK_L7 => events::VirtualKeyCode::L7, - //ffi::XK_F18 => events::VirtualKeyCode::F18, + ffi::XK_F18 => events::VirtualKeyCode::F18, //ffi::XK_L8 => events::VirtualKeyCode::L8, - //ffi::XK_F19 => events::VirtualKeyCode::F19, + ffi::XK_F19 => events::VirtualKeyCode::F19, //ffi::XK_L9 => events::VirtualKeyCode::L9, - //ffi::XK_F20 => events::VirtualKeyCode::F20, + ffi::XK_F20 => events::VirtualKeyCode::F20, //ffi::XK_L10 => events::VirtualKeyCode::L10, - //ffi::XK_F21 => events::VirtualKeyCode::F21, + ffi::XK_F21 => events::VirtualKeyCode::F21, //ffi::XK_R1 => events::VirtualKeyCode::R1, - //ffi::XK_F22 => events::VirtualKeyCode::F22, + ffi::XK_F22 => events::VirtualKeyCode::F22, //ffi::XK_R2 => events::VirtualKeyCode::R2, - //ffi::XK_F23 => events::VirtualKeyCode::F23, + ffi::XK_F23 => events::VirtualKeyCode::F23, //ffi::XK_R3 => events::VirtualKeyCode::R3, - //ffi::XK_F24 => events::VirtualKeyCode::F24, + ffi::XK_F24 => events::VirtualKeyCode::F24, //ffi::XK_R4 => events::VirtualKeyCode::R4, //ffi::XK_F25 => events::VirtualKeyCode::F25, //ffi::XK_R5 => events::VirtualKeyCode::R5, diff --git a/src/platform/macos/events_loop.rs b/src/platform/macos/events_loop.rs index edc2923c..7c5e6970 100644 --- a/src/platform/macos/events_loop.rs +++ b/src/platform/macos/events_loop.rs @@ -610,7 +610,7 @@ pub fn to_virtual_key_code(code: c_ushort) -> Option { 0x3d => events::VirtualKeyCode::RAlt, 0x3e => events::VirtualKeyCode::RControl, //0x3f => Fn key, - //0x40 => F17 Key, + 0x40 => events::VirtualKeyCode::F17, 0x41 => events::VirtualKeyCode::Decimal, //0x42 -> unkown, 0x43 => events::VirtualKeyCode::Multiply, @@ -625,8 +625,8 @@ pub fn to_virtual_key_code(code: c_ushort) -> Option { 0x4c => events::VirtualKeyCode::NumpadEnter, //0x4d => unkown, 0x4e => events::VirtualKeyCode::Subtract, - //0x4f => F18 key, - //0x50 => F19 Key, + 0x4f => events::VirtualKeyCode::F18, + 0x50 => events::VirtualKeyCode::F19, 0x51 => events::VirtualKeyCode::NumpadEquals, 0x52 => events::VirtualKeyCode::Numpad0, 0x53 => events::VirtualKeyCode::Numpad1, @@ -636,7 +636,7 @@ pub fn to_virtual_key_code(code: c_ushort) -> Option { 0x57 => events::VirtualKeyCode::Numpad5, 0x58 => events::VirtualKeyCode::Numpad6, 0x59 => events::VirtualKeyCode::Numpad7, - //0x5a => F20 Key, + 0x5a => events::VirtualKeyCode::F20, 0x5b => events::VirtualKeyCode::Numpad8, 0x5c => events::VirtualKeyCode::Numpad9, //0x5d => unkown, @@ -652,7 +652,7 @@ pub fn to_virtual_key_code(code: c_ushort) -> Option { 0x67 => events::VirtualKeyCode::F11, //0x68 => unkown, 0x69 => events::VirtualKeyCode::F13, - //0x6a => F16 Key, + 0x6a => events::VirtualKeyCode::F16, 0x6b => events::VirtualKeyCode::F14, //0x6c => unkown, 0x6d => events::VirtualKeyCode::F10, @@ -680,6 +680,23 @@ pub fn to_virtual_key_code(code: c_ushort) -> Option { }) } +pub fn check_additional_virtual_key_codes( + s: &Option +) -> Option { + if let &Some(ref s) = s { + if let Some(ch) = s.encode_utf16().next() { + return Some(match ch { + 0xf718 => events::VirtualKeyCode::F21, + 0xf719 => events::VirtualKeyCode::F22, + 0xf71a => events::VirtualKeyCode::F23, + 0xf71b => events::VirtualKeyCode::F24, + _ => return None, + }) + } + } + None +} + pub fn event_mods(event: cocoa::base::id) -> ModifiersState { let flags = unsafe { NSEvent::modifierFlags(event) diff --git a/src/platform/macos/view.rs b/src/platform/macos/view.rs index f042e88e..1e70be99 100644 --- a/src/platform/macos/view.rs +++ b/src/platform/macos/view.rs @@ -14,7 +14,7 @@ use objc::declare::ClassDecl; use objc::runtime::{Class, Object, Protocol, Sel, BOOL, YES}; use {ElementState, Event, KeyboardInput, MouseButton, WindowEvent, WindowId}; -use platform::platform::events_loop::{DEVICE_ID, event_mods, Shared, to_virtual_key_code}; +use platform::platform::events_loop::{DEVICE_ID, event_mods, Shared, to_virtual_key_code, check_additional_virtual_key_codes}; use platform::platform::util; use platform::platform::ffi::*; use platform::platform::window::{get_window_id, IdRef}; @@ -344,6 +344,18 @@ extern fn do_command_by_selector(this: &Object, _sel: Sel, command: Sel) { } } +fn get_characters(event: id) -> Option { + unsafe { + let characters: id = msg_send![event, characters]; + let slice = slice::from_raw_parts( + characters.UTF8String() as *const c_uchar, + characters.len(), + ); + let string = str::from_utf8_unchecked(slice); + Some(string.to_owned()) + } +} + extern fn key_down(this: &Object, _sel: Sel, event: id) { //println!("keyDown"); unsafe { @@ -351,8 +363,16 @@ extern fn key_down(this: &Object, _sel: Sel, event: id) { let state = &mut *(state_ptr as *mut ViewState); let window_id = WindowId(get_window_id(state.window)); + state.raw_characters = get_characters(event); + let keycode: c_ushort = msg_send![event, keyCode]; - let virtual_keycode = to_virtual_key_code(keycode); + // We are checking here for F21-F24 keys, since their keycode + // can vary, but we know that they are encoded + // in characters property. + let virtual_keycode = to_virtual_key_code(keycode) + .or_else(|| { + check_additional_virtual_key_codes(&state.raw_characters) + }); let scancode = keycode as u32; let is_repeat = msg_send![event, isARepeat]; @@ -369,16 +389,6 @@ extern fn key_down(this: &Object, _sel: Sel, event: id) { }, }; - state.raw_characters = { - let characters: id = msg_send![event, characters]; - let slice = slice::from_raw_parts( - characters.UTF8String() as *const c_uchar, - characters.len(), - ); - let string = str::from_utf8_unchecked(slice); - Some(string.to_owned()) - }; - if let Some(shared) = state.shared.upgrade() { shared.pending_events .lock() @@ -416,8 +426,15 @@ extern fn key_up(this: &Object, _sel: Sel, event: id) { state.last_insert = None; + // We need characters here to check for additional keys such as + // F21-F24. + let characters = get_characters(event); + let keycode: c_ushort = msg_send![event, keyCode]; - let virtual_keycode = to_virtual_key_code(keycode); + let virtual_keycode = to_virtual_key_code(keycode) + .or_else(|| { + check_additional_virtual_key_codes(&characters) + }); let scancode = keycode as u32; let window_event = Event::WindowEvent { window_id: WindowId(get_window_id(state.window)), diff --git a/src/platform/windows/event.rs b/src/platform/windows/event.rs index 7c35aa91..dfdff6ee 100644 --- a/src/platform/windows/event.rs +++ b/src/platform/windows/event.rs @@ -148,7 +148,7 @@ pub fn vkey_to_winit_vkey(vkey: c_int) -> Option { winuser::VK_F13 => Some(VirtualKeyCode::F13), winuser::VK_F14 => Some(VirtualKeyCode::F14), winuser::VK_F15 => Some(VirtualKeyCode::F15), - /*winuser::VK_F16 => Some(VirtualKeyCode::F16), + winuser::VK_F16 => Some(VirtualKeyCode::F16), winuser::VK_F17 => Some(VirtualKeyCode::F17), winuser::VK_F18 => Some(VirtualKeyCode::F18), winuser::VK_F19 => Some(VirtualKeyCode::F19), @@ -156,7 +156,7 @@ pub fn vkey_to_winit_vkey(vkey: c_int) -> Option { winuser::VK_F21 => Some(VirtualKeyCode::F21), winuser::VK_F22 => Some(VirtualKeyCode::F22), winuser::VK_F23 => Some(VirtualKeyCode::F23), - winuser::VK_F24 => Some(VirtualKeyCode::F24),*/ + winuser::VK_F24 => Some(VirtualKeyCode::F24), winuser::VK_NUMLOCK => Some(VirtualKeyCode::Numlock), winuser::VK_SCROLL => Some(VirtualKeyCode::Scroll), winuser::VK_BROWSER_BACK => Some(VirtualKeyCode::NavigateBackward),