Migrate Xkb::toQtKey away from KKeyServer

Summary:
Turn Xkb into a QObject

Reduced dependencies on other classes and allows to emit signal directly
instead of emitting a signal on another class.

Dependency inject KWayland::Server::SeatInterface into Xkb

No need to depend on WaylandServer from within Xkb.

[autotests] Add test case for Xkb::toQtKey

Tests all key codes KKeyServer is able to map to Qt.

Migrate Xkb::toQtKey away from KKeyServer

The regression in kwindowsystem in
32526718eae99ccb594360627586eebdf793372b showed once more that it's time
to migrate the xkb keysym to Qt::Key mapping away from KKeyServer. The
main problem with KKeyServer is that it's made for X11 and we don't have
X11 here. This causes warnings printed at runtime and the code only
works by accident at all because KKeyServer fails to initialise
modifiers. That is normally KKeyServer would include the modifiers, but
that is nothing we are interested in for mapping xkb keysyms to Qt::Key.

So to address this, KWin now implements the mapping itself. It's based
on the implementation in KKeyServer, but also improved by providing
faster xkb to Qt conversion (which matters for KWin more than the other
direction).

Long term plan is to extend this so that also on X11 it can be used.
Then it should be split out and be used in KKeyServer as a replacement
for the current implementation which could support both X11 and Wayland.

Test Plan:
New test case added which covers all keysyms supported by
existing KKeyserver mapping

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7336
icc-effect-5.14.5
Martin Flöser 2017-08-15 21:17:13 +02:00
parent 801fe41013
commit 5d101ce297
3 changed files with 280 additions and 37 deletions

View File

@ -484,36 +484,6 @@ void XkbTest::testToQtKey()
{
Xkb xkb;
QFETCH(xkb_keysym_t, keySym);
QEXPECT_FAIL("e0", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e1", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e2", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e3", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e4", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e5", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e6", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e7", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e8", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("e9", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("ea", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("eb", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("ec", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("ed", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("ee", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("ef", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f0", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f1", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f2", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f3", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f4", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f5", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f6", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f8", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("f9", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("fa", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("fb", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("fc", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("fd", "Incorrectly mapped by KKeyServer", Continue);
QEXPECT_FAIL("fe", "Incorrectly mapped by KKeyServer", Continue);
QTEST(xkb.toQtKey(keySym), "qt");
}

View File

@ -18,10 +18,10 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "xkb.h"
#include "xkb_qt_mapping.h"
#include "utils.h"
// frameworks
#include <KConfigGroup>
#include <KKeyServer>
// KWayland
#include <KWayland/Server/seat_interface.h>
// Qt
@ -442,12 +442,7 @@ QString Xkb::toString(xkb_keysym_t keysym)
Qt::Key Xkb::toQtKey(xkb_keysym_t keysym) const
{
int key = Qt::Key_unknown;
KKeyServer::symXToKeyQt(keysym, &key);
if (key & Qt::KeyboardModifierMask) {
key &= ~Qt::KeyboardModifierMask;
}
return static_cast<Qt::Key>(key);
return xkbToQtKey(keysym);
}
bool Xkb::shouldKeyRepeat(quint32 key) const

278
xkb_qt_mapping.h Normal file
View File

@ -0,0 +1,278 @@
/********************************************************************
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;
}
}
#endif