Krita Source Code Documentation
Loading...
Searching...
No Matches
KisExtendedModifiersMapperX11.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
10#include <QX11Info>
11#else
12#include <QGuiApplication>
13#endif
14
15#include <X11/X.h>
16#include <X11/XKBlib.h>
17#include <X11/Xlib.h>
18#include <X11/keysym.h>
20
21struct KeyMapping {
22 KeySym x11KeySym {0};
23 Qt::Key qtKey {Qt::Key_unknown};
24};
25
26static const KeyMapping s_mapping[] = {
27 {XK_Shift_L, Qt::Key_Shift},
28 {XK_Shift_R, Qt::Key_Shift},
29
30 {XK_Control_L, Qt::Key_Control},
31 {XK_Control_R, Qt::Key_Control},
32
33 {XK_Meta_L, Qt::Key_Alt},
34 {XK_Meta_R, Qt::Key_Alt},
35 {XK_Mode_switch, Qt::Key_AltGr},
36 {XK_ISO_Level3_Shift, Qt::Key_AltGr},
37
38 {XK_Alt_L, Qt::Key_Alt},
39 {XK_Alt_R, Qt::Key_Alt},
40
41 {XK_Super_L, Qt::Key_Meta},
42 {XK_Super_R, Qt::Key_Meta},
43
44 {XK_Hyper_L, Qt::Key_Hyper_L},
45 {XK_Hyper_R, Qt::Key_Hyper_R},
46
47 {XK_space, Qt::Key_Space},
48
49 {XK_0, Qt::Key_0},
50 {XK_1, Qt::Key_1},
51 {XK_2, Qt::Key_2},
52 {XK_3, Qt::Key_3},
53 {XK_4, Qt::Key_4},
54 {XK_5, Qt::Key_5},
55 {XK_6, Qt::Key_6},
56 {XK_7, Qt::Key_7},
57 {XK_8, Qt::Key_8},
58 {XK_9, Qt::Key_9},
59
60 {XK_a, Qt::Key_A},
61 {XK_b, Qt::Key_B},
62 {XK_c, Qt::Key_C},
63 {XK_d, Qt::Key_D},
64 {XK_e, Qt::Key_E},
65 {XK_f, Qt::Key_F},
66 {XK_g, Qt::Key_G},
67 {XK_h, Qt::Key_H},
68 {XK_i, Qt::Key_I},
69 {XK_j, Qt::Key_J},
70 {XK_k, Qt::Key_K},
71 {XK_l, Qt::Key_L},
72 {XK_m, Qt::Key_M},
73 {XK_n, Qt::Key_N},
74 {XK_o, Qt::Key_O},
75 {XK_p, Qt::Key_P},
76 {XK_q, Qt::Key_Q},
77 {XK_r, Qt::Key_R},
78 {XK_s, Qt::Key_S},
79 {XK_t, Qt::Key_T},
80 {XK_u, Qt::Key_U},
81 {XK_v, Qt::Key_V},
82 {XK_w, Qt::Key_W},
83 {XK_x, Qt::Key_X},
84 {XK_y, Qt::Key_Y},
85 {XK_z, Qt::Key_Z},
86
87 {XK_A, Qt::Key_A},
88 {XK_B, Qt::Key_B},
89 {XK_C, Qt::Key_C},
90 {XK_D, Qt::Key_D},
91 {XK_E, Qt::Key_E},
92 {XK_F, Qt::Key_F},
93 {XK_G, Qt::Key_G},
94 {XK_H, Qt::Key_H},
95 {XK_I, Qt::Key_I},
96 {XK_J, Qt::Key_J},
97 {XK_K, Qt::Key_K},
98 {XK_L, Qt::Key_L},
99 {XK_M, Qt::Key_M},
100 {XK_N, Qt::Key_N},
101 {XK_O, Qt::Key_O},
102 {XK_P, Qt::Key_P},
103 {XK_Q, Qt::Key_Q},
104 {XK_R, Qt::Key_R},
105 {XK_S, Qt::Key_S},
106 {XK_T, Qt::Key_T},
107 {XK_U, Qt::Key_U},
108 {XK_V, Qt::Key_V},
109 {XK_W, Qt::Key_W},
110 {XK_X, Qt::Key_X},
111 {XK_Y, Qt::Key_Y},
112 {XK_Z, Qt::Key_Z}
113};
114
119
121
123{
125
126 char keysState[32];
127 int minKeyCode = 0;
128 int maxKeyCode = 0;
129
130#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
131 XDisplayKeycodes(QX11Info::display(), &minKeyCode, &maxKeyCode);
132 XQueryKeymap(QX11Info::display(), keysState);
133#else
134 XDisplayKeycodes(qGuiApp->nativeInterface<QNativeInterface::QX11Application>()->display(),
135 &minKeyCode,
136 &maxKeyCode);
137 XQueryKeymap(qGuiApp->nativeInterface<QNativeInterface::QX11Application>()->display(), keysState);
138#endif
139
140
141 auto checkKeyCodePressedX11 = [&keysState] (KeyCode key) -> bool {
142 int byte = key / 8;
143 char mask = 1 << (key % 8);
144 return keysState[byte] & mask;
145 };
146
147 for (int keyCode = minKeyCode; keyCode <= maxKeyCode; keyCode++) {
148 if (checkKeyCodePressedX11(keyCode)) {
149#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
150 KeySym sym = XkbKeycodeToKeysym(QX11Info::display(),
151 keyCode,
152#else
153 KeySym sym = XkbKeycodeToKeysym(qGuiApp->nativeInterface<QNativeInterface::QX11Application>()->display(),
154 keyCode,
155#endif
156 0,
157 0);
158 for (size_t i = 0; i < sizeof(s_mapping) / sizeof(s_mapping[0]); i++) {
159 const KeyMapping &map = s_mapping[i];
160 if (map.x11KeySym == sym) {
161 modifiers << map.qtKey;
162 break;
163 }
164 }
165 }
166 }
167
168 // in X11 some keys may have multiple keysyms,
169 // (Alt Key == XK_Meta_{L,R}, XK_Meta_{L,R})
171 return modifiers;
172}
173
static const KeyMapping s_mapping[]
KisExtendedModifiersMapperX11(QObject *parent, const QVariantList &)
ExtendedModifiers queryExtendedModifiers() override
~KisExtendedModifiersMapperX11() override
void makeContainerUnique(C &container)