Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qxkbcommon.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qxkbcommon_p.h"
5
6#include <private/qmakearray_p.h>
7
8#include <QtCore/private/qstringiterator_p.h>
9#include <QtCore/qvarlengtharray.h>
10#include <QtCore/QMetaMethod>
11
12#include <QtGui/QKeyEvent>
13#include <QtGui/private/qguiapplication_p.h>
14
15#include <qpa/qplatforminputcontext.h>
16#include <qpa/qplatformintegration.h>
17
19
20static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
21 xkb_state *state, xkb_keycode_t code,
22 bool superAsMeta, bool hyperAsMeta);
23
24typedef struct xkb2qt
25{
26 unsigned int xkb;
27 unsigned int qt;
28
29 constexpr bool operator <=(const xkb2qt &that) const noexcept
30 {
31 return xkb <= that.xkb;
32 }
33
34 constexpr bool operator <(const xkb2qt &that) const noexcept
35 {
36 return xkb < that.xkb;
37 }
39
40template<std::size_t Xkb, std::size_t Qt>
41struct Xkb2Qt
42{
43 using Type = xkb2qt_t;
44 static constexpr Type data() noexcept { return Type{Xkb, Qt}; }
45};
46
47static constexpr const auto KeyTbl = qMakeArray(
49 // misc keys
50
51 Xkb2Qt<XKB_KEY_Escape, Qt::Key_Escape>,
52 Xkb2Qt<XKB_KEY_Tab, Qt::Key_Tab>,
53 Xkb2Qt<XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab>,
54 Xkb2Qt<XKB_KEY_BackSpace, Qt::Key_Backspace>,
55 Xkb2Qt<XKB_KEY_Return, Qt::Key_Return>,
56 Xkb2Qt<XKB_KEY_Insert, Qt::Key_Insert>,
57 Xkb2Qt<XKB_KEY_Delete, Qt::Key_Delete>,
58 Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
59 Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
60 Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
61 Xkb2Qt<XKB_KEY_Sys_Req, Qt::Key_SysReq>,
62 Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
63 Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
64
65 // cursor movement
66
67 Xkb2Qt<XKB_KEY_Home, Qt::Key_Home>,
68 Xkb2Qt<XKB_KEY_End, Qt::Key_End>,
69 Xkb2Qt<XKB_KEY_Left, Qt::Key_Left>,
70 Xkb2Qt<XKB_KEY_Up, Qt::Key_Up>,
71 Xkb2Qt<XKB_KEY_Right, Qt::Key_Right>,
72 Xkb2Qt<XKB_KEY_Down, Qt::Key_Down>,
73 Xkb2Qt<XKB_KEY_Prior, Qt::Key_PageUp>,
74 Xkb2Qt<XKB_KEY_Next, Qt::Key_PageDown>,
75
76 // modifiers
77
78 Xkb2Qt<XKB_KEY_Shift_L, Qt::Key_Shift>,
79 Xkb2Qt<XKB_KEY_Shift_R, Qt::Key_Shift>,
80 Xkb2Qt<XKB_KEY_Shift_Lock, Qt::Key_Shift>,
81 Xkb2Qt<XKB_KEY_Control_L, Qt::Key_Control>,
82 Xkb2Qt<XKB_KEY_Control_R, Qt::Key_Control>,
83 Xkb2Qt<XKB_KEY_Meta_L, Qt::Key_Meta>,
84 Xkb2Qt<XKB_KEY_Meta_R, Qt::Key_Meta>,
85 Xkb2Qt<XKB_KEY_Alt_L, Qt::Key_Alt>,
86 Xkb2Qt<XKB_KEY_Alt_R, Qt::Key_Alt>,
87 Xkb2Qt<XKB_KEY_Caps_Lock, Qt::Key_CapsLock>,
88 Xkb2Qt<XKB_KEY_Num_Lock, Qt::Key_NumLock>,
89 Xkb2Qt<XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock>,
90 Xkb2Qt<XKB_KEY_Super_L, Qt::Key_Super_L>,
91 Xkb2Qt<XKB_KEY_Super_R, Qt::Key_Super_R>,
92 Xkb2Qt<XKB_KEY_Menu, Qt::Key_Menu>,
93 Xkb2Qt<XKB_KEY_Hyper_L, Qt::Key_Hyper_L>,
94 Xkb2Qt<XKB_KEY_Hyper_R, Qt::Key_Hyper_R>,
95 Xkb2Qt<XKB_KEY_Help, Qt::Key_Help>,
96 Xkb2Qt<0x1000FF74, Qt::Key_Backtab>, // hardcoded HP backtab
97 Xkb2Qt<0x1005FF10, Qt::Key_F11>, // hardcoded Sun F36 (labeled F11)
98 Xkb2Qt<0x1005FF11, Qt::Key_F12>, // hardcoded Sun F37 (labeled F12)
99
100 // numeric and function keypad keys
101
102 Xkb2Qt<XKB_KEY_KP_Space, Qt::Key_Space>,
103 Xkb2Qt<XKB_KEY_KP_Tab, Qt::Key_Tab>,
104 Xkb2Qt<XKB_KEY_KP_Enter, Qt::Key_Enter>,
105 Xkb2Qt<XKB_KEY_KP_Home, Qt::Key_Home>,
106 Xkb2Qt<XKB_KEY_KP_Left, Qt::Key_Left>,
107 Xkb2Qt<XKB_KEY_KP_Up, Qt::Key_Up>,
108 Xkb2Qt<XKB_KEY_KP_Right, Qt::Key_Right>,
109 Xkb2Qt<XKB_KEY_KP_Down, Qt::Key_Down>,
110 Xkb2Qt<XKB_KEY_KP_Prior, Qt::Key_PageUp>,
111 Xkb2Qt<XKB_KEY_KP_Next, Qt::Key_PageDown>,
112 Xkb2Qt<XKB_KEY_KP_End, Qt::Key_End>,
113 Xkb2Qt<XKB_KEY_KP_Begin, Qt::Key_Clear>,
114 Xkb2Qt<XKB_KEY_KP_Insert, Qt::Key_Insert>,
115 Xkb2Qt<XKB_KEY_KP_Delete, Qt::Key_Delete>,
116 Xkb2Qt<XKB_KEY_KP_Equal, Qt::Key_Equal>,
117 Xkb2Qt<XKB_KEY_KP_Multiply, Qt::Key_Asterisk>,
118 Xkb2Qt<XKB_KEY_KP_Add, Qt::Key_Plus>,
119 Xkb2Qt<XKB_KEY_KP_Separator, Qt::Key_Comma>,
120 Xkb2Qt<XKB_KEY_KP_Subtract, Qt::Key_Minus>,
121 Xkb2Qt<XKB_KEY_KP_Decimal, Qt::Key_Period>,
122 Xkb2Qt<XKB_KEY_KP_Divide, Qt::Key_Slash>,
123
124 // special non-XF86 function keys
125
126 Xkb2Qt<XKB_KEY_Undo, Qt::Key_Undo>,
127 Xkb2Qt<XKB_KEY_Redo, Qt::Key_Redo>,
128 Xkb2Qt<XKB_KEY_Find, Qt::Key_Find>,
129 Xkb2Qt<XKB_KEY_Cancel, Qt::Key_Cancel>,
130
131 // International input method support keys
132
133 // International & multi-key character composition
134 Xkb2Qt<XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr>,
135 Xkb2Qt<XKB_KEY_Multi_key, Qt::Key_Multi_key>,
136 Xkb2Qt<XKB_KEY_Codeinput, Qt::Key_Codeinput>,
137 Xkb2Qt<XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate>,
138 Xkb2Qt<XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate>,
139 Xkb2Qt<XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate>,
140
141 // Misc Functions
142 Xkb2Qt<XKB_KEY_Mode_switch, Qt::Key_Mode_switch>,
143 Xkb2Qt<XKB_KEY_script_switch, Qt::Key_Mode_switch>,
144
145 // Japanese keyboard support
146 Xkb2Qt<XKB_KEY_Kanji, Qt::Key_Kanji>,
147 Xkb2Qt<XKB_KEY_Muhenkan, Qt::Key_Muhenkan>,
148 //Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan_Mode>,
149 Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan>,
150 Xkb2Qt<XKB_KEY_Henkan, Qt::Key_Henkan>,
151 Xkb2Qt<XKB_KEY_Romaji, Qt::Key_Romaji>,
152 Xkb2Qt<XKB_KEY_Hiragana, Qt::Key_Hiragana>,
153 Xkb2Qt<XKB_KEY_Katakana, Qt::Key_Katakana>,
154 Xkb2Qt<XKB_KEY_Hiragana_Katakana, Qt::Key_Hiragana_Katakana>,
155 Xkb2Qt<XKB_KEY_Zenkaku, Qt::Key_Zenkaku>,
156 Xkb2Qt<XKB_KEY_Hankaku, Qt::Key_Hankaku>,
157 Xkb2Qt<XKB_KEY_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku>,
158 Xkb2Qt<XKB_KEY_Touroku, Qt::Key_Touroku>,
159 Xkb2Qt<XKB_KEY_Massyo, Qt::Key_Massyo>,
160 Xkb2Qt<XKB_KEY_Kana_Lock, Qt::Key_Kana_Lock>,
161 Xkb2Qt<XKB_KEY_Kana_Shift, Qt::Key_Kana_Shift>,
162 Xkb2Qt<XKB_KEY_Eisu_Shift, Qt::Key_Eisu_Shift>,
163 Xkb2Qt<XKB_KEY_Eisu_toggle, Qt::Key_Eisu_toggle>,
164 //Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Kanji_Bangou>,
165 //Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_Zen_Koho>,
166 //Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_Mae_Koho>,
167 Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Codeinput>,
168 Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_MultipleCandidate>,
169 Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_PreviousCandidate>,
170
171 // Korean keyboard support
172 Xkb2Qt<XKB_KEY_Hangul, Qt::Key_Hangul>,
173 Xkb2Qt<XKB_KEY_Hangul_Start, Qt::Key_Hangul_Start>,
174 Xkb2Qt<XKB_KEY_Hangul_End, Qt::Key_Hangul_End>,
175 Xkb2Qt<XKB_KEY_Hangul_Hanja, Qt::Key_Hangul_Hanja>,
176 Xkb2Qt<XKB_KEY_Hangul_Jamo, Qt::Key_Hangul_Jamo>,
177 Xkb2Qt<XKB_KEY_Hangul_Romaja, Qt::Key_Hangul_Romaja>,
178 //Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Hangul_Codeinput>,
179 Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Codeinput>,
180 Xkb2Qt<XKB_KEY_Hangul_Jeonja, Qt::Key_Hangul_Jeonja>,
181 Xkb2Qt<XKB_KEY_Hangul_Banja, Qt::Key_Hangul_Banja>,
182 Xkb2Qt<XKB_KEY_Hangul_PreHanja, Qt::Key_Hangul_PreHanja>,
183 Xkb2Qt<XKB_KEY_Hangul_PostHanja, Qt::Key_Hangul_PostHanja>,
184 //Xkb2Qt<XKB_KEY_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate>,
185 //Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate>,
186 //Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate>,
187 Xkb2Qt<XKB_KEY_Hangul_SingleCandidate, Qt::Key_SingleCandidate>,
188 Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate>,
189 Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate>,
190 Xkb2Qt<XKB_KEY_Hangul_Special, Qt::Key_Hangul_Special>,
191 //Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Hangul_switch>,
192 Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Mode_switch>,
193
194 // dead keys
195 Xkb2Qt<XKB_KEY_dead_grave, Qt::Key_Dead_Grave>,
196 Xkb2Qt<XKB_KEY_dead_acute, Qt::Key_Dead_Acute>,
197 Xkb2Qt<XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex>,
198 Xkb2Qt<XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde>,
199 Xkb2Qt<XKB_KEY_dead_macron, Qt::Key_Dead_Macron>,
200 Xkb2Qt<XKB_KEY_dead_breve, Qt::Key_Dead_Breve>,
201 Xkb2Qt<XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot>,
202 Xkb2Qt<XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis>,
203 Xkb2Qt<XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering>,
204 Xkb2Qt<XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute>,
205 Xkb2Qt<XKB_KEY_dead_caron, Qt::Key_Dead_Caron>,
206 Xkb2Qt<XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla>,
207 Xkb2Qt<XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek>,
208 Xkb2Qt<XKB_KEY_dead_iota, Qt::Key_Dead_Iota>,
209 Xkb2Qt<XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound>,
210 Xkb2Qt<XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound>,
211 Xkb2Qt<XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot>,
212 Xkb2Qt<XKB_KEY_dead_hook, Qt::Key_Dead_Hook>,
213 Xkb2Qt<XKB_KEY_dead_horn, Qt::Key_Dead_Horn>,
214 Xkb2Qt<XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke>,
215 Xkb2Qt<XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma>,
216 Xkb2Qt<XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma>,
217 Xkb2Qt<XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave>,
218 Xkb2Qt<XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring>,
219 Xkb2Qt<XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron>,
220 Xkb2Qt<XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex>,
221 Xkb2Qt<XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde>,
222 Xkb2Qt<XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve>,
223 Xkb2Qt<XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis>,
224 Xkb2Qt<XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve>,
225 Xkb2Qt<XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma>,
226 Xkb2Qt<XKB_KEY_dead_currency, Qt::Key_Dead_Currency>,
227 Xkb2Qt<XKB_KEY_dead_a, Qt::Key_Dead_a>,
228 Xkb2Qt<XKB_KEY_dead_A, Qt::Key_Dead_A>,
229 Xkb2Qt<XKB_KEY_dead_e, Qt::Key_Dead_e>,
230 Xkb2Qt<XKB_KEY_dead_E, Qt::Key_Dead_E>,
231 Xkb2Qt<XKB_KEY_dead_i, Qt::Key_Dead_i>,
232 Xkb2Qt<XKB_KEY_dead_I, Qt::Key_Dead_I>,
233 Xkb2Qt<XKB_KEY_dead_o, Qt::Key_Dead_o>,
234 Xkb2Qt<XKB_KEY_dead_O, Qt::Key_Dead_O>,
235 Xkb2Qt<XKB_KEY_dead_u, Qt::Key_Dead_u>,
236 Xkb2Qt<XKB_KEY_dead_U, Qt::Key_Dead_U>,
237 Xkb2Qt<XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa>,
238 Xkb2Qt<XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa>,
239 Xkb2Qt<XKB_KEY_dead_greek, Qt::Key_Dead_Greek>,
240/* The following four XKB_KEY_dead keys got removed in libxkbcommon 1.6.0
241 The define check is kind of version check here. */
242#ifdef XKB_KEY_dead_lowline
243 Xkb2Qt<XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline>,
244 Xkb2Qt<XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline>,
245 Xkb2Qt<XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline>,
246 Xkb2Qt<XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay>,
247#endif
248
249 // Special keys from X.org - This include multimedia keys,
250 // wireless/bluetooth/uwb keys, special launcher keys, etc.
251 Xkb2Qt<XKB_KEY_XF86Back, Qt::Key_Back>,
252 Xkb2Qt<XKB_KEY_XF86Forward, Qt::Key_Forward>,
253 Xkb2Qt<XKB_KEY_XF86Stop, Qt::Key_Stop>,
254 Xkb2Qt<XKB_KEY_XF86Refresh, Qt::Key_Refresh>,
255 Xkb2Qt<XKB_KEY_XF86Favorites, Qt::Key_Favorites>,
256 Xkb2Qt<XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia>,
257 Xkb2Qt<XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl>,
258 Xkb2Qt<XKB_KEY_XF86HomePage, Qt::Key_HomePage>,
259 Xkb2Qt<XKB_KEY_XF86Search, Qt::Key_Search>,
260 Xkb2Qt<XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown>,
261 Xkb2Qt<XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute>,
262 Xkb2Qt<XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp>,
263 Xkb2Qt<XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay>,
264 Xkb2Qt<XKB_KEY_XF86AudioStop, Qt::Key_MediaStop>,
265 Xkb2Qt<XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious>,
266 Xkb2Qt<XKB_KEY_XF86AudioNext, Qt::Key_MediaNext>,
267 Xkb2Qt<XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord>,
268 Xkb2Qt<XKB_KEY_XF86AudioPause, Qt::Key_MediaPause>,
269 Xkb2Qt<XKB_KEY_XF86Mail, Qt::Key_LaunchMail>,
270 Xkb2Qt<XKB_KEY_XF86MyComputer, Qt::Key_LaunchMedia>,
271 Xkb2Qt<XKB_KEY_XF86Memo, Qt::Key_Memo>,
272 Xkb2Qt<XKB_KEY_XF86ToDoList, Qt::Key_ToDoList>,
273 Xkb2Qt<XKB_KEY_XF86Calendar, Qt::Key_Calendar>,
274 Xkb2Qt<XKB_KEY_XF86PowerDown, Qt::Key_PowerDown>,
275 Xkb2Qt<XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust>,
276 Xkb2Qt<XKB_KEY_XF86Standby, Qt::Key_Standby>,
277 Xkb2Qt<XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp>,
278 Xkb2Qt<XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown>,
279 Xkb2Qt<XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff>,
280 Xkb2Qt<XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp>,
281 Xkb2Qt<XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown>,
282 Xkb2Qt<XKB_KEY_XF86PowerOff, Qt::Key_PowerOff>,
283 Xkb2Qt<XKB_KEY_XF86WakeUp, Qt::Key_WakeUp>,
284 Xkb2Qt<XKB_KEY_XF86Eject, Qt::Key_Eject>,
285 Xkb2Qt<XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver>,
286 Xkb2Qt<XKB_KEY_XF86WWW, Qt::Key_WWW>,
287 Xkb2Qt<XKB_KEY_XF86Sleep, Qt::Key_Sleep>,
288 Xkb2Qt<XKB_KEY_XF86LightBulb, Qt::Key_LightBulb>,
289 Xkb2Qt<XKB_KEY_XF86Shop, Qt::Key_Shop>,
290 Xkb2Qt<XKB_KEY_XF86History, Qt::Key_History>,
291 Xkb2Qt<XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite>,
292 Xkb2Qt<XKB_KEY_XF86HotLinks, Qt::Key_HotLinks>,
293 Xkb2Qt<XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust>,
294 Xkb2Qt<XKB_KEY_XF86Finance, Qt::Key_Finance>,
295 Xkb2Qt<XKB_KEY_XF86Community, Qt::Key_Community>,
296 Xkb2Qt<XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind>,
297 Xkb2Qt<XKB_KEY_XF86BackForward, Qt::Key_BackForward>,
298 Xkb2Qt<XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft>,
299 Xkb2Qt<XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight>,
300 Xkb2Qt<XKB_KEY_XF86Book, Qt::Key_Book>,
301 Xkb2Qt<XKB_KEY_XF86CD, Qt::Key_CD>,
302 Xkb2Qt<XKB_KEY_XF86Calculater, Qt::Key_Calculator>,
303 Xkb2Qt<XKB_KEY_XF86Calculator, Qt::Key_Calculator>,
304 Xkb2Qt<XKB_KEY_XF86Clear, Qt::Key_Clear>,
305 Xkb2Qt<XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab>,
306 Xkb2Qt<XKB_KEY_XF86Close, Qt::Key_Close>,
307 Xkb2Qt<XKB_KEY_XF86Copy, Qt::Key_Copy>,
308 Xkb2Qt<XKB_KEY_XF86Cut, Qt::Key_Cut>,
309 Xkb2Qt<XKB_KEY_XF86Display, Qt::Key_Display>,
310 Xkb2Qt<XKB_KEY_XF86DOS, Qt::Key_DOS>,
311 Xkb2Qt<XKB_KEY_XF86Documents, Qt::Key_Documents>,
312 Xkb2Qt<XKB_KEY_XF86Excel, Qt::Key_Excel>,
313 Xkb2Qt<XKB_KEY_XF86Explorer, Qt::Key_Explorer>,
314 Xkb2Qt<XKB_KEY_XF86Game, Qt::Key_Game>,
315 Xkb2Qt<XKB_KEY_XF86Go, Qt::Key_Go>,
316 Xkb2Qt<XKB_KEY_XF86iTouch, Qt::Key_iTouch>,
317 Xkb2Qt<XKB_KEY_XF86LogOff, Qt::Key_LogOff>,
318 Xkb2Qt<XKB_KEY_XF86Market, Qt::Key_Market>,
319 Xkb2Qt<XKB_KEY_XF86Meeting, Qt::Key_Meeting>,
320 Xkb2Qt<XKB_KEY_XF86MenuKB, Qt::Key_MenuKB>,
321 Xkb2Qt<XKB_KEY_XF86MenuPB, Qt::Key_MenuPB>,
322 Xkb2Qt<XKB_KEY_XF86MySites, Qt::Key_MySites>,
323 Xkb2Qt<XKB_KEY_XF86New, Qt::Key_New>,
324 Xkb2Qt<XKB_KEY_XF86News, Qt::Key_News>,
325 Xkb2Qt<XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome>,
326 Xkb2Qt<XKB_KEY_XF86Open, Qt::Key_Open>,
327 Xkb2Qt<XKB_KEY_XF86Option, Qt::Key_Option>,
328 Xkb2Qt<XKB_KEY_XF86Paste, Qt::Key_Paste>,
329 Xkb2Qt<XKB_KEY_XF86Phone, Qt::Key_Phone>,
330 Xkb2Qt<XKB_KEY_XF86Reply, Qt::Key_Reply>,
331 Xkb2Qt<XKB_KEY_XF86Reload, Qt::Key_Reload>,
332 Xkb2Qt<XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows>,
333 Xkb2Qt<XKB_KEY_XF86RotationPB, Qt::Key_RotationPB>,
334 Xkb2Qt<XKB_KEY_XF86RotationKB, Qt::Key_RotationKB>,
335 Xkb2Qt<XKB_KEY_XF86Save, Qt::Key_Save>,
336 Xkb2Qt<XKB_KEY_XF86Send, Qt::Key_Send>,
337 Xkb2Qt<XKB_KEY_XF86Spell, Qt::Key_Spell>,
338 Xkb2Qt<XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen>,
339 Xkb2Qt<XKB_KEY_XF86Support, Qt::Key_Support>,
340 Xkb2Qt<XKB_KEY_XF86TaskPane, Qt::Key_TaskPane>,
341 Xkb2Qt<XKB_KEY_XF86Terminal, Qt::Key_Terminal>,
342 Xkb2Qt<XKB_KEY_XF86Tools, Qt::Key_Tools>,
343 Xkb2Qt<XKB_KEY_XF86Travel, Qt::Key_Travel>,
344 Xkb2Qt<XKB_KEY_XF86Video, Qt::Key_Video>,
345 Xkb2Qt<XKB_KEY_XF86Word, Qt::Key_Word>,
346 Xkb2Qt<XKB_KEY_XF86Xfer, Qt::Key_Xfer>,
347 Xkb2Qt<XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn>,
348 Xkb2Qt<XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut>,
349 Xkb2Qt<XKB_KEY_XF86Away, Qt::Key_Away>,
350 Xkb2Qt<XKB_KEY_XF86Messenger, Qt::Key_Messenger>,
351 Xkb2Qt<XKB_KEY_XF86WebCam, Qt::Key_WebCam>,
352 Xkb2Qt<XKB_KEY_XF86MailForward, Qt::Key_MailForward>,
353 Xkb2Qt<XKB_KEY_XF86Pictures, Qt::Key_Pictures>,
354 Xkb2Qt<XKB_KEY_XF86Music, Qt::Key_Music>,
355 Xkb2Qt<XKB_KEY_XF86Battery, Qt::Key_Battery>,
356 Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
357 Xkb2Qt<XKB_KEY_XF86WLAN, Qt::Key_WLAN>,
358 Xkb2Qt<XKB_KEY_XF86UWB, Qt::Key_UWB>,
359 Xkb2Qt<XKB_KEY_XF86AudioForward, Qt::Key_AudioForward>,
360 Xkb2Qt<XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat>,
361 Xkb2Qt<XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay>,
362 Xkb2Qt<XKB_KEY_XF86Subtitle, Qt::Key_Subtitle>,
363 Xkb2Qt<XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack>,
364 Xkb2Qt<XKB_KEY_XF86Time, Qt::Key_Time>,
365 Xkb2Qt<XKB_KEY_XF86Select, Qt::Key_Select>,
366 Xkb2Qt<XKB_KEY_XF86View, Qt::Key_View>,
367 Xkb2Qt<XKB_KEY_XF86TopMenu, Qt::Key_TopMenu>,
368 Xkb2Qt<XKB_KEY_XF86Red, Qt::Key_Red>,
369 Xkb2Qt<XKB_KEY_XF86Green, Qt::Key_Green>,
370 Xkb2Qt<XKB_KEY_XF86Yellow, Qt::Key_Yellow>,
371 Xkb2Qt<XKB_KEY_XF86Blue, Qt::Key_Blue>,
372 Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
373 Xkb2Qt<XKB_KEY_XF86Suspend, Qt::Key_Suspend>,
374 Xkb2Qt<XKB_KEY_XF86Hibernate, Qt::Key_Hibernate>,
375 Xkb2Qt<XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle>,
376 Xkb2Qt<XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn>,
377 Xkb2Qt<XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff>,
378 Xkb2Qt<XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute>,
379 Xkb2Qt<XKB_KEY_XF86Launch0, Qt::Key_Launch0>,
380 Xkb2Qt<XKB_KEY_XF86Launch1, Qt::Key_Launch1>,
381 Xkb2Qt<XKB_KEY_XF86Launch2, Qt::Key_Launch2>,
382 Xkb2Qt<XKB_KEY_XF86Launch3, Qt::Key_Launch3>,
383 Xkb2Qt<XKB_KEY_XF86Launch4, Qt::Key_Launch4>,
384 Xkb2Qt<XKB_KEY_XF86Launch5, Qt::Key_Launch5>,
385 Xkb2Qt<XKB_KEY_XF86Launch6, Qt::Key_Launch6>,
386 Xkb2Qt<XKB_KEY_XF86Launch7, Qt::Key_Launch7>,
387 Xkb2Qt<XKB_KEY_XF86Launch8, Qt::Key_Launch8>,
388 Xkb2Qt<XKB_KEY_XF86Launch9, Qt::Key_Launch9>,
389 Xkb2Qt<XKB_KEY_XF86LaunchA, Qt::Key_LaunchA>,
390 Xkb2Qt<XKB_KEY_XF86LaunchB, Qt::Key_LaunchB>,
391 Xkb2Qt<XKB_KEY_XF86LaunchC, Qt::Key_LaunchC>,
392 Xkb2Qt<XKB_KEY_XF86LaunchD, Qt::Key_LaunchD>,
393 Xkb2Qt<XKB_KEY_XF86LaunchE, Qt::Key_LaunchE>,
394 Xkb2Qt<XKB_KEY_XF86LaunchF, Qt::Key_LaunchF>
395 >::Data{}
396);
397
399{
400 xkb_keysym_t lower, upper;
401
402 xkbcommon_XConvertCase(ks, &lower, &upper);
403
404 return upper;
405}
406
407QString QXkbCommon::lookupString(struct xkb_state *state, xkb_keycode_t code)
408{
409 QVarLengthArray<char, 32> chars(32);
410 const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
411 if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
412 chars.resize(size + 1);
413 xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
414 }
415 return QString::fromUtf8(chars.constData(), size);
416}
417
419{
420 QVarLengthArray<char, 32> chars(32);
421 const int size = xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
422 if (size == 0)
423 return QString(); // the keysym does not have a Unicode representation
424
425 if (Q_UNLIKELY(size > chars.size())) {
426 chars.resize(size);
427 xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
428 }
429 return QString::fromUtf8(chars.constData(), size - 1);
430}
431
433{
434 QList<xkb_keysym_t> keysyms;
435 int qtKey = event->key();
436
437 if (qtKey >= Qt::Key_F1 && qtKey <= Qt::Key_F35) {
438 keysyms.append(XKB_KEY_F1 + (qtKey - Qt::Key_F1));
439 } else if (event->modifiers() & Qt::KeypadModifier) {
440 if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
441 keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
442 } else if (isLatin1(qtKey) && event->text().isUpper()) {
443 keysyms.append(qtKey);
444 }
445
446 if (!keysyms.isEmpty())
447 return keysyms;
448
449 // check if we have a direct mapping
450 auto it = std::find_if(KeyTbl.cbegin(), KeyTbl.cend(), [&qtKey](xkb2qt_t elem) {
451 return elem.qt == static_cast<uint>(qtKey);
452 });
453 if (it != KeyTbl.end()) {
454 keysyms.append(it->xkb);
455 return keysyms;
456 }
457
458 QList<uint> ucs4;
459 if (event->text().isEmpty())
460 ucs4.append(qtKey);
461 else
462 ucs4 = event->text().toUcs4();
463
464 // From libxkbcommon keysym-utf.c:
465 // "We allow to represent any UCS character in the range U-00000000 to
466 // U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff."
467 for (uint utf32 : std::as_const(ucs4))
468 keysyms.append(utf32 | 0x01000000);
469
470 return keysyms;
471}
472
473int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers)
474{
475 return keysymToQtKey(keysym, modifiers, nullptr, 0);
476}
477
478int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
479 xkb_state *state, xkb_keycode_t code,
480 bool superAsMeta, bool hyperAsMeta)
481{
482 // Note 1: All standard key sequences on linux (as defined in platform theme)
483 // that use a latin character also contain a control modifier, which is why
484 // checking for Qt::ControlModifier is sufficient here. It is possible to
485 // override QPlatformTheme::keyBindings() and provide custom sequences for
486 // QKeySequence::StandardKey. Custom sequences probably should respect this
487 // convention (alternatively, we could test against other modifiers here).
488 // Note 2: The possibleKeys() shorcut mechanism is not affected by this value
489 // adjustment and does its own thing.
491 // With standard shortcuts we should prefer a latin character, this is
492 // for checks like "some qkeyevent == QKeySequence::Copy" to work even
493 // when using for example 'russian' keyboard layout.
495 xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
496 if (latinKeysym != XKB_KEY_NoSymbol)
497 keysym = latinKeysym;
498 }
499 }
500
501 return keysymToQtKey_internal(keysym, modifiers, state, code, superAsMeta, hyperAsMeta);
502}
503
504static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
505 xkb_state *state, xkb_keycode_t code,
506 bool superAsMeta, bool hyperAsMeta)
507{
508 int qtKey = 0;
509
510 // lookup from direct mapping
511 if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
512 // function keys
513 qtKey = Qt::Key_F1 + (keysym - XKB_KEY_F1);
514 } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
515 // numeric keypad keys
516 qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
517 } else if (QXkbCommon::isLatin1(keysym)) {
518 // Most Qt::Key values are determined by their upper-case version,
519 // where this is in the Latin-1 repertoire. So start with that:
521 // However, Key_mu and Key_ydiaeresis are U+00B5 MICRO SIGN and
522 // U+00FF LATIN SMALL LETTER Y WITH DIAERESIS, both lower-case,
523 // with upper-case forms outside Latin-1, so use them as they are
524 // since they're the Qt::Key values.
526 qtKey = keysym;
527 } else {
528 // check if we have a direct mapping
529 xkb2qt_t searchKey{keysym, 0};
530 auto it = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
531 if (it != KeyTbl.end() && !(searchKey < *it))
532 qtKey = it->qt;
533
534 // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
535 if (superAsMeta && (qtKey == Qt::Key_Super_L || qtKey == Qt::Key_Super_R))
537 if (hyperAsMeta && (qtKey == Qt::Key_Hyper_L || qtKey == Qt::Key_Hyper_R))
539 }
540
541 if (qtKey)
542 return qtKey;
543
544 // lookup from unicode
547 // Control modifier changes the text to ASCII control character, therefore we
548 // can't use this text to map keysym to a qt key. We can use the same keysym
549 // (it is not affectd by transformation) to obtain untransformed text. For details
550 // see "Appendix A. Default Symbol Transformations" in the XKB specification.
552 } else {
554 }
555 if (!text.isEmpty()) {
556 if (text.unicode()->isDigit()) {
557 // Ensures that also non-latin digits are mapped to corresponding qt keys,
558 // e.g CTRL + Û² (arabic two), is mapped to CTRL + Qt::Key_2.
559 qtKey = Qt::Key_0 + text.unicode()->digitValue();
560 } else {
561 text = text.toUpper();
563 qtKey = i.next(0);
564 }
565 }
566
567 return qtKey;
568}
569
570Qt::KeyboardModifiers QXkbCommon::modifiers(struct xkb_state *state, xkb_keysym_t keysym)
571{
572 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
573
574 if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) > 0)
576 if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) > 0)
578 if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) > 0)
580 if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) > 0)
582
583 if (isKeypad(keysym))
585
586 return modifiers;
587}
588
589// Possible modifier states.
590static const Qt::KeyboardModifiers ModsTbl[] = {
591 Qt::NoModifier, // 0
595 Qt::AltModifier, // 4
599 Qt::NoModifier // Fall-back to raw Key_*, for non-latin1 kb layouts
600};
601
602/*
603 Compatibility until all sub modules have transitioned to new API below
604*/
605QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
606 bool superAsMeta, bool hyperAsMeta)
607{
608 QList<int> result;
609 auto keyCombinations = possibleKeyCombinations(state, event, superAsMeta, hyperAsMeta);
610 for (auto keyCombination : keyCombinations)
611 result << keyCombination.toCombined();
612
613 return result;
614}
615
616QList<QKeyCombination> QXkbCommon::possibleKeyCombinations(xkb_state *state, const QKeyEvent *event,
617 bool superAsMeta, bool hyperAsMeta)
618{
619 QList<QKeyCombination> result;
620 quint32 keycode = event->nativeScanCode();
621 if (!keycode)
622 return result;
623
624 Qt::KeyboardModifiers modifiers = event->modifiers();
625 xkb_keymap *keymap = xkb_state_get_keymap(state);
626 // turn off the modifier bits which doesn't participate in shortcuts
627 Qt::KeyboardModifiers notNeeded = Qt::KeypadModifier | Qt::GroupSwitchModifier;
628 modifiers &= ~notNeeded;
629 // create a fresh kb state and test against the relevant modifier combinations
630 ScopedXKBState scopedXkbQueryState(xkb_state_new(keymap));
631 xkb_state *queryState = scopedXkbQueryState.get();
632 if (!queryState) {
633 qCWarning(lcQpaKeyMapper) << Q_FUNC_INFO << "failed to compile xkb keymap";
634 return result;
635 }
636 // get kb state from the master state and update the temporary state
637 xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(state, XKB_STATE_LAYOUT_LOCKED);
638 xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED);
639 xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED);
640 xkb_mod_mask_t depressedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_DEPRESSED);
641 xkb_state_update_mask(queryState, depressedMods, latchedMods, lockedMods, 0, 0, lockedLayout);
642 // handle shortcuts for level three and above
643 xkb_layout_index_t layoutIndex = xkb_state_key_get_layout(queryState, keycode);
644 xkb_level_index_t levelIndex = 0;
645 if (layoutIndex != XKB_LAYOUT_INVALID) {
646 levelIndex = xkb_state_key_get_level(queryState, keycode, layoutIndex);
647 if (levelIndex == XKB_LEVEL_INVALID)
648 levelIndex = 0;
649 }
650 if (levelIndex <= 1)
651 xkb_state_update_mask(queryState, 0, latchedMods, lockedMods, 0, 0, lockedLayout);
652
653 xkb_keysym_t sym = xkb_state_key_get_one_sym(queryState, keycode);
654 if (sym == XKB_KEY_NoSymbol)
655 return result;
656
657 int baseQtKey = keysymToQtKey_internal(sym, modifiers, queryState, keycode, superAsMeta, hyperAsMeta);
658 if (baseQtKey)
660
661 xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(keymap, "Shift");
662 xkb_mod_index_t altMod = xkb_keymap_mod_get_index(keymap, "Alt");
663 xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(keymap, "Control");
664 xkb_mod_index_t metaMod = xkb_keymap_mod_get_index(keymap, "Meta");
665
666 Q_ASSERT(shiftMod < 32);
667 Q_ASSERT(altMod < 32);
668 Q_ASSERT(controlMod < 32);
669
670 xkb_mod_mask_t depressed;
671 int qtKey = 0;
672 // obtain a list of possible shortcuts for the given key event
673 for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) {
674 Qt::KeyboardModifiers neededMods = ModsTbl[i];
675 if ((modifiers & neededMods) == neededMods) {
676 if (i == 8) {
677 if (isLatin1(baseQtKey))
678 continue;
679 // add a latin key as a fall back key
681 } else {
682 depressed = 0;
683 if (neededMods & Qt::AltModifier)
684 depressed |= (1 << altMod);
685 if (neededMods & Qt::ShiftModifier)
686 depressed |= (1 << shiftMod);
687 if (neededMods & Qt::ControlModifier)
688 depressed |= (1 << controlMod);
689 if (metaMod < 32 && neededMods & Qt::MetaModifier)
690 depressed |= (1 << metaMod);
691 xkb_state_update_mask(queryState, depressed, latchedMods, lockedMods, 0, 0, lockedLayout);
692 sym = xkb_state_key_get_one_sym(queryState, keycode);
693 }
694 if (sym == XKB_KEY_NoSymbol)
695 continue;
696
697 Qt::KeyboardModifiers mods = modifiers & ~neededMods;
698 qtKey = keysymToQtKey_internal(sym, mods, queryState, keycode, superAsMeta, hyperAsMeta);
699 if (!qtKey || qtKey == baseQtKey)
700 continue;
701
702 // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +,
703 // but Ctrl++ is more specific than +, so we should skip the last one
704 bool ambiguous = false;
705 for (auto keyCombination : std::as_const(result)) {
706 if (keyCombination.key() == qtKey
707 && (keyCombination.keyboardModifiers() & mods) == mods) {
708 ambiguous = true;
709 break;
710 }
711 }
712 if (ambiguous)
713 continue;
714
716 }
717 }
718
719 return result;
720}
721
722void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
723{
724 const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(keymap);
725 const xkb_keycode_t minKeycode = xkb_keymap_min_keycode(keymap);
726 const xkb_keycode_t maxKeycode = xkb_keymap_max_keycode(keymap);
727
728 const xkb_keysym_t *keysyms = nullptr;
729 int nrLatinKeys = 0;
730 for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
731 for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
732 xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
733 if (keysyms && isLatin1(keysyms[0]))
734 nrLatinKeys++;
735 if (nrLatinKeys > 10) // arbitrarily chosen threshold
736 return;
737 }
738 }
739 // This means that lookupLatinKeysym() will not find anything and latin
740 // key shortcuts might not work. This is a bug in the affected desktop
741 // environment. Usually can be solved via system settings by adding e.g. 'us'
742 // layout to the list of selected layouts, or by using command line, "setxkbmap
743 // -layout rus,en". The position of latin key based layout in the list of the
744 // selected layouts is irrelevant. Properly functioning desktop environments
745 // handle this behind the scenes, even if no latin key based layout has been
746 // explicitly listed in the selected layouts.
747 qCDebug(lcQpaKeyMapper, "no keyboard layouts with latin keys present");
748}
749
750xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode)
751{
752 xkb_layout_index_t layout;
753 xkb_keysym_t sym = XKB_KEY_NoSymbol;
754 if (!state)
755 return sym;
756 xkb_keymap *keymap = xkb_state_get_keymap(state);
757 const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(keymap, keycode);
758 const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(state, keycode);
759 // Look at user layouts in the order in which they are defined in system
760 // settings to find a latin keysym.
761 for (layout = 0; layout < layoutCount; ++layout) {
762 if (layout == currentLayout)
763 continue;
764 const xkb_keysym_t *syms = nullptr;
765 xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
766 if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
767 continue;
768 if (isLatin1(syms[0])) {
769 sym = syms[0];
770 break;
771 }
772 }
773
774 if (sym == XKB_KEY_NoSymbol)
775 return sym;
776
777 xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED);
778 xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED);
779
780 // Check for uniqueness, consider the following setup:
781 // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active).
782 // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+<physical x key>,
783 // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained
784 // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired
785 // then the obtained key is not unique. This prevents ctrl+<physical q key> from generating a ctrl+q
786 // shortcut in the above described setup. We don't want ctrl+<physical x key> and ctrl+<physical q key> to
787 // generate the same shortcut event in this case.
788 const xkb_keycode_t minKeycode = xkb_keymap_min_keycode(keymap);
789 const xkb_keycode_t maxKeycode = xkb_keymap_max_keycode(keymap);
790 ScopedXKBState queryState(xkb_state_new(keymap));
791 for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) {
792 xkb_state_update_mask(queryState.get(), 0, latchedMods, lockedMods, 0, 0, prevLayout);
793 for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
794 xkb_keysym_t prevSym = xkb_state_key_get_one_sym(queryState.get(), code);
795 if (prevSym == sym) {
796 sym = XKB_KEY_NoSymbol;
797 break;
798 }
799 }
800 }
801
802 return sym;
803}
804
805void QXkbCommon::setXkbContext(QPlatformInputContext *inputContext, struct xkb_context *context)
806{
807 if (!inputContext || !context)
808 return;
809
810 const char *const inputContextClassName = "QComposeInputContext";
811 const char *const normalizedSignature = "setXkbContext(xkb_context*)";
812
813 if (inputContext->objectName() != QLatin1StringView(inputContextClassName))
814 return;
815
816 static const QMetaMethod setXkbContext = [&]() {
817 int methodIndex = inputContext->metaObject()->indexOfMethod(normalizedSignature);
818 QMetaMethod method = inputContext->metaObject()->method(methodIndex);
819 Q_ASSERT(method.isValid());
820 if (!method.isValid())
821 qCWarning(lcQpaKeyMapper) << normalizedSignature << "not found on" << inputContextClassName;
822 return method;
823 }();
824
825 if (!setXkbContext.isValid())
826 return;
827
828 setXkbContext.invoke(inputContext, Qt::DirectConnection, Q_ARG(struct xkb_context*, context));
829}
830
static constexpr QKeyCombination fromCombined(int combined)
The QKeyEvent class describes a key event.
Definition qevent.h:424
\inmodule QtCore
Definition qmetaobject.h:19
QString objectName
the name of this object
Definition qobject.h:107
The QPlatformInputContext class abstracts the input method dependent data and composing state.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QString toUpper() const &
Definition qstring.h:439
const QChar * unicode() const
Returns a Unicode representation of the string.
Definition qstring.h:1230
static QString lookupStringNoKeysymTransformations(xkb_keysym_t keysym)
static void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
static QList< QKeyCombination > possibleKeyCombinations(xkb_state *state, const QKeyEvent *event, bool superAsMeta=false, bool hyperAsMeta=false)
static bool isLatin1(xkb_keysym_t sym)
static QString lookupString(struct xkb_state *state, xkb_keycode_t code)
static void verifyHasLatinLayout(xkb_keymap *keymap)
std::unique_ptr< struct xkb_state, XKBStateDeleter > ScopedXKBState
static QList< xkb_keysym_t > toKeysym(QKeyEvent *event)
static Qt::KeyboardModifiers modifiers(struct xkb_state *state, xkb_keysym_t keysym=XKB_KEY_VoidSymbol)
static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode)
static QList< int > possibleKeys(xkb_state *state, const QKeyEvent *event, bool superAsMeta=false, bool hyperAsMeta=false)
static void setXkbContext(QPlatformInputContext *inputContext, struct xkb_context *context)
static bool isKeypad(xkb_keysym_t sym)
static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers)
static xkb_keysym_t qxkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks)
EGLImageKHR int int EGLuint64KHR * modifiers
QString text
QSet< QString >::iterator it
else opt state
[0]
Combined button and popup list for selecting options.
Definition qcompare.h:63
@ Key_Super_R
Definition qnamespace.h:726
@ Key_9
Definition qnamespace.h:539
@ Key_Super_L
Definition qnamespace.h:725
@ Key_F35
Definition qnamespace.h:724
@ Key_0
Definition qnamespace.h:530
@ Key_Meta
Definition qnamespace.h:685
@ Key_F1
Definition qnamespace.h:690
@ Key_Hyper_R
Definition qnamespace.h:729
@ Key_Hyper_L
Definition qnamespace.h:728
@ ShiftModifier
@ ControlModifier
@ MetaModifier
@ GroupSwitchModifier
@ KeypadModifier
@ NoModifier
@ AltModifier
@ DirectConnection
static void * context
#define Q_UNLIKELY(x)
#define Q_FUNC_INFO
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr QtPrivate::ArrayType< ManualType, Types... > qMakeArray(Types &&... t) noexcept
#define Q_ARG(Type, data)
Definition qobjectdefs.h:63
GLenum GLuint GLint level
GLenum GLuint GLintptr GLsizeiptr size
[1]
struct _cl_event * event
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QString qtKey(CFStringRef cfkey)
unsigned int quint32
Definition qtypes.h:50
unsigned int uint
Definition qtypes.h:34
int keycode
Definition qvnc.cpp:140
int keysym
Definition qvnc.cpp:139
#define XKB_MOD_NAME_ALT
#define XKB_MOD_NAME_SHIFT
#define XKB_MOD_NAME_LOGO
#define XKB_MOD_NAME_CTRL
static constexpr const auto KeyTbl
static QT_BEGIN_NAMESPACE int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers, xkb_state *state, xkb_keycode_t code, bool superAsMeta, bool hyperAsMeta)
struct xkb2qt xkb2qt_t
static const Qt::KeyboardModifiers ModsTbl[]
QVBoxLayout * layout
static constexpr Type data() noexcept
constexpr bool operator<=(const xkb2qt &that) const noexcept
unsigned int xkb
constexpr bool operator<(const xkb2qt &that) const noexcept
unsigned int qt