15 #include <string_view> 16 #include <unordered_map> 21 #include "keynametable-compat.h" 22 #include "keynametable.h" 33 std::unordered_map<KeySym, const char *, EnumHash> makeLookupKeyNameMap() {
39 {FcitxKey_Alt_L, NC_(
"Key name",
"Left Alt")},
40 {FcitxKey_Alt_R, NC_(
"Key name",
"Right Alt")},
41 {FcitxKey_Shift_L, NC_(
"Key name",
"Left Shift")},
42 {FcitxKey_Shift_R, NC_(
"Key name",
"Right Shift")},
43 {FcitxKey_Control_L, NC_(
"Key name",
"Left Control")},
44 {FcitxKey_Control_R, NC_(
"Key name",
"Right Control")},
45 {FcitxKey_Super_L, NC_(
"Key name",
"Left Super")},
46 {FcitxKey_Super_R, NC_(
"Key name",
"Right Super")},
47 {FcitxKey_Hyper_L, NC_(
"Key name",
"Left Hyper")},
48 {FcitxKey_Hyper_R, NC_(
"Key name",
"Right Hyper")},
49 {FcitxKey_space, NC_(
"Key name",
"Space")},
50 {FcitxKey_Tab, NC_(
"Key name",
"Tab")},
51 {FcitxKey_BackSpace, NC_(
"Key name",
"Backspace")},
52 {FcitxKey_Return, NC_(
"Key name",
"Return")},
53 {FcitxKey_Pause, NC_(
"Key name",
"Pause")},
54 {FcitxKey_Home, NC_(
"Key name",
"Home")},
55 {FcitxKey_End, NC_(
"Key name",
"End")},
56 {FcitxKey_Left, NC_(
"Key name",
"Left")},
57 {FcitxKey_Up, NC_(
"Key name",
"Up")},
58 {FcitxKey_Right, NC_(
"Key name",
"Right")},
59 {FcitxKey_Down, NC_(
"Key name",
"Down")},
60 {FcitxKey_Page_Up, NC_(
"Key name",
"Page Up")},
61 {FcitxKey_Page_Down, NC_(
"Key name",
"Page Down")},
62 {FcitxKey_Caps_Lock, NC_(
"Key name",
"CapsLock")},
63 {FcitxKey_Num_Lock, NC_(
"Key name",
"NumLock")},
64 {FcitxKey_KP_Space, NC_(
"Key name",
"Keypad Space")},
65 {FcitxKey_KP_Tab, NC_(
"Key name",
"Keypad Tab")},
66 {FcitxKey_KP_Enter, NC_(
"Key name",
"Keypad Enter")},
67 {FcitxKey_KP_F1, NC_(
"Key name",
"Keypad F1")},
68 {FcitxKey_KP_F2, NC_(
"Key name",
"Keypad F2")},
69 {FcitxKey_KP_F3, NC_(
"Key name",
"Keypad F3")},
70 {FcitxKey_KP_F4, NC_(
"Key name",
"Keypad F4")},
71 {FcitxKey_KP_Home, NC_(
"Key name",
"Keypad Home")},
72 {FcitxKey_KP_Left, NC_(
"Key name",
"Keypad Left")},
73 {FcitxKey_KP_Up, NC_(
"Key name",
"Keypad Up")},
74 {FcitxKey_KP_Right, NC_(
"Key name",
"Keypad Right")},
75 {FcitxKey_KP_Down, NC_(
"Key name",
"Keypad Down")},
76 {FcitxKey_KP_Page_Up, NC_(
"Key name",
"Keypad Page Up")},
77 {FcitxKey_KP_Page_Down, NC_(
"Key name",
"Keypad Page Down")},
78 {FcitxKey_KP_End, NC_(
"Key name",
"Keypad End")},
79 {FcitxKey_KP_Begin, NC_(
"Key name",
"Keypad Begin")},
80 {FcitxKey_KP_Insert, NC_(
"Key name",
"Keypad Insert")},
81 {FcitxKey_KP_Delete, NC_(
"Key name",
"Keypad Delete")},
82 {FcitxKey_KP_Equal, NC_(
"Key name",
"Keypad =")},
83 {FcitxKey_KP_Multiply, NC_(
"Key name",
"Keypad *")},
84 {FcitxKey_KP_Add, NC_(
"Key name",
"Keypad +")},
85 {FcitxKey_KP_Separator, NC_(
"Key name",
"Keypad ,")},
86 {FcitxKey_KP_Subtract, NC_(
"Key name",
"Keypad -")},
87 {FcitxKey_KP_Decimal, NC_(
"Key name",
"Keypad .")},
88 {FcitxKey_KP_Divide, NC_(
"Key name",
"Keypad /")},
89 {FcitxKey_KP_0, NC_(
"Key name",
"Keypad 0")},
90 {FcitxKey_KP_1, NC_(
"Key name",
"Keypad 1")},
91 {FcitxKey_KP_2, NC_(
"Key name",
"Keypad 2")},
92 {FcitxKey_KP_3, NC_(
"Key name",
"Keypad 3")},
93 {FcitxKey_KP_4, NC_(
"Key name",
"Keypad 4")},
94 {FcitxKey_KP_5, NC_(
"Key name",
"Keypad 5")},
95 {FcitxKey_KP_6, NC_(
"Key name",
"Keypad 6")},
96 {FcitxKey_KP_7, NC_(
"Key name",
"Keypad 7")},
97 {FcitxKey_KP_8, NC_(
"Key name",
"Keypad 8")},
98 {FcitxKey_KP_9, NC_(
"Key name",
"Keypad 9")},
99 {FcitxKey_Scroll_Lock, NC_(
"Key name",
"ScrollLock")},
100 {FcitxKey_Menu, NC_(
"Key name",
"Menu")},
101 {FcitxKey_Help, NC_(
"Key name",
"Help")},
102 {FcitxKey_Back, NC_(
"Key name",
"Back")},
103 {FcitxKey_Forward, NC_(
"Key name",
"Forward")},
104 {FcitxKey_Stop, NC_(
"Key name",
"Stop")},
105 {FcitxKey_Refresh, NC_(
"Key name",
"Refresh")},
106 {FcitxKey_AudioLowerVolume, NC_(
"Key name",
"Volume Down")},
107 {FcitxKey_AudioMute, NC_(
"Key name",
"Volume Mute")},
108 {FcitxKey_AudioRaiseVolume, NC_(
"Key name",
"Volume Up")},
109 {FcitxKey_AudioPlay, NC_(
"Key name",
"Media Play")},
110 {FcitxKey_AudioStop, NC_(
"Key name",
"Media Stop")},
111 {FcitxKey_AudioPrev, NC_(
"Key name",
"Media Previous")},
112 {FcitxKey_AudioNext, NC_(
"Key name",
"Media Next")},
113 {FcitxKey_AudioRecord, NC_(
"Key name",
"Media Record")},
114 {FcitxKey_AudioPause, NC_(
"Key name",
"Media Pause")},
115 {FcitxKey_HomePage, NC_(
"Key name",
"Home Page")},
116 {FcitxKey_Favorites, NC_(
"Key name",
"Favorites")},
117 {FcitxKey_Search, NC_(
"Key name",
"Search")},
118 {FcitxKey_Standby, NC_(
"Key name",
"Standby")},
119 {FcitxKey_OpenURL, NC_(
"Key name",
"Open URL")},
120 {FcitxKey_Mail, NC_(
"Key name",
"Launch Mail")},
121 {FcitxKey_Launch0, NC_(
"Key name",
"Launch (0)")},
122 {FcitxKey_Launch1, NC_(
"Key name",
"Launch (1)")},
123 {FcitxKey_Launch2, NC_(
"Key name",
"Launch (2)")},
124 {FcitxKey_Launch3, NC_(
"Key name",
"Launch (3)")},
125 {FcitxKey_Launch4, NC_(
"Key name",
"Launch (4)")},
126 {FcitxKey_Launch5, NC_(
"Key name",
"Launch (5)")},
127 {FcitxKey_Launch6, NC_(
"Key name",
"Launch (6)")},
128 {FcitxKey_Launch7, NC_(
"Key name",
"Launch (7)")},
129 {FcitxKey_Launch8, NC_(
"Key name",
"Launch (8)")},
130 {FcitxKey_Launch9, NC_(
"Key name",
"Launch (9)")},
131 {FcitxKey_LaunchA, NC_(
"Key name",
"Launch (A)")},
132 {FcitxKey_LaunchB, NC_(
"Key name",
"Launch (B)")},
133 {FcitxKey_LaunchC, NC_(
"Key name",
"Launch (C)")},
134 {FcitxKey_LaunchD, NC_(
"Key name",
"Launch (D)")},
135 {FcitxKey_LaunchE, NC_(
"Key name",
"Launch (E)")},
136 {FcitxKey_LaunchF, NC_(
"Key name",
"Launch (F)")},
137 {FcitxKey_MonBrightnessUp, NC_(
"Key name",
"Monitor Brightness Up")},
138 {FcitxKey_MonBrightnessDown,
139 NC_(
"Key name",
"Monitor Brightness Down")},
140 {FcitxKey_KbdLightOnOff, NC_(
"Key name",
"Keyboard Light On/Off")},
141 {FcitxKey_KbdBrightnessUp, NC_(
"Key name",
"Keyboard Brightness Up")},
142 {FcitxKey_KbdBrightnessDown,
143 NC_(
"Key name",
"Keyboard Brightness Down")},
144 {FcitxKey_PowerOff, NC_(
"Key name",
"Power Off")},
145 {FcitxKey_WakeUp, NC_(
"Key name",
"Wake Up")},
146 {FcitxKey_Eject, NC_(
"Key name",
"Eject")},
147 {FcitxKey_ScreenSaver, NC_(
"Key name",
"Screensaver")},
148 {FcitxKey_WWW, NC_(
"Key name",
"WWW")},
149 {FcitxKey_Sleep, NC_(
"Key name",
"Sleep")},
150 {FcitxKey_LightBulb, NC_(
"Key name",
"LightBulb")},
151 {FcitxKey_Shop, NC_(
"Key name",
"Shop")},
152 {FcitxKey_History, NC_(
"Key name",
"History")},
153 {FcitxKey_AddFavorite, NC_(
"Key name",
"Add Favorite")},
154 {FcitxKey_HotLinks, NC_(
"Key name",
"Hot Links")},
155 {FcitxKey_BrightnessAdjust, NC_(
"Key name",
"Adjust Brightness")},
156 {FcitxKey_Finance, NC_(
"Key name",
"Finance")},
157 {FcitxKey_Community, NC_(
"Key name",
"Community")},
158 {FcitxKey_AudioRewind, NC_(
"Key name",
"Media Rewind")},
159 {FcitxKey_BackForward, NC_(
"Key name",
"Back Forward")},
160 {FcitxKey_ApplicationLeft, NC_(
"Key name",
"Application Left")},
161 {FcitxKey_ApplicationRight, NC_(
"Key name",
"Application Right")},
162 {FcitxKey_Book, NC_(
"Key name",
"Book")},
163 {FcitxKey_CD, NC_(
"Key name",
"CD")},
164 {FcitxKey_Calculator, NC_(
"Key name",
"Calculator")},
165 {FcitxKey_Clear, NC_(
"Key name",
"Clear")},
166 {FcitxKey_Close, NC_(
"Key name",
"Close")},
167 {FcitxKey_Copy, NC_(
"Key name",
"Copy")},
168 {FcitxKey_Cut, NC_(
"Key name",
"Cut")},
169 {FcitxKey_Display, NC_(
"Key name",
"Display")},
170 {FcitxKey_DOS, NC_(
"Key name",
"DOS")},
171 {FcitxKey_Documents, NC_(
"Key name",
"Documents")},
172 {FcitxKey_Excel, NC_(
"Key name",
"Spreadsheet")},
173 {FcitxKey_Explorer, NC_(
"Key name",
"Browser")},
174 {FcitxKey_Game, NC_(
"Key name",
"Game")},
175 {FcitxKey_Go, NC_(
"Key name",
"Go")},
176 {FcitxKey_iTouch, NC_(
"Key name",
"iTouch")},
177 {FcitxKey_LogOff, NC_(
"Key name",
"Logoff")},
178 {FcitxKey_Market, NC_(
"Key name",
"Market")},
179 {FcitxKey_Meeting, NC_(
"Key name",
"Meeting")},
180 {FcitxKey_MenuKB, NC_(
"Key name",
"Keyboard Menu")},
181 {FcitxKey_MenuPB, NC_(
"Key name",
"Menu PB")},
182 {FcitxKey_MySites, NC_(
"Key name",
"My Sites")},
183 {FcitxKey_News, NC_(
"Key name",
"News")},
184 {FcitxKey_OfficeHome, NC_(
"Key name",
"Home Office")},
185 {FcitxKey_Option, NC_(
"Key name",
"Option")},
186 {FcitxKey_Paste, NC_(
"Key name",
"Paste")},
187 {FcitxKey_Phone, NC_(
"Key name",
"Phone")},
188 {FcitxKey_Reply, NC_(
"Key name",
"Reply")},
189 {FcitxKey_Reload, NC_(
"Key name",
"Reload")},
190 {FcitxKey_RotateWindows, NC_(
"Key name",
"Rotate Windows")},
191 {FcitxKey_RotationPB, NC_(
"Key name",
"Rotation PB")},
192 {FcitxKey_RotationKB, NC_(
"Key name",
"Rotation KB")},
193 {FcitxKey_Save, NC_(
"Key name",
"Save")},
194 {FcitxKey_Send, NC_(
"Key name",
"Send")},
195 {FcitxKey_Spell, NC_(
"Key name",
"Spellchecker")},
196 {FcitxKey_SplitScreen, NC_(
"Key name",
"Split Screen")},
197 {FcitxKey_Support, NC_(
"Key name",
"Support")},
198 {FcitxKey_TaskPane, NC_(
"Key name",
"Task Panel")},
199 {FcitxKey_Terminal, NC_(
"Key name",
"Terminal")},
200 {FcitxKey_Tools, NC_(
"Key name",
"Tools")},
201 {FcitxKey_Travel, NC_(
"Key name",
"Travel")},
202 {FcitxKey_Video, NC_(
"Key name",
"Video")},
203 {FcitxKey_Word, NC_(
"Key name",
"Word Processor")},
204 {FcitxKey_Xfer, NC_(
"Key name",
"XFer")},
205 {FcitxKey_ZoomIn, NC_(
"Key name",
"Zoom In")},
206 {FcitxKey_ZoomOut, NC_(
"Key name",
"Zoom Out")},
207 {FcitxKey_Away, NC_(
"Key name",
"Away")},
208 {FcitxKey_Messenger, NC_(
"Key name",
"Messenger")},
209 {FcitxKey_WebCam, NC_(
"Key name",
"WebCam")},
210 {FcitxKey_MailForward, NC_(
"Key name",
"Mail Forward")},
211 {FcitxKey_Pictures, NC_(
"Key name",
"Pictures")},
212 {FcitxKey_Music, NC_(
"Key name",
"Music")},
213 {FcitxKey_Battery, NC_(
"Key name",
"Battery")},
214 {FcitxKey_Bluetooth, NC_(
"Key name",
"Bluetooth")},
215 {FcitxKey_WLAN, NC_(
"Key name",
"Wireless")},
216 {FcitxKey_AudioForward, NC_(
"Key name",
"Media Fast Forward")},
217 {FcitxKey_AudioRepeat, NC_(
"Key name",
"Audio Repeat")},
218 {FcitxKey_AudioRandomPlay, NC_(
"Key name",
"Audio Random Play")},
219 {FcitxKey_Subtitle, NC_(
"Key name",
"Subtitle")},
220 {FcitxKey_AudioCycleTrack, NC_(
"Key name",
"Audio Cycle Track")},
221 {FcitxKey_Time, NC_(
"Key name",
"Time")},
222 {FcitxKey_Hibernate, NC_(
"Key name",
"Hibernate")},
223 {FcitxKey_View, NC_(
"Key name",
"View")},
224 {FcitxKey_TopMenu, NC_(
"Key name",
"Top Menu")},
225 {FcitxKey_PowerDown, NC_(
"Key name",
"Power Down")},
226 {FcitxKey_Suspend, NC_(
"Key name",
"Suspend")},
227 {FcitxKey_AudioMicMute, NC_(
"Key name",
"Microphone Mute")},
228 {FcitxKey_Red, NC_(
"Key name",
"Red")},
229 {FcitxKey_Green, NC_(
"Key name",
"Green")},
230 {FcitxKey_Yellow, NC_(
"Key name",
"Yellow")},
231 {FcitxKey_Blue, NC_(
"Key name",
"Blue")},
232 {FcitxKey_New, NC_(
"Key name",
"New")},
233 {FcitxKey_Open, NC_(
"Key name",
"Open")},
234 {FcitxKey_Find, NC_(
"Key name",
"Find")},
235 {FcitxKey_Undo, NC_(
"Key name",
"Undo")},
236 {FcitxKey_Redo, NC_(
"Key name",
"Redo")},
237 {FcitxKey_Print, NC_(
"Key name",
"Print Screen")},
238 {FcitxKey_Insert, NC_(
"Key name",
"Insert")},
239 {FcitxKey_Delete, NC_(
"Key name",
"Delete")},
240 {FcitxKey_Escape, NC_(
"Key name",
"Escape")},
241 {FcitxKey_Sys_Req, NC_(
"Key name",
"System Request")},
242 {FcitxKey_Select, NC_(
"Key name",
"Select")},
243 {FcitxKey_Kanji, NC_(
"Key name",
"Kanji")},
244 {FcitxKey_Muhenkan, NC_(
"Key name",
"Muhenkan")},
245 {FcitxKey_Henkan, NC_(
"Key name",
"Henkan")},
246 {FcitxKey_Romaji, NC_(
"Key name",
"Romaji")},
247 {FcitxKey_Hiragana, NC_(
"Key name",
"Hiragana")},
248 {FcitxKey_Katakana, NC_(
"Key name",
"Katakana")},
249 {FcitxKey_Hiragana_Katakana, NC_(
"Key name",
"Hiragana Katakana")},
250 {FcitxKey_Zenkaku, NC_(
"Key name",
"Zenkaku")},
251 {FcitxKey_Hankaku, NC_(
"Key name",
"Hankaku")},
252 {FcitxKey_Zenkaku_Hankaku, NC_(
"Key name",
"Zenkaku Hankaku")},
253 {FcitxKey_Touroku, NC_(
"Key name",
"Touroku")},
254 {FcitxKey_Massyo, NC_(
"Key name",
"Massyo")},
255 {FcitxKey_Kana_Lock, NC_(
"Key name",
"Kana Lock")},
256 {FcitxKey_Kana_Shift, NC_(
"Key name",
"Kana Shift")},
257 {FcitxKey_Eisu_Shift, NC_(
"Key name",
"Eisu Shift")},
258 {FcitxKey_Eisu_toggle, NC_(
"Key name",
"Eisu toggle")},
259 {FcitxKey_Codeinput, NC_(
"Key name",
"Code input")},
260 {FcitxKey_MultipleCandidate, NC_(
"Key name",
"Multiple Candidate")},
261 {FcitxKey_PreviousCandidate, NC_(
"Key name",
"Previous Candidate")},
262 {FcitxKey_Hangul, NC_(
"Key name",
"Hangul")},
263 {FcitxKey_Hangul_Start, NC_(
"Key name",
"Hangul Start")},
264 {FcitxKey_Hangul_End, NC_(
"Key name",
"Hangul End")},
265 {FcitxKey_Hangul_Hanja, NC_(
"Key name",
"Hangul Hanja")},
266 {FcitxKey_Hangul_Jamo, NC_(
"Key name",
"Hangul Jamo")},
267 {FcitxKey_Hangul_Romaja, NC_(
"Key name",
"Hangul Romaja")},
268 {FcitxKey_Hangul_Jeonja, NC_(
"Key name",
"Hangul Jeonja")},
269 {FcitxKey_Hangul_Banja, NC_(
"Key name",
"Hangul Banja")},
270 {FcitxKey_Hangul_PreHanja, NC_(
"Key name",
"Hangul PreHanja")},
271 {FcitxKey_Hangul_PostHanja, NC_(
"Key name",
"Hangul PostHanja")},
272 {FcitxKey_Hangul_Special, NC_(
"Key name",
"Hangul Special")},
273 {FcitxKey_Cancel, NC_(
"Key name",
"Cancel")},
274 {FcitxKey_Execute, NC_(
"Key name",
"Execute")},
275 {FcitxKey_TouchpadToggle, NC_(
"Key name",
"Touchpad Toggle")},
276 {FcitxKey_TouchpadOn, NC_(
"Key name",
"Touchpad On")},
277 {FcitxKey_TouchpadOff, NC_(
"Key name",
"Touchpad Off")},
278 {FcitxKey_VoidSymbol, NC_(
"Key name",
"Void Symbol")},
280 std::unordered_map<KeySym, const char *, EnumHash> result;
281 for (
const auto &item : keyname) {
282 result[item.key] = item.name;
287 const char *lookupName(KeySym sym) {
288 static const std::unordered_map<KeySym, const char *, EnumHash> map =
289 makeLookupKeyNameMap();
290 const auto *result = findValue(map, sym);
291 return result ? *result :
nullptr;
295 Key::Key(
const char *keyString) :
Key() {
298 const char *p = keyString;
299 const char *lastModifier = keyString;
300 const char *found =
nullptr;
302 #define _CHECK_MODIFIER(NAME, VALUE) \ 303 if ((found = strstr(p, NAME))) { \ 304 states |= KeyState::VALUE; \ 305 if (found + strlen(NAME) > lastModifier) { \ 306 lastModifier = found + strlen(NAME); \ 310 _CHECK_MODIFIER(
"CTRL_", Ctrl)
311 _CHECK_MODIFIER(
"Control+", Ctrl)
312 _CHECK_MODIFIER(
"ALT_", Alt)
313 _CHECK_MODIFIER(
"Alt+", Alt)
314 _CHECK_MODIFIER(
"SHIFT_", Shift)
315 _CHECK_MODIFIER(
"Shift+", Shift)
316 _CHECK_MODIFIER(
"SUPER_", Super)
317 _CHECK_MODIFIER(
"Super+", Super)
318 _CHECK_MODIFIER(
"HYPER_", Mod3)
319 _CHECK_MODIFIER(
"Hyper+", Mod3)
321 #undef _CHECK_MODIFIER 324 std::string_view keyValue = lastModifier;
325 if (keyValue.starts_with(
"<") && keyValue.ends_with(
">")) {
326 keyValue.remove_prefix(1);
327 keyValue.remove_suffix(1);
328 std::from_chars(keyValue.data(), keyValue.data() + keyValue.size(),
343 std::vector<Key> keys;
344 keys.emplace_back(key.sym(), states);
345 if (key.states() & KeyState::Ctrl) {
346 if (key.sym() != FcitxKey_Control_R) {
347 keys.emplace_back(FcitxKey_Control_L, states);
349 if (key.sym() != FcitxKey_Control_L) {
350 keys.emplace_back(FcitxKey_Control_R, states);
353 if (key.states() & KeyState::Alt) {
354 if (key.sym() != FcitxKey_Alt_R && key.sym() != FcitxKey_Meta_R) {
355 keys.emplace_back(FcitxKey_Alt_L, states);
356 keys.emplace_back(FcitxKey_Meta_L, states);
358 if (key.sym() != FcitxKey_Alt_L && key.sym() != FcitxKey_Meta_L) {
359 keys.emplace_back(FcitxKey_Alt_R, states);
360 keys.emplace_back(FcitxKey_Meta_R, states);
363 if (key.states() & KeyState::Shift) {
364 if (key.sym() != FcitxKey_Shift_R) {
365 keys.emplace_back(FcitxKey_Shift_L, states);
367 if (key.sym() != FcitxKey_Shift_L) {
368 keys.emplace_back(FcitxKey_Shift_R, states);
371 if ((key.states() & KeyState::Super) || (key.states() & KeyState::Super2)) {
372 if (key.sym() != FcitxKey_Super_R && key.sym() != FcitxKey_Hyper_R) {
373 keys.emplace_back(FcitxKey_Super_L, states);
374 keys.emplace_back(FcitxKey_Hyper_L, states);
376 if (key.sym() != FcitxKey_Super_L && key.sym() != FcitxKey_Hyper_L) {
377 keys.emplace_back(FcitxKey_Super_R, states);
378 keys.emplace_back(FcitxKey_Hyper_R, states);
386 auto states = states_ &
KeyStates({KeyState::Ctrl_Alt_Shift,
387 KeyState::Super, KeyState::Mod3});
388 if (states_.test(KeyState::Super2)) {
389 states |= KeyState::Super;
394 return key.states_ == states && key.code_ == code_;
397 if (key.sym() == FcitxKey_None || key.sym() == FcitxKey_VoidSymbol) {
406 return (key.sym_ == sym_ && key.states_ == states) ||
407 (key.sym_ == keyAlt.sym_ && key.states_ == keyAlt.states_);
410 return (key.sym_ == sym_ && key.states_ == states);
414 return !states_ && ((sym_ >= FcitxKey_0 && sym_ <= FcitxKey_9) ||
415 (sym_ >= FcitxKey_KP_0 && sym_ <= FcitxKey_KP_9));
422 if (sym_ >= FcitxKey_0 && sym_ <= FcitxKey_9) {
423 return sym_ - FcitxKey_0;
425 if (sym_ >= FcitxKey_KP_0 && sym_ <= FcitxKey_KP_9) {
426 return sym_ - FcitxKey_KP_0;
432 auto filteredStates =
434 KeyStates({KeyState::Ctrl_Alt_Shift, KeyState::Super, KeyState::Mod3});
435 if (filteredStates != states) {
441 return (idx + 9) % 10;
447 return !states_ && sym_ >= FcitxKey_A && sym_ <= FcitxKey_Z;
451 return !states_ && sym_ >= FcitxKey_a && sym_ <= FcitxKey_z;
457 return !states_ && sym_ >= FcitxKey_space && sym_ <= FcitxKey_asciitilde;
461 return (sym_ == FcitxKey_Control_L || sym_ == FcitxKey_Control_R ||
462 sym_ == FcitxKey_Meta_L || sym_ == FcitxKey_Meta_R ||
463 sym_ == FcitxKey_Alt_L || sym_ == FcitxKey_Alt_R ||
464 sym_ == FcitxKey_Super_L || sym_ == FcitxKey_Super_R ||
465 sym_ == FcitxKey_Hyper_L || sym_ == FcitxKey_Hyper_R ||
466 sym_ == FcitxKey_Shift_L || sym_ == FcitxKey_Shift_R);
470 return ((sym_ == FcitxKey_Left || sym_ == FcitxKey_Right ||
471 sym_ == FcitxKey_Up || sym_ == FcitxKey_Down ||
472 sym_ == FcitxKey_Page_Up || sym_ == FcitxKey_Page_Down ||
473 sym_ == FcitxKey_Home || sym_ == FcitxKey_End ||
474 sym_ == FcitxKey_KP_Left || sym_ == FcitxKey_KP_Right ||
475 sym_ == FcitxKey_KP_Up || sym_ == FcitxKey_KP_Down ||
476 sym_ == FcitxKey_KP_Page_Up || sym_ == FcitxKey_KP_Page_Down ||
477 sym_ == FcitxKey_KP_Home || sym_ == FcitxKey_KP_End) &&
478 (states_ == KeyState::Ctrl || states_ == KeyState::Ctrl_Shift ||
479 states_ == KeyState::Shift || states_ == KeyState::NoState));
483 return ((sym_ >= FcitxKey_KP_Multiply && sym_ <= FcitxKey_KP_9) ||
484 (sym_ >= FcitxKey_KP_F1 && sym_ <= FcitxKey_KP_Delete) ||
485 sym_ == FcitxKey_KP_Space || sym_ == FcitxKey_KP_Tab ||
486 sym_ == FcitxKey_KP_Enter || sym_ == FcitxKey_KP_Equal);
496 if (key.sym_ == FcitxKey_ISO_Left_Tab) {
497 key.sym_ = FcitxKey_Tab;
502 key.states_ &
KeyStates({KeyState::Ctrl_Alt_Shift, KeyState::Super,
503 KeyState::Mod3, KeyState::Super2});
504 if (key.states_.test(KeyState::Super2)) {
505 key.states_ = key.states_.unset(KeyState::Super2);
506 key.states_ |= KeyState::Super;
509 if (key.states_ != KeyState::Shift &&
Key(key.sym_).
isLAZ()) {
510 key.sym_ =
static_cast<KeySym
>(key.sym_ + FcitxKey_A - FcitxKey_a);
518 if (key.states_ == KeyState::Shift) {
522 if ((key.states_ & KeyState::Shift) &&
525 key.sym_ != FcitxKey_space && key.sym_ != FcitxKey_Return &&
526 key.sym_ != FcitxKey_Tab) ||
527 (key.sym_ >= FcitxKey_KP_0 && key.sym_ <= FcitxKey_KP_9))) {
528 key.states_ ^= KeyState::Shift;
538 return (sym_ != FcitxKey_None && sym_ != FcitxKey_VoidSymbol) || code_ != 0;
544 if (code_ && sym_ == FcitxKey_None) {
546 key += std::to_string(code_);
550 if (sym == FcitxKey_None) {
551 return std::string();
554 if (sym == FcitxKey_ISO_Left_Tab) {
561 return std::string();
565 auto states = states_;
570 #define _APPEND_MODIFIER_STRING(STR, VALUE) \ 571 if (states & VALUE) { \ 576 _APPEND_MODIFIER_STRING(
"Control", KeyState::Ctrl)
577 _APPEND_MODIFIER_STRING(
"Alt", KeyState::Alt)
578 _APPEND_MODIFIER_STRING(
"Shift", KeyState::Shift)
579 _APPEND_MODIFIER_STRING(
"Super",
580 (
KeyStates{KeyState::Super, KeyState::Super2}))
581 _APPEND_MODIFIER_STRING(
"Hyper",
582 (
KeyStates{KeyState::Hyper, KeyState::Hyper2}))
584 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Control"), KeyState::Ctrl)
585 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Alt"), KeyState::Alt)
586 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Shift"), KeyState::Shift)
587 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Super"),
588 (
KeyStates{KeyState::Super, KeyState::Super2}))
589 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Hyper"),
590 (
KeyStates{KeyState::Hyper, KeyState::Hyper2}))
593 #undef _APPEND_MODIFIER_STRING 601 case FcitxKey_Control_L:
602 case FcitxKey_Control_R:
603 return KeyState::Ctrl;
606 case FcitxKey_Meta_L:
607 case FcitxKey_Meta_R:
608 return KeyState::Alt;
609 case FcitxKey_Shift_L:
610 case FcitxKey_Shift_R:
611 return KeyState::Shift;
612 case FcitxKey_Super_L:
613 case FcitxKey_Super_R:
614 case FcitxKey_Hyper_L:
615 case FcitxKey_Hyper_R:
616 return KeyState::Super;
623 const auto *value = std::lower_bound(
624 keyValueByNameOffset,
625 keyValueByNameOffset + FCITX_ARRAY_SIZE(keyValueByNameOffset),
626 keyString, [](
const uint32_t &idx,
const std::string &str) {
627 return keyNameList[&idx - keyValueByNameOffset] < str;
631 keyValueByNameOffset + FCITX_ARRAY_SIZE(keyValueByNameOffset) &&
632 keyString == keyNameList[value - keyValueByNameOffset]) {
633 return static_cast<KeySym
>(*value);
636 const auto *compat = std::lower_bound(
638 keyNameListCompat + FCITX_ARRAY_SIZE(keyNameListCompat), keyString,
639 [](
const KeyNameListCompat &c,
const std::string &str) {
642 if (compat != keyNameListCompat + FCITX_ARRAY_SIZE(keyNameListCompat) &&
643 compat->name == keyString) {
651 return static_cast<KeySym
>(keyString[0]);
657 return FcitxKey_None;
662 if (
const auto *name = lookupName(sym)) {
663 return C_(
"Key name", name);
667 if (charutils::isprint(code)) {
675 const KeyNameOffsetByValue *result = std::lower_bound(
676 keyNameOffsetByValue,
677 keyNameOffsetByValue + FCITX_ARRAY_SIZE(keyNameOffsetByValue), sym,
678 [](
const KeyNameOffsetByValue &item, KeySym key) {
679 return item.sym < key;
682 keyNameOffsetByValue + FCITX_ARRAY_SIZE(keyNameOffsetByValue) &&
683 result->sym == sym) {
684 return keyNameList[result->offset];
686 return std::string();
690 const auto &tab = unicode_to_keysym_tab();
692 int max = tab.size() - 1;
696 if ((unicode >= 0x0020 && unicode <= 0x007e) ||
697 (unicode >= 0x00a0 && unicode <= 0x00ff))
698 return static_cast<KeySym
>(unicode);
701 if ((unicode >= (FcitxKey_BackSpace & 0x7f) &&
702 unicode <= (FcitxKey_Clear & 0x7f)) ||
703 unicode == (FcitxKey_Return & 0x7f) ||
704 unicode == (FcitxKey_Escape & 0x7f)) {
705 return static_cast<KeySym
>(unicode | 0xff00);
707 if (unicode == (FcitxKey_Delete & 0x7f)) {
708 return FcitxKey_Delete;
712 if ((unicode >= 0xd800 && unicode <= 0xdfff) ||
713 (unicode >= 0xfdd0 && unicode <= 0xfdef) || unicode > 0x10ffff ||
714 (unicode & 0xfffe) == 0xfffe) {
715 return FcitxKey_None;
720 mid = (min + max) / 2;
721 if (tab[mid].ucs < unicode) {
723 }
else if (tab[mid].ucs > unicode) {
727 return static_cast<KeySym
>(tab[mid].keysym);
735 return static_cast<KeySym
>(unicode | 0x01000000);
741 sizeof(keysym_to_unicode_tab) /
sizeof(keysym_to_unicode_tab[0]) - 1;
745 if ((sym >= 0x0020 && sym <= 0x007e) || (sym >= 0x00a0 && sym <= 0x00ff)) {
750 if (sym == FcitxKey_KP_Space) {
751 return FcitxKey_space & 0x7f;
755 if ((sym >= FcitxKey_BackSpace && sym <= FcitxKey_Clear) ||
756 (sym >= FcitxKey_KP_Multiply && sym <= FcitxKey_KP_9) ||
757 sym == FcitxKey_Return || sym == FcitxKey_Escape ||
758 sym == FcitxKey_Delete || sym == FcitxKey_KP_Tab ||
759 sym == FcitxKey_KP_Enter || sym == FcitxKey_KP_Equal) {
769 if (0x0100d800 <= sym && sym <= 0x0100dfff) {
778 if (0x01000000 <= sym && sym <= 0x0110ffff) {
779 const uint32_t code = sym - 0x01000000;
788 mid = (min + max) / 2;
789 if (keysym_to_unicode_tab[mid].keysym < sym) {
791 }
else if (keysym_to_unicode_tab[mid].keysym > sym) {
795 return keysym_to_unicode_tab[mid].ucs;
812 std::vector<Key> keyList;
814 auto lastPos = str.find_first_not_of(FCITX_WHITESPACE, 0);
815 auto pos = str.find_first_of(FCITX_WHITESPACE, lastPos);
817 while (std::string::npos != pos || std::string::npos != lastPos) {
818 Key key(str.substr(lastPos, pos - lastPos));
820 if (key.sym() != FcitxKey_None) {
821 keyList.push_back(key);
823 lastPos = str.find_first_not_of(FCITX_WHITESPACE, pos);
824 pos = str.find_first_of(FCITX_WHITESPACE, lastPos);
static KeyList keyListFromString(const std::string &str)
Parse a list of key string into a KeyList.
bool check(const Key &key) const
Check if current key match the key.
bool hasModifier() const
Check if states has modifier.
bool checkKeyList(const Container &c) const
Check the current key against a key list.
bool isSimple() const
Check if key is in the range of ascii and has no states.
std::string UCS4ToUTF8(uint32_t code)
Convert UCS4 to UTF8 string.
static uint32_t keySymToUnicode(KeySym sym)
Convert keysym to a unicode.
bool isCursorMove() const
Check if this key will cause cursor to move, e.g.
bool isValid() const
Check if the sym is not FcitxKey_None or FcitxKey_VoidSymbol.
bool isDigit() const
Check if key is digit key or keypad digit key.
KeyStringFormat
Control the behavior of toString function.
C++ Utility functions for handling utf8 strings.
int digit() const
Return the value of digit key.
bool isVirtual() const
Check if states has virtual bit.
Can be used to parse from a string.
size_t lengthValidated(Iter start, Iter end)
Validate and return the number UTF-8 characters in the string iterator range.
uint32_t getChar(Iter iter, Iter end)
Get next UCS4 char from iter, do not cross end.
static KeyStates keySymToStates(KeySym sym)
Convert the modifier symbol to its corresponding states.
bool isModifier() const
Check if the key is a modifier press.
static KeySym keySymFromString(const std::string &keyString)
Convert a key symbol string to KeySym.
bool UCS4IsValid(uint32_t code)
Check if a ucs4 is valid.
bool isReleaseOfModifier(const Key &key) const
Check if current key is a key release of given modifier only key.
Return the human readable string in localized format.
static std::string keySymToUTF8(KeySym sym)
Convert keysym to a unicode string.
bool isKeyPad() const
Check if this key is a key pad key.
static std::string keySymToString(KeySym sym, KeyStringFormat format=KeyStringFormat::Portable)
Convert keysym to a string.
int digitSelection(KeyStates states=KeyStates()) const
Return index when using digit key for selection.
Class to represent a key.
std::string toString(KeyStringFormat format=KeyStringFormat::Portable) const
Convert key to a string.
Local independent API to detect character type.
bool isLAZ() const
Check if key is lower case.
static KeySym keySymFromUnicode(uint32_t unicode)
Convert unicode to key symbol.
bool isUAZ() const
Check if key is upper case.
ssize_t ncharByteLength(Iter iter, size_t n)
get the byte length of next N utf-8 character.
Key normalize() const
Normalize a key, usually used when key is from frontend.