diff --git a/src/qt/cocoa_keyboard.hpp b/src/qt/cocoa_keyboard.hpp new file mode 100644 index 000000000..b4359c7d9 --- /dev/null +++ b/src/qt/cocoa_keyboard.hpp @@ -0,0 +1,129 @@ +std::array cocoa_keycodes = { /* key names in parentheses are not declared by Apple headers */ + 0x1e, /* ANSI_A */ + 0x1f, /* ANSI_S */ + 0x20, /* ANSI_D */ + 0x21, /* ANSI_F */ + 0x23, /* ANSI_H */ + 0x22, /* ANSI_G */ + 0x2c, /* ANSI_Z */ + 0x2d, /* ANSI_X */ + 0x2e, /* ANSI_C */ + 0x2f, /* ANSI_V */ + 0x56, /* ISO_Section */ + 0x30, /* ANSI_B */ + 0x10, /* ANSI_Q */ + 0x11, /* ANSI_W */ + 0x12, /* ANSI_E */ + 0x13, /* ANSI_R */ + 0x15, /* ANSI_Y */ + 0x14, /* ANSI_T */ + 0x02, /* ANSI_1 */ + 0x03, /* ANSI_2 */ + 0x04, /* ANSI_3 */ + 0x05, /* ANSI_4 */ + 0x07, /* ANSI_6 */ + 0x06, /* ANSI_5 */ + 0x0d, /* ANSI_Equal */ + 0x0a, /* ANSI_9 */ + 0x08, /* ANSI_7 */ + 0x0c, /* ANSI_Minus */ + 0x09, /* ANSI_8 */ + 0x0b, /* ANSI_0 */ + 0x1b, /* ANSI_RightBracket */ + 0x18, /* ANSI_O */ + 0x16, /* ANSI_U */ + 0x1a, /* ANSI_LeftBracket */ + 0x17, /* ANSI_I */ + 0x19, /* ANSI_P */ + 0x1c, /* Return */ + 0x26, /* ANSI_L */ + 0x24, /* ANSI_J */ + 0x28, /* ANSI_Quote */ + 0x25, /* ANSI_K */ + 0x27, /* ANSI_Semicolon */ + 0x2b, /* ANSI_Backslash */ + 0x33, /* ANSI_Comma */ + 0x35, /* ANSI_Slash */ + 0x31, /* ANSI_N */ + 0x32, /* ANSI_M */ + 0x34, /* ANSI_Period */ + 0x0f, /* Tab */ + 0x39, /* Space */ + 0x29, /* ANSI_Grave */ + 0x0e, /* Delete => Backspace */ + 0x11c, /* (ANSI_KeypadEnter) */ + 0x01, /* Escape */ + 0x15c, /* (RightCommand) => Right Windows */ + 0x15b, /* (Left)Command => Left Windows */ + 0x2a, /* Shift */ + 0x3a, /* CapsLock */ + 0x38, /* Option */ + 0x1d, /* Control */ + 0x36, /* RightShift */ + 0x138, /* RightOption */ + 0x11d, /* RightControl */ + 0x15c, /* Function */ + 0x5e, /* F17 => F14 */ + 0x53, /* ANSI_KeypadDecimal */ + 0, + 0x37, /* ANSI_KeypadMultiply */ + 0, + 0x4e, /* ANSI_KeypadPlus */ + 0, + 0x45, /* ANSI_KeypadClear => Num Lock (location equivalent) */ + 0x130, /* VolumeUp */ + 0x12e, /* VolumeDown */ + 0x120, /* Mute */ + 0x135, /* ANSI_KeypadDivide */ + 0x11c, /* ANSI_KeypadEnter */ + 0, + 0x4a, /* ANSI_KeypadMinus */ + 0x5f, /* F18 => F15 */ + 0, /* F19 */ + 0x59, /* ANSI_KeypadEquals */ + 0x52, /* ANSI_Keypad0 */ + 0x4f, /* ANSI_Keypad1 */ + 0x50, /* ANSI_Keypad2 */ + 0x51, /* ANSI_Keypad3 */ + 0x4b, /* ANSI_Keypad4 */ + 0x4c, /* ANSI_Keypad5 */ + 0x4d, /* ANSI_Keypad6 */ + 0x47, /* ANSI_Keypad7 */ + 0, /* F20 */ + 0x48, /* ANSI_Keypad8 */ + 0x49, /* ANSI_Keypad9 */ + 0x7d, /* JIS_Yen */ + 0x73, /* JIS_Underscore */ + 0x5c, /* JIS_KeypadComma */ + 0x3f, /* F5 */ + 0x40, /* F6 */ + 0x41, /* F7 */ + 0x3d, /* F3 */ + 0x42, /* F8 */ + 0x43, /* F9 */ + 0x7b, /* JIS_Eisu => muhenkan (location equivalent) */ + 0x57, /* F11 */ + 0x79, /* JIS_Kana => henkan (location equivalent) */ + 0x137, /* F13 => SysRq (location equivalent) */ + 0x5d, /* F16 => F13 */ + 0x46, /* F14 => Scroll Lock (location equivalent) */ + 0, + 0x44, /* F10 */ + 0x15d, /* (Menu) */ + 0x58, /* F12 */ + 0, + 0x145, /* F15 => Pause (location equivalent) */ + 0x152, /* Help => Insert (location equivalent) */ + 0x147, /* Home */ + 0x149, /* PageUp */ + 0x153, /* ForwardDelete */ + 0x3e, /* F4 */ + 0x14f, /* End */ + 0x3c, /* F2 */ + 0x151, /* PageDown */ + 0x3b, /* F1 */ + 0x14b, /* LeftArrow */ + 0x14d, /* RightArrow */ + 0x150, /* DownArrow */ + 0x148, /* UpArrow */ +}; diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index 4aad4e377..505618ef7 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -69,7 +69,7 @@ static std::unordered_map evdev_keycodes = { /* Multimedia keys. Guideline is to try and follow the Microsoft standard, then fill in remaining scancodes with OEM-specific keys for redundancy sake. Keys marked with # are not translated into evdev codes by the standard atkbd driver. */ - {117, 0x59}, /* Num= */ + {117, 0x59}, /* KPEQUAL */ {418, 0x6a}, /* ZOOMIN# => Logitech */ {420, 0x6b}, /* ZOOMRESET# => Logitech */ {223, 0x6d}, /* CANCEL# => Logitech */ diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 89e010702..2a1268a7f 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -115,6 +115,7 @@ extern int qt_nvr_save(void); #endif #ifdef Q_OS_MACOS +# include "cocoa_keyboard.hpp" // The namespace is required to avoid clashing typedefs; we only use this // header for its #defines anyway. namespace IOKit { @@ -905,139 +906,6 @@ MainWindow::on_actionSettings_triggered() plat_pause(currentPause); } -#ifdef Q_OS_MACOS -std::array darwin_to_xt { - 0x1E, - 0x1F, - 0x20, - 0x21, - 0x23, - 0x22, - 0x2C, - 0x2D, - 0x2E, - 0x2F, - 0x2B, - 0x30, - 0x10, - 0x11, - 0x12, - 0x13, - 0x15, - 0x14, - 0x02, - 0x03, - 0x04, - 0x05, - 0x07, - 0x06, - 0x0D, - 0x0A, - 0x08, - 0x0C, - 0x09, - 0x0B, - 0x1B, - 0x18, - 0x16, - 0x1A, - 0x17, - 0x19, - 0x1C, - 0x26, - 0x24, - 0x28, - 0x25, - 0x27, - 0x2B, - 0x33, - 0x35, - 0x31, - 0x32, - 0x34, - 0x0F, - 0x39, - 0x29, - 0x0E, - 0x11C, - 0x01, - 0x15C, - 0x15B, - 0x2A, - 0x3A, - 0x38, - 0x1D, - 0x36, - 0x138, - 0x11D, - 0x15C, - 0, - 0x53, - 0, - 0x37, - 0, - 0x4E, - 0, - 0x45, - 0x130, - 0x12E, - 0x120, - 0x135, - 0x11C, - 0, - 0x4A, - 0, - 0, - 0, - 0x52, - 0x4F, - 0x50, - 0x51, - 0x4B, - 0x4C, - 0x4D, - 0x47, - 0, - 0x48, - 0x49, - 0, - 0, - 0, - 0x3F, - 0x40, - 0x41, - 0x3D, - 0x42, - 0x43, - 0, - 0x57, - 0, - 0x137, - 0, - 0x46, - 0, - 0x44, - 0x15D, - 0x58, - 0, - 0, // Pause/Break key. - 0x152, - 0x147, - 0x149, - 0x153, - 0x3E, - 0x14F, - 0x3C, - 0x151, - 0x3B, - 0x14B, - 0x14D, - 0x150, - 0x148, - 0, -}; -#endif - #ifdef __HAIKU__ static std::unordered_map be_to_xt = { {0x01, 0x01 }, @@ -1155,7 +1023,7 @@ x11_keycode_to_keysym(uint32_t keycode) #if defined(Q_OS_WINDOWS) finalkeycode = (keycode & 0xFFFF); #elif defined(Q_OS_MACOS) - finalkeycode = darwin_to_xt[keycode]; + finalkeycode = (keycode < 127) ? cocoa_keycodes[keycode] : 0; #elif defined(__HAIKU__) finalkeycode = be_to_xt[keycode]; #else @@ -1170,8 +1038,10 @@ x11_keycode_to_keysym(uint32_t keycode) finalkeycode = 0; # endif #endif - /* Special case for Ctrl+Pause. */ - if ((finalkeycode == 0x145) && (keyboard_recv(0x1d) || keyboard_recv(0x11d))) + /* Special case for Alt+Print Screen and Ctrl+Pause. */ + if ((finalkeycode == 0x137) && (keyboard_recv(0x38) || keyboard_recv(0x138))) + finalkeycode = 0x54; + else if ((finalkeycode == 0x145) && (keyboard_recv(0x1d) || keyboard_recv(0x11d))) finalkeycode = 0x146; if (rctrl_is_lalt && finalkeycode == 0x11D) @@ -1382,31 +1252,20 @@ void MainWindow::keyPressEvent(QKeyEvent *event) { if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) { - // Windows keys in Qt have one-to-one mapping. - if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) { - if ((keyboard_recv(0x1D) || keyboard_recv(0x11D))) { - keyboard_input(1, 0x46); - } else { - keyboard_input(0, 0xE1); - keyboard_input(0, 0x1D); - keyboard_input(0, 0x45); - keyboard_input(0, 0xE1); - keyboard_input(1, 0x1D); - keyboard_input(1, 0x45); - } - } else { #ifdef Q_OS_MACOS - processMacKeyboardInput(true, event); + processMacKeyboardInput(true, event); #else - auto scan = x11_keycode_to_keysym(event->nativeScanCode()); - if (scan == 0x145) { - /* Special case for Pause. */ - keyboard_input(1, scan & 0xff00); - scan &= 0x00ff; - } - keyboard_input(1, scan); -#endif + auto scan = x11_keycode_to_keysym(event->nativeScanCode()); + if (scan == 0x137) { + /* Special case for Print Screen. */ + keyboard_input(1, 0x12a); + } else if (scan == 0x145) { + /* Special case for Pause. */ + keyboard_input(1, 0xe11d); + scan &= 0x00ff; } + keyboard_input(1, scan); +#endif } if ((video_fullscreen > 0) && keyboard_isfsexit()) { @@ -1454,9 +1313,13 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) processMacKeyboardInput(false, event); #else auto scan = x11_keycode_to_keysym(event->nativeScanCode()); - if (scan == 0x145) { + if (scan == 0x137) { + /* Special case for Print Screen. */ + keyboard_input(0, scan); + scan = 0x12a; + } else if (scan == 0x145) { /* Special case for Pause. */ - keyboard_input(0, scan & 0xff00); + keyboard_input(0, 0xe11d); scan &= 0x00ff; } keyboard_input(0, scan);