@@ -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+
199258static 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 }
0 commit comments