Skip to content

Commit f7f86f3

Browse files
authored
recover Alt+(Shift+)key before sending to fcitx (#273)
1 parent 03b68e9 commit f7f86f3

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

keycode/keycode.cpp

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,65 @@ static struct {
196196
{OSX_VK_SHIFT_R, 54},
197197
};
198198

199+
static struct {
200+
uint32_t osxKeycode;
201+
char asciiChar;
202+
char shiftedAsciiChar;
203+
} char_mappings[] = {
204+
// alphabet
205+
{OSX_VK_A, 'a', 'A'},
206+
{OSX_VK_B, 'b', 'B'},
207+
{OSX_VK_C, 'c', 'C'},
208+
{OSX_VK_D, 'd', 'D'},
209+
{OSX_VK_E, 'e', 'E'},
210+
{OSX_VK_F, 'f', 'F'},
211+
{OSX_VK_G, 'g', 'G'},
212+
{OSX_VK_H, 'h', 'H'},
213+
{OSX_VK_I, 'i', 'I'},
214+
{OSX_VK_J, 'j', 'J'},
215+
{OSX_VK_K, 'k', 'K'},
216+
{OSX_VK_L, 'l', 'L'},
217+
{OSX_VK_M, 'm', 'M'},
218+
{OSX_VK_N, 'n', 'N'},
219+
{OSX_VK_O, 'o', 'O'},
220+
{OSX_VK_P, 'p', 'P'},
221+
{OSX_VK_Q, 'q', 'Q'},
222+
{OSX_VK_R, 'r', 'R'},
223+
{OSX_VK_S, 's', 'S'},
224+
{OSX_VK_T, 't', 'T'},
225+
{OSX_VK_U, 'u', 'U'},
226+
{OSX_VK_V, 'v', 'V'},
227+
{OSX_VK_W, 'w', 'W'},
228+
{OSX_VK_X, 'x', 'X'},
229+
{OSX_VK_Y, 'y', 'Y'},
230+
{OSX_VK_Z, 'z', 'Z'},
231+
232+
// number row with shift mappings
233+
{OSX_VK_KEY_0, '0', ')'},
234+
{OSX_VK_KEY_1, '1', '!'},
235+
{OSX_VK_KEY_2, '2', '@'},
236+
{OSX_VK_KEY_3, '3', '#'},
237+
{OSX_VK_KEY_4, '4', '$'},
238+
{OSX_VK_KEY_5, '5', '%'},
239+
{OSX_VK_KEY_6, '6', '^'},
240+
{OSX_VK_KEY_7, '7', '&'},
241+
{OSX_VK_KEY_8, '8', '*'},
242+
{OSX_VK_KEY_9, '9', '('},
243+
244+
// symbols with shift
245+
{OSX_VK_BACKQUOTE, '`', '~'},
246+
{OSX_VK_BACKSLASH, '\\', '|'},
247+
{OSX_VK_BRACKET_LEFT, '[', '{'},
248+
{OSX_VK_BRACKET_RIGHT, ']', '}'},
249+
{OSX_VK_COMMA, ',', '<'},
250+
{OSX_VK_DOT, '.', '>'},
251+
{OSX_VK_EQUAL, '=', '+'},
252+
{OSX_VK_MINUS, '-', '_'},
253+
{OSX_VK_QUOTE, '\'', '"'},
254+
{OSX_VK_SEMICOLON, ';', ':'},
255+
{OSX_VK_SLASH, '/', '?'},
256+
};
257+
199258
static struct {
200259
uint32_t osxModifier;
201260
fcitx::KeyState fcitxModifier;
@@ -215,11 +274,21 @@ fcitx::KeySym osx_unicode_to_fcitx_keysym(uint32_t unicode,
215274
return pair.sym;
216275
}
217276
}
277+
// macOS sends special unicode for Alt+(Shift+) non-whitespace key thus can't match any configured hotkey in fcitx.
278+
// So we revert unicode to ascii, which doesn't change the committing special char behavior if rejected by fcitx.
279+
if ((osxModifiers & ~OSX_MODIFIER_SHIFT) == OSX_MODIFIER_OPTION) {
280+
for (const auto &pair : char_mappings) {
281+
if (pair.osxKeycode == osxKeycode) {
282+
unicode = (osxModifiers & OSX_MODIFIER_SHIFT) ? pair.shiftedAsciiChar : pair.asciiChar;
283+
break;
284+
}
285+
}
286+
}
218287
// Send capital keysym when shift is pressed (bug #101)
219288
// This is for Squirrel compatibility:
220289
// Squirrel recognizes Control+Shift+F and Control+Shift+0
221290
// but not Control+Shift+f and Control+Shift+parenright
222-
if ((unicode >= 'a') && (unicode <= 'z') &&
291+
else if ((unicode >= 'a') && (unicode <= 'z') &&
223292
(osxModifiers & OSX_MODIFIER_SHIFT)) {
224293
unicode = unicode - 'a' + 'A';
225294
}

tests/testkey.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "fcitx-utils/keysym.h"
12
#include "fcitx-utils/log.h"
23
#include "keycode.h"
34

@@ -8,6 +9,11 @@ void test_osx_to_fcitx() {
89
FCITX_ASSERT(osx_unicode_to_fcitx_keysym('a', 0, 0) == FcitxKey_a);
910
FCITX_ASSERT(osx_unicode_to_fcitx_keysym('a', OSX_MODIFIER_SHIFT, 0) ==
1011
FcitxKey_A);
12+
FCITX_ASSERT(osx_unicode_to_fcitx_keysym(161 /* ¡ */, OSX_MODIFIER_OPTION,
13+
OSX_VK_KEY_1) == FcitxKey_1);
14+
FCITX_ASSERT(osx_unicode_to_fcitx_keysym(
15+
8260 /**/, OSX_MODIFIER_SHIFT | OSX_MODIFIER_OPTION,
16+
OSX_VK_KEY_1) == FcitxKey_exclam);
1117

1218
FCITX_ASSERT(osx_keycode_to_fcitx_keycode(OSX_VK_KEY_0) == 11 + 8);
1319
FCITX_ASSERT(osx_keycode_to_fcitx_keycode(OSX_VK_KEYPAD_0) == 82 + 8);

0 commit comments

Comments
 (0)