15 #include <string_view> 16 #include <unordered_map> 21 #include "keynametable-compat.h" 22 #include "keynametable.h" 34 std::unordered_map<KeySym, const char *, EnumHash> makeLookupKeyNameMap() {
40 {FcitxKey_Alt_L, NC_(
"Key name",
"Left Alt")},
41 {FcitxKey_Alt_R, NC_(
"Key name",
"Right Alt")},
42 {FcitxKey_Shift_L, NC_(
"Key name",
"Left Shift")},
43 {FcitxKey_Shift_R, NC_(
"Key name",
"Right Shift")},
44 {FcitxKey_Control_L, NC_(
"Key name",
"Left Control")},
45 {FcitxKey_Control_R, NC_(
"Key name",
"Right Control")},
46 {FcitxKey_Super_L, NC_(
"Key name",
"Left Super")},
47 {FcitxKey_Super_R, NC_(
"Key name",
"Right Super")},
48 {FcitxKey_Hyper_L, NC_(
"Key name",
"Left Hyper")},
49 {FcitxKey_Hyper_R, NC_(
"Key name",
"Right Hyper")},
50 {FcitxKey_space, NC_(
"Key name",
"Space")},
51 {FcitxKey_Tab, NC_(
"Key name",
"Tab")},
52 {FcitxKey_BackSpace, NC_(
"Key name",
"Backspace")},
53 {FcitxKey_Return, NC_(
"Key name",
"Return")},
54 {FcitxKey_Pause, NC_(
"Key name",
"Pause")},
55 {FcitxKey_Home, NC_(
"Key name",
"Home")},
56 {FcitxKey_End, NC_(
"Key name",
"End")},
57 {FcitxKey_Left, NC_(
"Key name",
"Left")},
58 {FcitxKey_Up, NC_(
"Key name",
"Up")},
59 {FcitxKey_Right, NC_(
"Key name",
"Right")},
60 {FcitxKey_Down, NC_(
"Key name",
"Down")},
61 {FcitxKey_Page_Up, NC_(
"Key name",
"Page Up")},
62 {FcitxKey_Page_Down, NC_(
"Key name",
"Page Down")},
63 {FcitxKey_Caps_Lock, NC_(
"Key name",
"CapsLock")},
64 {FcitxKey_Num_Lock, NC_(
"Key name",
"NumLock")},
65 {FcitxKey_KP_Space, NC_(
"Key name",
"Keypad Space")},
66 {FcitxKey_KP_Tab, NC_(
"Key name",
"Keypad Tab")},
67 {FcitxKey_KP_Enter, NC_(
"Key name",
"Keypad Enter")},
68 {FcitxKey_KP_F1, NC_(
"Key name",
"Keypad F1")},
69 {FcitxKey_KP_F2, NC_(
"Key name",
"Keypad F2")},
70 {FcitxKey_KP_F3, NC_(
"Key name",
"Keypad F3")},
71 {FcitxKey_KP_F4, NC_(
"Key name",
"Keypad F4")},
72 {FcitxKey_KP_Home, NC_(
"Key name",
"Keypad Home")},
73 {FcitxKey_KP_Left, NC_(
"Key name",
"Keypad Left")},
74 {FcitxKey_KP_Up, NC_(
"Key name",
"Keypad Up")},
75 {FcitxKey_KP_Right, NC_(
"Key name",
"Keypad Right")},
76 {FcitxKey_KP_Down, NC_(
"Key name",
"Keypad Down")},
77 {FcitxKey_KP_Page_Up, NC_(
"Key name",
"Keypad Page Up")},
78 {FcitxKey_KP_Page_Down, NC_(
"Key name",
"Keypad Page Down")},
79 {FcitxKey_KP_End, NC_(
"Key name",
"Keypad End")},
80 {FcitxKey_KP_Begin, NC_(
"Key name",
"Keypad Begin")},
81 {FcitxKey_KP_Insert, NC_(
"Key name",
"Keypad Insert")},
82 {FcitxKey_KP_Delete, NC_(
"Key name",
"Keypad Delete")},
83 {FcitxKey_KP_Equal, NC_(
"Key name",
"Keypad =")},
84 {FcitxKey_KP_Multiply, NC_(
"Key name",
"Keypad *")},
85 {FcitxKey_KP_Add, NC_(
"Key name",
"Keypad +")},
86 {FcitxKey_KP_Separator, NC_(
"Key name",
"Keypad ,")},
87 {FcitxKey_KP_Subtract, NC_(
"Key name",
"Keypad -")},
88 {FcitxKey_KP_Decimal, NC_(
"Key name",
"Keypad .")},
89 {FcitxKey_KP_Divide, NC_(
"Key name",
"Keypad /")},
90 {FcitxKey_KP_0, NC_(
"Key name",
"Keypad 0")},
91 {FcitxKey_KP_1, NC_(
"Key name",
"Keypad 1")},
92 {FcitxKey_KP_2, NC_(
"Key name",
"Keypad 2")},
93 {FcitxKey_KP_3, NC_(
"Key name",
"Keypad 3")},
94 {FcitxKey_KP_4, NC_(
"Key name",
"Keypad 4")},
95 {FcitxKey_KP_5, NC_(
"Key name",
"Keypad 5")},
96 {FcitxKey_KP_6, NC_(
"Key name",
"Keypad 6")},
97 {FcitxKey_KP_7, NC_(
"Key name",
"Keypad 7")},
98 {FcitxKey_KP_8, NC_(
"Key name",
"Keypad 8")},
99 {FcitxKey_KP_9, NC_(
"Key name",
"Keypad 9")},
100 {FcitxKey_Scroll_Lock, NC_(
"Key name",
"ScrollLock")},
101 {FcitxKey_Menu, NC_(
"Key name",
"Menu")},
102 {FcitxKey_Help, NC_(
"Key name",
"Help")},
103 {FcitxKey_Back, NC_(
"Key name",
"Back")},
104 {FcitxKey_Forward, NC_(
"Key name",
"Forward")},
105 {FcitxKey_Stop, NC_(
"Key name",
"Stop")},
106 {FcitxKey_Refresh, NC_(
"Key name",
"Refresh")},
107 {FcitxKey_AudioLowerVolume, NC_(
"Key name",
"Volume Down")},
108 {FcitxKey_AudioMute, NC_(
"Key name",
"Volume Mute")},
109 {FcitxKey_AudioRaiseVolume, NC_(
"Key name",
"Volume Up")},
110 {FcitxKey_AudioPlay, NC_(
"Key name",
"Media Play")},
111 {FcitxKey_AudioStop, NC_(
"Key name",
"Media Stop")},
112 {FcitxKey_AudioPrev, NC_(
"Key name",
"Media Previous")},
113 {FcitxKey_AudioNext, NC_(
"Key name",
"Media Next")},
114 {FcitxKey_AudioRecord, NC_(
"Key name",
"Media Record")},
115 {FcitxKey_AudioPause, NC_(
"Key name",
"Media Pause")},
116 {FcitxKey_HomePage, NC_(
"Key name",
"Home Page")},
117 {FcitxKey_Favorites, NC_(
"Key name",
"Favorites")},
118 {FcitxKey_Search, NC_(
"Key name",
"Search")},
119 {FcitxKey_Standby, NC_(
"Key name",
"Standby")},
120 {FcitxKey_OpenURL, NC_(
"Key name",
"Open URL")},
121 {FcitxKey_Mail, NC_(
"Key name",
"Launch Mail")},
122 {FcitxKey_Launch0, NC_(
"Key name",
"Launch (0)")},
123 {FcitxKey_Launch1, NC_(
"Key name",
"Launch (1)")},
124 {FcitxKey_Launch2, NC_(
"Key name",
"Launch (2)")},
125 {FcitxKey_Launch3, NC_(
"Key name",
"Launch (3)")},
126 {FcitxKey_Launch4, NC_(
"Key name",
"Launch (4)")},
127 {FcitxKey_Launch5, NC_(
"Key name",
"Launch (5)")},
128 {FcitxKey_Launch6, NC_(
"Key name",
"Launch (6)")},
129 {FcitxKey_Launch7, NC_(
"Key name",
"Launch (7)")},
130 {FcitxKey_Launch8, NC_(
"Key name",
"Launch (8)")},
131 {FcitxKey_Launch9, NC_(
"Key name",
"Launch (9)")},
132 {FcitxKey_LaunchA, NC_(
"Key name",
"Launch (A)")},
133 {FcitxKey_LaunchB, NC_(
"Key name",
"Launch (B)")},
134 {FcitxKey_LaunchC, NC_(
"Key name",
"Launch (C)")},
135 {FcitxKey_LaunchD, NC_(
"Key name",
"Launch (D)")},
136 {FcitxKey_LaunchE, NC_(
"Key name",
"Launch (E)")},
137 {FcitxKey_LaunchF, NC_(
"Key name",
"Launch (F)")},
138 {FcitxKey_MonBrightnessUp, NC_(
"Key name",
"Monitor Brightness Up")},
139 {FcitxKey_MonBrightnessDown,
140 NC_(
"Key name",
"Monitor Brightness Down")},
141 {FcitxKey_KbdLightOnOff, NC_(
"Key name",
"Keyboard Light On/Off")},
142 {FcitxKey_KbdBrightnessUp, NC_(
"Key name",
"Keyboard Brightness Up")},
143 {FcitxKey_KbdBrightnessDown,
144 NC_(
"Key name",
"Keyboard Brightness Down")},
145 {FcitxKey_PowerOff, NC_(
"Key name",
"Power Off")},
146 {FcitxKey_WakeUp, NC_(
"Key name",
"Wake Up")},
147 {FcitxKey_Eject, NC_(
"Key name",
"Eject")},
148 {FcitxKey_ScreenSaver, NC_(
"Key name",
"Screensaver")},
149 {FcitxKey_WWW, NC_(
"Key name",
"WWW")},
150 {FcitxKey_Sleep, NC_(
"Key name",
"Sleep")},
151 {FcitxKey_LightBulb, NC_(
"Key name",
"LightBulb")},
152 {FcitxKey_Shop, NC_(
"Key name",
"Shop")},
153 {FcitxKey_History, NC_(
"Key name",
"History")},
154 {FcitxKey_AddFavorite, NC_(
"Key name",
"Add Favorite")},
155 {FcitxKey_HotLinks, NC_(
"Key name",
"Hot Links")},
156 {FcitxKey_BrightnessAdjust, NC_(
"Key name",
"Adjust Brightness")},
157 {FcitxKey_Finance, NC_(
"Key name",
"Finance")},
158 {FcitxKey_Community, NC_(
"Key name",
"Community")},
159 {FcitxKey_AudioRewind, NC_(
"Key name",
"Media Rewind")},
160 {FcitxKey_BackForward, NC_(
"Key name",
"Back Forward")},
161 {FcitxKey_ApplicationLeft, NC_(
"Key name",
"Application Left")},
162 {FcitxKey_ApplicationRight, NC_(
"Key name",
"Application Right")},
163 {FcitxKey_Book, NC_(
"Key name",
"Book")},
164 {FcitxKey_CD, NC_(
"Key name",
"CD")},
165 {FcitxKey_Calculator, NC_(
"Key name",
"Calculator")},
166 {FcitxKey_Clear, NC_(
"Key name",
"Clear")},
167 {FcitxKey_Close, NC_(
"Key name",
"Close")},
168 {FcitxKey_Copy, NC_(
"Key name",
"Copy")},
169 {FcitxKey_Cut, NC_(
"Key name",
"Cut")},
170 {FcitxKey_Display, NC_(
"Key name",
"Display")},
171 {FcitxKey_DOS, NC_(
"Key name",
"DOS")},
172 {FcitxKey_Documents, NC_(
"Key name",
"Documents")},
173 {FcitxKey_Excel, NC_(
"Key name",
"Spreadsheet")},
174 {FcitxKey_Explorer, NC_(
"Key name",
"Browser")},
175 {FcitxKey_Game, NC_(
"Key name",
"Game")},
176 {FcitxKey_Go, NC_(
"Key name",
"Go")},
177 {FcitxKey_iTouch, NC_(
"Key name",
"iTouch")},
178 {FcitxKey_LogOff, NC_(
"Key name",
"Logoff")},
179 {FcitxKey_Market, NC_(
"Key name",
"Market")},
180 {FcitxKey_Meeting, NC_(
"Key name",
"Meeting")},
181 {FcitxKey_MenuKB, NC_(
"Key name",
"Keyboard Menu")},
182 {FcitxKey_MenuPB, NC_(
"Key name",
"Menu PB")},
183 {FcitxKey_MySites, NC_(
"Key name",
"My Sites")},
184 {FcitxKey_News, NC_(
"Key name",
"News")},
185 {FcitxKey_OfficeHome, NC_(
"Key name",
"Home Office")},
186 {FcitxKey_Option, NC_(
"Key name",
"Option")},
187 {FcitxKey_Paste, NC_(
"Key name",
"Paste")},
188 {FcitxKey_Phone, NC_(
"Key name",
"Phone")},
189 {FcitxKey_Reply, NC_(
"Key name",
"Reply")},
190 {FcitxKey_Reload, NC_(
"Key name",
"Reload")},
191 {FcitxKey_RotateWindows, NC_(
"Key name",
"Rotate Windows")},
192 {FcitxKey_RotationPB, NC_(
"Key name",
"Rotation PB")},
193 {FcitxKey_RotationKB, NC_(
"Key name",
"Rotation KB")},
194 {FcitxKey_Save, NC_(
"Key name",
"Save")},
195 {FcitxKey_Send, NC_(
"Key name",
"Send")},
196 {FcitxKey_Spell, NC_(
"Key name",
"Spellchecker")},
197 {FcitxKey_SplitScreen, NC_(
"Key name",
"Split Screen")},
198 {FcitxKey_Support, NC_(
"Key name",
"Support")},
199 {FcitxKey_TaskPane, NC_(
"Key name",
"Task Panel")},
200 {FcitxKey_Terminal, NC_(
"Key name",
"Terminal")},
201 {FcitxKey_Tools, NC_(
"Key name",
"Tools")},
202 {FcitxKey_Travel, NC_(
"Key name",
"Travel")},
203 {FcitxKey_Video, NC_(
"Key name",
"Video")},
204 {FcitxKey_Word, NC_(
"Key name",
"Word Processor")},
205 {FcitxKey_Xfer, NC_(
"Key name",
"XFer")},
206 {FcitxKey_ZoomIn, NC_(
"Key name",
"Zoom In")},
207 {FcitxKey_ZoomOut, NC_(
"Key name",
"Zoom Out")},
208 {FcitxKey_Away, NC_(
"Key name",
"Away")},
209 {FcitxKey_Messenger, NC_(
"Key name",
"Messenger")},
210 {FcitxKey_WebCam, NC_(
"Key name",
"WebCam")},
211 {FcitxKey_MailForward, NC_(
"Key name",
"Mail Forward")},
212 {FcitxKey_Pictures, NC_(
"Key name",
"Pictures")},
213 {FcitxKey_Music, NC_(
"Key name",
"Music")},
214 {FcitxKey_Battery, NC_(
"Key name",
"Battery")},
215 {FcitxKey_Bluetooth, NC_(
"Key name",
"Bluetooth")},
216 {FcitxKey_WLAN, NC_(
"Key name",
"Wireless")},
217 {FcitxKey_AudioForward, NC_(
"Key name",
"Media Fast Forward")},
218 {FcitxKey_AudioRepeat, NC_(
"Key name",
"Audio Repeat")},
219 {FcitxKey_AudioRandomPlay, NC_(
"Key name",
"Audio Random Play")},
220 {FcitxKey_Subtitle, NC_(
"Key name",
"Subtitle")},
221 {FcitxKey_AudioCycleTrack, NC_(
"Key name",
"Audio Cycle Track")},
222 {FcitxKey_Time, NC_(
"Key name",
"Time")},
223 {FcitxKey_Hibernate, NC_(
"Key name",
"Hibernate")},
224 {FcitxKey_View, NC_(
"Key name",
"View")},
225 {FcitxKey_TopMenu, NC_(
"Key name",
"Top Menu")},
226 {FcitxKey_PowerDown, NC_(
"Key name",
"Power Down")},
227 {FcitxKey_Suspend, NC_(
"Key name",
"Suspend")},
228 {FcitxKey_AudioMicMute, NC_(
"Key name",
"Microphone Mute")},
229 {FcitxKey_Red, NC_(
"Key name",
"Red")},
230 {FcitxKey_Green, NC_(
"Key name",
"Green")},
231 {FcitxKey_Yellow, NC_(
"Key name",
"Yellow")},
232 {FcitxKey_Blue, NC_(
"Key name",
"Blue")},
233 {FcitxKey_New, NC_(
"Key name",
"New")},
234 {FcitxKey_Open, NC_(
"Key name",
"Open")},
235 {FcitxKey_Find, NC_(
"Key name",
"Find")},
236 {FcitxKey_Undo, NC_(
"Key name",
"Undo")},
237 {FcitxKey_Redo, NC_(
"Key name",
"Redo")},
238 {FcitxKey_Print, NC_(
"Key name",
"Print Screen")},
239 {FcitxKey_Insert, NC_(
"Key name",
"Insert")},
240 {FcitxKey_Delete, NC_(
"Key name",
"Delete")},
241 {FcitxKey_Escape, NC_(
"Key name",
"Escape")},
242 {FcitxKey_Sys_Req, NC_(
"Key name",
"System Request")},
243 {FcitxKey_Select, NC_(
"Key name",
"Select")},
244 {FcitxKey_Kanji, NC_(
"Key name",
"Kanji")},
245 {FcitxKey_Muhenkan, NC_(
"Key name",
"Muhenkan")},
246 {FcitxKey_Henkan, NC_(
"Key name",
"Henkan")},
247 {FcitxKey_Romaji, NC_(
"Key name",
"Romaji")},
248 {FcitxKey_Hiragana, NC_(
"Key name",
"Hiragana")},
249 {FcitxKey_Katakana, NC_(
"Key name",
"Katakana")},
250 {FcitxKey_Hiragana_Katakana, NC_(
"Key name",
"Hiragana Katakana")},
251 {FcitxKey_Zenkaku, NC_(
"Key name",
"Zenkaku")},
252 {FcitxKey_Hankaku, NC_(
"Key name",
"Hankaku")},
253 {FcitxKey_Zenkaku_Hankaku, NC_(
"Key name",
"Zenkaku Hankaku")},
254 {FcitxKey_Touroku, NC_(
"Key name",
"Touroku")},
255 {FcitxKey_Massyo, NC_(
"Key name",
"Massyo")},
256 {FcitxKey_Kana_Lock, NC_(
"Key name",
"Kana Lock")},
257 {FcitxKey_Kana_Shift, NC_(
"Key name",
"Kana Shift")},
258 {FcitxKey_Eisu_Shift, NC_(
"Key name",
"Eisu Shift")},
259 {FcitxKey_Eisu_toggle, NC_(
"Key name",
"Eisu toggle")},
260 {FcitxKey_Codeinput, NC_(
"Key name",
"Code input")},
261 {FcitxKey_MultipleCandidate, NC_(
"Key name",
"Multiple Candidate")},
262 {FcitxKey_PreviousCandidate, NC_(
"Key name",
"Previous Candidate")},
263 {FcitxKey_Hangul, NC_(
"Key name",
"Hangul")},
264 {FcitxKey_Hangul_Start, NC_(
"Key name",
"Hangul Start")},
265 {FcitxKey_Hangul_End, NC_(
"Key name",
"Hangul End")},
266 {FcitxKey_Hangul_Hanja, NC_(
"Key name",
"Hangul Hanja")},
267 {FcitxKey_Hangul_Jamo, NC_(
"Key name",
"Hangul Jamo")},
268 {FcitxKey_Hangul_Romaja, NC_(
"Key name",
"Hangul Romaja")},
269 {FcitxKey_Hangul_Jeonja, NC_(
"Key name",
"Hangul Jeonja")},
270 {FcitxKey_Hangul_Banja, NC_(
"Key name",
"Hangul Banja")},
271 {FcitxKey_Hangul_PreHanja, NC_(
"Key name",
"Hangul PreHanja")},
272 {FcitxKey_Hangul_PostHanja, NC_(
"Key name",
"Hangul PostHanja")},
273 {FcitxKey_Hangul_Special, NC_(
"Key name",
"Hangul Special")},
274 {FcitxKey_Cancel, NC_(
"Key name",
"Cancel")},
275 {FcitxKey_Execute, NC_(
"Key name",
"Execute")},
276 {FcitxKey_TouchpadToggle, NC_(
"Key name",
"Touchpad Toggle")},
277 {FcitxKey_TouchpadOn, NC_(
"Key name",
"Touchpad On")},
278 {FcitxKey_TouchpadOff, NC_(
"Key name",
"Touchpad Off")},
279 {FcitxKey_VoidSymbol, NC_(
"Key name",
"Void Symbol")},
281 std::unordered_map<KeySym, const char *, EnumHash> result;
282 for (
const auto &item : keyname) {
283 result[item.key] = item.name;
288 const char *lookupName(KeySym sym) {
289 static const std::unordered_map<KeySym, const char *, EnumHash> map =
290 makeLookupKeyNameMap();
291 const auto *result = findValue(map, sym);
292 return result ? *result :
nullptr;
296 Key::Key(
const char *keyString) :
Key() {
299 const char *p = keyString;
300 const char *lastModifier = keyString;
301 const char *found =
nullptr;
303 #define _CHECK_MODIFIER(NAME, VALUE) \ 304 if ((found = strstr(p, NAME))) { \ 305 states |= KeyState::VALUE; \ 306 if (found + strlen(NAME) > lastModifier) { \ 307 lastModifier = found + strlen(NAME); \ 311 _CHECK_MODIFIER(
"CTRL_", Ctrl)
312 _CHECK_MODIFIER(
"Control+", Ctrl)
313 _CHECK_MODIFIER(
"ALT_", Alt)
314 _CHECK_MODIFIER(
"Alt+", Alt)
315 _CHECK_MODIFIER(
"SHIFT_", Shift)
316 _CHECK_MODIFIER(
"Shift+", Shift)
317 _CHECK_MODIFIER(
"SUPER_", Super)
318 _CHECK_MODIFIER(
"Super+", Super)
319 _CHECK_MODIFIER(
"HYPER_", Mod3)
320 _CHECK_MODIFIER(
"Hyper+", Mod3)
322 #undef _CHECK_MODIFIER 325 std::string_view keyValue = lastModifier;
328 keyValue.remove_prefix(1);
329 keyValue.remove_suffix(1);
330 std::from_chars(keyValue.data(), keyValue.data() + keyValue.size(),
345 std::vector<Key> keys;
346 keys.emplace_back(key.sym(), states);
347 if (key.states() & KeyState::Ctrl) {
348 if (key.sym() != FcitxKey_Control_R) {
349 keys.emplace_back(FcitxKey_Control_L, states);
351 if (key.sym() != FcitxKey_Control_L) {
352 keys.emplace_back(FcitxKey_Control_R, states);
355 if (key.states() & KeyState::Alt) {
356 if (key.sym() != FcitxKey_Alt_R && key.sym() != FcitxKey_Meta_R) {
357 keys.emplace_back(FcitxKey_Alt_L, states);
358 keys.emplace_back(FcitxKey_Meta_L, states);
360 if (key.sym() != FcitxKey_Alt_L && key.sym() != FcitxKey_Meta_L) {
361 keys.emplace_back(FcitxKey_Alt_R, states);
362 keys.emplace_back(FcitxKey_Meta_R, states);
365 if (key.states() & KeyState::Shift) {
366 if (key.sym() != FcitxKey_Shift_R) {
367 keys.emplace_back(FcitxKey_Shift_L, states);
369 if (key.sym() != FcitxKey_Shift_L) {
370 keys.emplace_back(FcitxKey_Shift_R, states);
373 if ((key.states() & KeyState::Super) || (key.states() & KeyState::Super2)) {
374 if (key.sym() != FcitxKey_Super_R && key.sym() != FcitxKey_Hyper_R) {
375 keys.emplace_back(FcitxKey_Super_L, states);
376 keys.emplace_back(FcitxKey_Hyper_L, states);
378 if (key.sym() != FcitxKey_Super_L && key.sym() != FcitxKey_Hyper_L) {
379 keys.emplace_back(FcitxKey_Super_R, states);
380 keys.emplace_back(FcitxKey_Hyper_R, states);
388 auto states = states_ &
KeyStates({KeyState::Ctrl_Alt_Shift,
389 KeyState::Super, KeyState::Mod3});
390 if (states_.test(KeyState::Super2)) {
391 states |= KeyState::Super;
396 return key.states_ == states && key.code_ == code_;
399 if (key.sym() == FcitxKey_None || key.sym() == FcitxKey_VoidSymbol) {
408 return (key.sym_ == sym_ && key.states_ == states) ||
409 (key.sym_ == keyAlt.sym_ && key.states_ == keyAlt.states_);
412 return (key.sym_ == sym_ && key.states_ == states);
416 return !states_ && ((sym_ >= FcitxKey_0 && sym_ <= FcitxKey_9) ||
417 (sym_ >= FcitxKey_KP_0 && sym_ <= FcitxKey_KP_9));
424 if (sym_ >= FcitxKey_0 && sym_ <= FcitxKey_9) {
425 return sym_ - FcitxKey_0;
427 if (sym_ >= FcitxKey_KP_0 && sym_ <= FcitxKey_KP_9) {
428 return sym_ - FcitxKey_KP_0;
434 auto filteredStates =
436 KeyStates({KeyState::Ctrl_Alt_Shift, KeyState::Super, KeyState::Mod3});
437 if (filteredStates != states) {
443 return (idx + 9) % 10;
449 return !states_ && sym_ >= FcitxKey_A && sym_ <= FcitxKey_Z;
453 return !states_ && sym_ >= FcitxKey_a && sym_ <= FcitxKey_z;
459 return !states_ && sym_ >= FcitxKey_space && sym_ <= FcitxKey_asciitilde;
463 return (sym_ == FcitxKey_Control_L || sym_ == FcitxKey_Control_R ||
464 sym_ == FcitxKey_Meta_L || sym_ == FcitxKey_Meta_R ||
465 sym_ == FcitxKey_Alt_L || sym_ == FcitxKey_Alt_R ||
466 sym_ == FcitxKey_Super_L || sym_ == FcitxKey_Super_R ||
467 sym_ == FcitxKey_Hyper_L || sym_ == FcitxKey_Hyper_R ||
468 sym_ == FcitxKey_Shift_L || sym_ == FcitxKey_Shift_R);
472 return ((sym_ == FcitxKey_Left || sym_ == FcitxKey_Right ||
473 sym_ == FcitxKey_Up || sym_ == FcitxKey_Down ||
474 sym_ == FcitxKey_Page_Up || sym_ == FcitxKey_Page_Down ||
475 sym_ == FcitxKey_Home || sym_ == FcitxKey_End ||
476 sym_ == FcitxKey_KP_Left || sym_ == FcitxKey_KP_Right ||
477 sym_ == FcitxKey_KP_Up || sym_ == FcitxKey_KP_Down ||
478 sym_ == FcitxKey_KP_Page_Up || sym_ == FcitxKey_KP_Page_Down ||
479 sym_ == FcitxKey_KP_Home || sym_ == FcitxKey_KP_End) &&
480 (states_ == KeyState::Ctrl || states_ == KeyState::Ctrl_Shift ||
481 states_ == KeyState::Shift || states_ == KeyState::NoState));
485 return ((sym_ >= FcitxKey_KP_Multiply && sym_ <= FcitxKey_KP_9) ||
486 (sym_ >= FcitxKey_KP_F1 && sym_ <= FcitxKey_KP_Delete) ||
487 sym_ == FcitxKey_KP_Space || sym_ == FcitxKey_KP_Tab ||
488 sym_ == FcitxKey_KP_Enter || sym_ == FcitxKey_KP_Equal);
498 if (key.sym_ == FcitxKey_ISO_Left_Tab) {
499 key.sym_ = FcitxKey_Tab;
504 key.states_ &
KeyStates({KeyState::Ctrl_Alt_Shift, KeyState::Super,
505 KeyState::Mod3, KeyState::Super2});
506 if (key.states_.test(KeyState::Super2)) {
507 key.states_ = key.states_.unset(KeyState::Super2);
508 key.states_ |= KeyState::Super;
511 if (key.states_ != KeyState::Shift &&
Key(key.sym_).
isLAZ()) {
512 key.sym_ =
static_cast<KeySym
>(key.sym_ + FcitxKey_A - FcitxKey_a);
520 if (key.states_ == KeyState::Shift) {
524 if ((key.states_ & KeyState::Shift) &&
527 key.sym_ != FcitxKey_space && key.sym_ != FcitxKey_Return &&
528 key.sym_ != FcitxKey_Tab) ||
529 (key.sym_ >= FcitxKey_KP_0 && key.sym_ <= FcitxKey_KP_9))) {
530 key.states_ ^= KeyState::Shift;
540 return (sym_ != FcitxKey_None && sym_ != FcitxKey_VoidSymbol) || code_ != 0;
546 if (code_ && sym_ == FcitxKey_None) {
548 key += std::to_string(code_);
552 if (sym == FcitxKey_None) {
553 return std::string();
556 if (sym == FcitxKey_ISO_Left_Tab) {
563 return std::string();
567 auto states = states_;
572 #define _APPEND_MODIFIER_STRING(STR, VALUE) \ 573 if (states & VALUE) { \ 578 _APPEND_MODIFIER_STRING(
"Control", KeyState::Ctrl)
579 _APPEND_MODIFIER_STRING(
"Alt", KeyState::Alt)
580 _APPEND_MODIFIER_STRING(
"Shift", KeyState::Shift)
581 _APPEND_MODIFIER_STRING(
"Super",
582 (
KeyStates{KeyState::Super, KeyState::Super2}))
583 _APPEND_MODIFIER_STRING(
"Hyper",
584 (
KeyStates{KeyState::Hyper, KeyState::Hyper2}))
586 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Control"), KeyState::Ctrl)
587 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Alt"), KeyState::Alt)
588 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Shift"), KeyState::Shift)
589 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Super"),
590 (
KeyStates{KeyState::Super, KeyState::Super2}))
591 _APPEND_MODIFIER_STRING(C_(
"Key name",
"Hyper"),
592 (
KeyStates{KeyState::Hyper, KeyState::Hyper2}))
595 #undef _APPEND_MODIFIER_STRING 603 case FcitxKey_Control_L:
604 case FcitxKey_Control_R:
605 return KeyState::Ctrl;
608 case FcitxKey_Meta_L:
609 case FcitxKey_Meta_R:
610 return KeyState::Alt;
611 case FcitxKey_Shift_L:
612 case FcitxKey_Shift_R:
613 return KeyState::Shift;
614 case FcitxKey_Super_L:
615 case FcitxKey_Super_R:
616 case FcitxKey_Hyper_L:
617 case FcitxKey_Hyper_R:
618 return KeyState::Super;
625 const auto *value = std::lower_bound(
626 keyValueByNameOffset,
627 keyValueByNameOffset + FCITX_ARRAY_SIZE(keyValueByNameOffset),
628 keyString, [](
const uint32_t &idx,
const std::string &str) {
629 return keyNameList[&idx - keyValueByNameOffset] < str;
633 keyValueByNameOffset + FCITX_ARRAY_SIZE(keyValueByNameOffset) &&
634 keyString == keyNameList[value - keyValueByNameOffset]) {
635 return static_cast<KeySym
>(*value);
638 const auto *compat = std::lower_bound(
640 keyNameListCompat + FCITX_ARRAY_SIZE(keyNameListCompat), keyString,
641 [](
const KeyNameListCompat &c,
const std::string &str) {
644 if (compat != keyNameListCompat + FCITX_ARRAY_SIZE(keyNameListCompat) &&
645 compat->name == keyString) {
653 return static_cast<KeySym
>(keyString[0]);
659 return FcitxKey_None;
664 if (
const auto *name = lookupName(sym)) {
665 return C_(
"Key name", name);
669 if (charutils::isprint(code)) {
677 const KeyNameOffsetByValue *result = std::lower_bound(
678 keyNameOffsetByValue,
679 keyNameOffsetByValue + FCITX_ARRAY_SIZE(keyNameOffsetByValue), sym,
680 [](
const KeyNameOffsetByValue &item, KeySym key) {
681 return item.sym < key;
684 keyNameOffsetByValue + FCITX_ARRAY_SIZE(keyNameOffsetByValue) &&
685 result->sym == sym) {
686 return keyNameList[result->offset];
688 return std::string();
692 const auto &tab = unicode_to_keysym_tab();
694 int max = tab.size() - 1;
698 if ((unicode >= 0x0020 && unicode <= 0x007e) ||
699 (unicode >= 0x00a0 && unicode <= 0x00ff))
700 return static_cast<KeySym
>(unicode);
703 if ((unicode >= (FcitxKey_BackSpace & 0x7f) &&
704 unicode <= (FcitxKey_Clear & 0x7f)) ||
705 unicode == (FcitxKey_Return & 0x7f) ||
706 unicode == (FcitxKey_Escape & 0x7f)) {
707 return static_cast<KeySym
>(unicode | 0xff00);
709 if (unicode == (FcitxKey_Delete & 0x7f)) {
710 return FcitxKey_Delete;
714 if ((unicode >= 0xd800 && unicode <= 0xdfff) ||
715 (unicode >= 0xfdd0 && unicode <= 0xfdef) || unicode > 0x10ffff ||
716 (unicode & 0xfffe) == 0xfffe) {
717 return FcitxKey_None;
722 mid = (min + max) / 2;
723 if (tab[mid].ucs < unicode) {
725 }
else if (tab[mid].ucs > unicode) {
729 return static_cast<KeySym
>(tab[mid].keysym);
737 return static_cast<KeySym
>(unicode | 0x01000000);
743 sizeof(keysym_to_unicode_tab) /
sizeof(keysym_to_unicode_tab[0]) - 1;
747 if ((sym >= 0x0020 && sym <= 0x007e) || (sym >= 0x00a0 && sym <= 0x00ff)) {
752 if (sym == FcitxKey_KP_Space) {
753 return FcitxKey_space & 0x7f;
757 if ((sym >= FcitxKey_BackSpace && sym <= FcitxKey_Clear) ||
758 (sym >= FcitxKey_KP_Multiply && sym <= FcitxKey_KP_9) ||
759 sym == FcitxKey_Return || sym == FcitxKey_Escape ||
760 sym == FcitxKey_Delete || sym == FcitxKey_KP_Tab ||
761 sym == FcitxKey_KP_Enter || sym == FcitxKey_KP_Equal) {
771 if (0x0100d800 <= sym && sym <= 0x0100dfff) {
780 if (0x01000000 <= sym && sym <= 0x0110ffff) {
781 const uint32_t code = sym - 0x01000000;
790 mid = (min + max) / 2;
791 if (keysym_to_unicode_tab[mid].keysym < sym) {
793 }
else if (keysym_to_unicode_tab[mid].keysym > sym) {
797 return keysym_to_unicode_tab[mid].ucs;
814 std::vector<Key> keyList;
816 auto lastPos = str.find_first_not_of(FCITX_WHITESPACE, 0);
817 auto pos = str.find_first_of(FCITX_WHITESPACE, lastPos);
819 while (std::string::npos != pos || std::string::npos != lastPos) {
820 Key key(str.substr(lastPos, pos - lastPos));
822 if (key.sym() != FcitxKey_None) {
823 keyList.push_back(key);
825 lastPos = str.find_first_not_of(FCITX_WHITESPACE, pos);
826 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.
bool endsWith(std::string_view str, std::string_view suffix)
Check if a string ends with a suffix.
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.
bool startsWith(std::string_view str, std::string_view prefix)
Check if a string starts with a prefix.
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.