a17c85a9ea
Summary: This is needed in virtual keyboard and also used KKeyServer so far. With this change it is moved to new API provided in Xkb. The new translation map is now also used for the direction from Qt::Key + Qt::KeyboardModifier to xkb_keysym_t. New implementation is supported by a new test case covering the same combinations as in the existing direction. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D7356
317 lines
13 KiB
C++
317 lines
13 KiB
C++
/********************************************************************
|
|
KWin - the KDE window manager
|
|
This file is part of the KDE project.
|
|
|
|
Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*********************************************************************/
|
|
#ifndef KWIN_XKB_QT_MAPPING_H
|
|
#define KWIN_XKB_QT_MAPPING_H
|
|
|
|
#include <QtGlobal>
|
|
|
|
#include <map>
|
|
#include <xkbcommon/xkbcommon-keysyms.h>
|
|
|
|
namespace KWin
|
|
{
|
|
|
|
// based on mapping in kwindowsystem/src/platforms/xcb/kkeyserver.cpp
|
|
// adjusted to XKB
|
|
static const std::map<xkb_keysym_t, Qt::Key> s_mapping{
|
|
{ XKB_KEY_Escape, Qt::Key_Escape },
|
|
{ XKB_KEY_Tab, Qt::Key_Tab },
|
|
{ XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab },
|
|
{ XKB_KEY_BackSpace, Qt::Key_Backspace },
|
|
{ XKB_KEY_Return, Qt::Key_Return },
|
|
{ XKB_KEY_Insert, Qt::Key_Insert },
|
|
{ XKB_KEY_Delete, Qt::Key_Delete },
|
|
{ XKB_KEY_Pause, Qt::Key_Pause },
|
|
{ XKB_KEY_Print, Qt::Key_Print },
|
|
{ XKB_KEY_Sys_Req, Qt::Key_SysReq },
|
|
{ XKB_KEY_Home, Qt::Key_Home },
|
|
{ XKB_KEY_End, Qt::Key_End },
|
|
{ XKB_KEY_Left, Qt::Key_Left },
|
|
{ XKB_KEY_Up, Qt::Key_Up },
|
|
{ XKB_KEY_Right, Qt::Key_Right },
|
|
{ XKB_KEY_Down, Qt::Key_Down },
|
|
{ XKB_KEY_Prior, Qt::Key_PageUp },
|
|
{ XKB_KEY_Next, Qt::Key_PageDown },
|
|
{ XKB_KEY_Caps_Lock, Qt::Key_CapsLock },
|
|
{ XKB_KEY_Num_Lock, Qt::Key_NumLock },
|
|
{ XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock },
|
|
{ XKB_KEY_F1, Qt::Key_F1 },
|
|
{ XKB_KEY_F2, Qt::Key_F2 },
|
|
{ XKB_KEY_F3, Qt::Key_F3 },
|
|
{ XKB_KEY_F4, Qt::Key_F4 },
|
|
{ XKB_KEY_F5, Qt::Key_F5 },
|
|
{ XKB_KEY_F6, Qt::Key_F6 },
|
|
{ XKB_KEY_F7, Qt::Key_F7 },
|
|
{ XKB_KEY_F8, Qt::Key_F8 },
|
|
{ XKB_KEY_F9, Qt::Key_F9 },
|
|
{ XKB_KEY_F10, Qt::Key_F10 },
|
|
{ XKB_KEY_F11, Qt::Key_F11 },
|
|
{ XKB_KEY_F12, Qt::Key_F12 },
|
|
{ XKB_KEY_F13, Qt::Key_F13 },
|
|
{ XKB_KEY_F14, Qt::Key_F14 },
|
|
{ XKB_KEY_F15, Qt::Key_F15 },
|
|
{ XKB_KEY_F16, Qt::Key_F16 },
|
|
{ XKB_KEY_F17, Qt::Key_F17 },
|
|
{ XKB_KEY_F18, Qt::Key_F18 },
|
|
{ XKB_KEY_F19, Qt::Key_F19 },
|
|
{ XKB_KEY_F20, Qt::Key_F20 },
|
|
{ XKB_KEY_F21, Qt::Key_F21 },
|
|
{ XKB_KEY_F22, Qt::Key_F22 },
|
|
{ XKB_KEY_F23, Qt::Key_F23 },
|
|
{ XKB_KEY_F24, Qt::Key_F24 },
|
|
{ XKB_KEY_F25, Qt::Key_F25 },
|
|
{ XKB_KEY_F26, Qt::Key_F26 },
|
|
{ XKB_KEY_F27, Qt::Key_F27 },
|
|
{ XKB_KEY_F28, Qt::Key_F28 },
|
|
{ XKB_KEY_F29, Qt::Key_F29 },
|
|
{ XKB_KEY_F30, Qt::Key_F30 },
|
|
{ XKB_KEY_F31, Qt::Key_F31 },
|
|
{ XKB_KEY_F32, Qt::Key_F32 },
|
|
{ XKB_KEY_F33, Qt::Key_F33 },
|
|
{ XKB_KEY_F34, Qt::Key_F34 },
|
|
{ XKB_KEY_F35, Qt::Key_F35 },
|
|
{ XKB_KEY_Super_L, Qt::Key_Super_L },
|
|
{ XKB_KEY_Super_R, Qt::Key_Super_R },
|
|
{ XKB_KEY_Menu, Qt::Key_Menu },
|
|
{ XKB_KEY_Hyper_L, Qt::Key_Hyper_L },
|
|
{ XKB_KEY_Hyper_R, Qt::Key_Hyper_R },
|
|
{ XKB_KEY_Help, Qt::Key_Help },
|
|
{ XKB_KEY_KP_Space, Qt::Key_Space },
|
|
{ XKB_KEY_KP_Tab, Qt::Key_Tab },
|
|
{ XKB_KEY_KP_Enter, Qt::Key_Enter },
|
|
{ XKB_KEY_KP_Home, Qt::Key_Home },
|
|
{ XKB_KEY_KP_Left, Qt::Key_Left },
|
|
{ XKB_KEY_KP_Up, Qt::Key_Up },
|
|
{ XKB_KEY_KP_Right, Qt::Key_Right },
|
|
{ XKB_KEY_KP_Down, Qt::Key_Down },
|
|
{ XKB_KEY_KP_Prior, Qt::Key_PageUp },
|
|
{ XKB_KEY_KP_Next, Qt::Key_PageDown },
|
|
{ XKB_KEY_KP_End, Qt::Key_End },
|
|
{ XKB_KEY_KP_Begin, Qt::Key_Clear },
|
|
{ XKB_KEY_KP_Insert, Qt::Key_Insert },
|
|
{ XKB_KEY_KP_Delete, Qt::Key_Delete },
|
|
{ XKB_KEY_KP_Equal, Qt::Key_Equal },
|
|
{ XKB_KEY_KP_Multiply, Qt::Key_Asterisk },
|
|
{ XKB_KEY_KP_Add, Qt::Key_Plus },
|
|
{ XKB_KEY_KP_Separator, Qt::Key_Comma },
|
|
{ XKB_KEY_KP_Subtract, Qt::Key_Minus },
|
|
{ XKB_KEY_KP_Decimal, Qt::Key_Period },
|
|
{ XKB_KEY_KP_Divide, Qt::Key_Slash },
|
|
{ XKB_KEY_XF86Back, Qt::Key_Back },
|
|
{ XKB_KEY_XF86Forward, Qt::Key_Forward },
|
|
{ XKB_KEY_XF86Stop, Qt::Key_Stop },
|
|
{ XKB_KEY_XF86Refresh, Qt::Key_Refresh },
|
|
{ XKB_KEY_XF86Favorites, Qt::Key_Favorites },
|
|
{ XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia },
|
|
{ XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl },
|
|
{ XKB_KEY_XF86HomePage, Qt::Key_HomePage },
|
|
{ XKB_KEY_XF86Search, Qt::Key_Search },
|
|
{ XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown },
|
|
{ XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute },
|
|
{ XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp },
|
|
{ XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay },
|
|
{ XKB_KEY_XF86AudioStop, Qt::Key_MediaStop },
|
|
{ XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious },
|
|
{ XKB_KEY_XF86AudioNext, Qt::Key_MediaNext },
|
|
{ XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord },
|
|
{ XKB_KEY_XF86Mail, Qt::Key_LaunchMail },
|
|
{ XKB_KEY_XF86MyComputer, Qt::Key_Launch0 },
|
|
{ XKB_KEY_XF86Calculator, Qt::Key_Launch1 },
|
|
{ XKB_KEY_XF86Memo, Qt::Key_Memo },
|
|
{ XKB_KEY_XF86ToDoList, Qt::Key_ToDoList },
|
|
{ XKB_KEY_XF86Calendar, Qt::Key_Calendar },
|
|
{ XKB_KEY_XF86PowerDown, Qt::Key_PowerDown },
|
|
{ XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust },
|
|
{ XKB_KEY_XF86Standby, Qt::Key_Standby },
|
|
{ XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp },
|
|
{ XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown },
|
|
{ XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff },
|
|
{ XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp },
|
|
{ XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown },
|
|
{ XKB_KEY_XF86PowerOff, Qt::Key_PowerOff },
|
|
{ XKB_KEY_XF86WakeUp, Qt::Key_WakeUp },
|
|
{ XKB_KEY_XF86Eject, Qt::Key_Eject },
|
|
{ XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver },
|
|
{ XKB_KEY_XF86WWW, Qt::Key_WWW },
|
|
{ XKB_KEY_XF86Sleep, Qt::Key_Sleep },
|
|
{ XKB_KEY_XF86LightBulb, Qt::Key_LightBulb },
|
|
{ XKB_KEY_XF86Shop, Qt::Key_Shop },
|
|
{ XKB_KEY_XF86History, Qt::Key_History },
|
|
{ XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite },
|
|
{ XKB_KEY_XF86HotLinks, Qt::Key_HotLinks },
|
|
{ XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust },
|
|
{ XKB_KEY_XF86Finance, Qt::Key_Finance },
|
|
{ XKB_KEY_XF86Community, Qt::Key_Community },
|
|
{ XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind },
|
|
{ XKB_KEY_XF86BackForward, Qt::Key_BackForward },
|
|
{ XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft },
|
|
{ XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight },
|
|
{ XKB_KEY_XF86Book, Qt::Key_Book },
|
|
{ XKB_KEY_XF86CD, Qt::Key_CD },
|
|
{ XKB_KEY_XF86Calculater, Qt::Key_Calculator },
|
|
{ XKB_KEY_XF86Clear, Qt::Key_Clear },
|
|
{ XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab },
|
|
{ XKB_KEY_XF86Close, Qt::Key_Close },
|
|
{ XKB_KEY_XF86Copy, Qt::Key_Copy },
|
|
{ XKB_KEY_XF86Cut, Qt::Key_Cut },
|
|
{ XKB_KEY_XF86Display, Qt::Key_Display },
|
|
{ XKB_KEY_XF86DOS, Qt::Key_DOS },
|
|
{ XKB_KEY_XF86Documents, Qt::Key_Documents },
|
|
{ XKB_KEY_XF86Excel, Qt::Key_Excel },
|
|
{ XKB_KEY_XF86Explorer, Qt::Key_Explorer },
|
|
{ XKB_KEY_XF86Game, Qt::Key_Game },
|
|
{ XKB_KEY_XF86Go, Qt::Key_Go },
|
|
{ XKB_KEY_XF86iTouch, Qt::Key_iTouch },
|
|
{ XKB_KEY_XF86LogOff, Qt::Key_LogOff },
|
|
{ XKB_KEY_XF86Market, Qt::Key_Market },
|
|
{ XKB_KEY_XF86Meeting, Qt::Key_Meeting },
|
|
{ XKB_KEY_XF86MenuKB, Qt::Key_MenuKB },
|
|
{ XKB_KEY_XF86MenuPB, Qt::Key_MenuPB },
|
|
{ XKB_KEY_XF86MySites, Qt::Key_MySites },
|
|
{ XKB_KEY_XF86News, Qt::Key_News },
|
|
{ XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome },
|
|
{ XKB_KEY_XF86Option, Qt::Key_Option },
|
|
{ XKB_KEY_XF86Paste, Qt::Key_Paste },
|
|
{ XKB_KEY_XF86Phone, Qt::Key_Phone },
|
|
{ XKB_KEY_XF86Reply, Qt::Key_Reply },
|
|
{ XKB_KEY_XF86Reload, Qt::Key_Reload },
|
|
{ XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows },
|
|
{ XKB_KEY_XF86RotationPB, Qt::Key_RotationPB },
|
|
{ XKB_KEY_XF86RotationKB, Qt::Key_RotationKB },
|
|
{ XKB_KEY_XF86Save, Qt::Key_Save },
|
|
{ XKB_KEY_XF86Send, Qt::Key_Send },
|
|
{ XKB_KEY_XF86Spell, Qt::Key_Spell },
|
|
{ XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen },
|
|
{ XKB_KEY_XF86Support, Qt::Key_Support },
|
|
{ XKB_KEY_XF86TaskPane, Qt::Key_TaskPane },
|
|
{ XKB_KEY_XF86Terminal, Qt::Key_Terminal },
|
|
{ XKB_KEY_XF86Tools, Qt::Key_Tools },
|
|
{ XKB_KEY_XF86Travel, Qt::Key_Travel },
|
|
{ XKB_KEY_XF86Video, Qt::Key_Video },
|
|
{ XKB_KEY_XF86Word, Qt::Key_Word },
|
|
{ XKB_KEY_XF86Xfer, Qt::Key_Xfer },
|
|
{ XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn },
|
|
{ XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut },
|
|
{ XKB_KEY_XF86Away, Qt::Key_Away },
|
|
{ XKB_KEY_XF86Messenger, Qt::Key_Messenger },
|
|
{ XKB_KEY_XF86WebCam, Qt::Key_WebCam },
|
|
{ XKB_KEY_XF86MailForward, Qt::Key_MailForward },
|
|
{ XKB_KEY_XF86Pictures, Qt::Key_Pictures },
|
|
{ XKB_KEY_XF86Music, Qt::Key_Music },
|
|
{ XKB_KEY_XF86Battery, Qt::Key_Battery },
|
|
{ XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth },
|
|
{ XKB_KEY_XF86WLAN, Qt::Key_WLAN },
|
|
{ XKB_KEY_XF86UWB, Qt::Key_UWB },
|
|
{ XKB_KEY_XF86AudioForward, Qt::Key_AudioForward },
|
|
{ XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat },
|
|
{ XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay },
|
|
{ XKB_KEY_XF86Subtitle, Qt::Key_Subtitle },
|
|
{ XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack },
|
|
{ XKB_KEY_XF86Time, Qt::Key_Time },
|
|
{ XKB_KEY_XF86Select, Qt::Key_Select },
|
|
{ XKB_KEY_XF86View, Qt::Key_View },
|
|
{ XKB_KEY_XF86TopMenu, Qt::Key_TopMenu },
|
|
{ XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth },
|
|
{ XKB_KEY_XF86Suspend, Qt::Key_Suspend },
|
|
{ XKB_KEY_XF86Hibernate, Qt::Key_Hibernate },
|
|
{ XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle },
|
|
{ XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn },
|
|
{ XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff },
|
|
{ XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute },
|
|
{ XKB_KEY_XF86Launch0, Qt::Key_Launch2 },
|
|
{ XKB_KEY_XF86Launch1, Qt::Key_Launch3 },
|
|
{ XKB_KEY_XF86Launch2, Qt::Key_Launch4 },
|
|
{ XKB_KEY_XF86Launch3, Qt::Key_Launch5 },
|
|
{ XKB_KEY_XF86Launch4, Qt::Key_Launch6 },
|
|
{ XKB_KEY_XF86Launch5, Qt::Key_Launch7 },
|
|
{ XKB_KEY_XF86Launch6, Qt::Key_Launch8 },
|
|
{ XKB_KEY_XF86Launch7, Qt::Key_Launch9 },
|
|
{ XKB_KEY_XF86Launch8, Qt::Key_LaunchA },
|
|
{ XKB_KEY_XF86Launch9, Qt::Key_LaunchB },
|
|
{ XKB_KEY_XF86LaunchA, Qt::Key_LaunchC },
|
|
{ XKB_KEY_XF86LaunchB, Qt::Key_LaunchD },
|
|
{ XKB_KEY_XF86LaunchC, Qt::Key_LaunchE },
|
|
{ XKB_KEY_XF86LaunchD, Qt::Key_LaunchF }
|
|
};
|
|
|
|
static inline Qt::Key xkbToQtKey(xkb_keysym_t keySym)
|
|
{
|
|
Qt::Key key = Qt::Key_unknown;
|
|
if (keySym >= XKB_KEY_KP_0 && keySym <= XKB_KEY_KP_9) {
|
|
// numeric keypad keys
|
|
key = Qt::Key(int(Qt::Key_0) + int(keySym) - XKB_KEY_KP_0);
|
|
} else if ((keySym >= XKB_KEY_a && keySym <= XKB_KEY_z) ||
|
|
(keySym >= XKB_KEY_agrave && keySym < XKB_KEY_division) ||
|
|
(keySym > XKB_KEY_division && keySym <= XKB_KEY_thorn)) {
|
|
key = Qt::Key(QChar(keySym).toUpper().unicode());
|
|
} else if (keySym < 0x3000) {
|
|
key = Qt::Key(keySym);
|
|
}
|
|
if (key == Qt::Key_unknown) {
|
|
const auto it = s_mapping.find(keySym);
|
|
if (it != s_mapping.end()) {
|
|
key = it->second;
|
|
}
|
|
}
|
|
return key;
|
|
}
|
|
|
|
static inline xkb_keysym_t qtKeyToXkb(Qt::Key qtKey, Qt::KeyboardModifiers modifiers)
|
|
{
|
|
xkb_keysym_t sym = XKB_KEY_NoSymbol;
|
|
if (modifiers.testFlag(Qt::KeypadModifier) && qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9) {
|
|
sym = XKB_KEY_KP_0 + qtKey - Qt::Key_0;
|
|
} else if (qtKey < 0x1000 && !modifiers.testFlag(Qt::KeypadModifier)) {
|
|
QChar character(qtKey);
|
|
if (!modifiers.testFlag(Qt::ShiftModifier)) {
|
|
character = character.toLower();
|
|
}
|
|
sym = character.unicode();
|
|
}
|
|
|
|
if (sym == XKB_KEY_NoSymbol) {
|
|
std::vector<xkb_keysym_t> possibleMatches;
|
|
for (auto pair : s_mapping) {
|
|
if (pair.second == qtKey) {
|
|
possibleMatches.emplace_back(pair.first);
|
|
}
|
|
}
|
|
if (!possibleMatches.empty()) {
|
|
sym = possibleMatches.front();
|
|
for (auto match : possibleMatches) {
|
|
// is the current match better than existing?
|
|
if (modifiers.testFlag(Qt::KeypadModifier)) {
|
|
if (match >= XKB_KEY_KP_Space && match <= XKB_KEY_KP_9) {
|
|
sym = match;
|
|
}
|
|
} else {
|
|
if (sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9) {
|
|
sym = match;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return sym;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|