Skip to content

Commit 7236ff3

Browse files
committed
Support Unicode Characters for .typeString()
- rudimentary UTF-8 parsing - tested with Chinese characters - doesn't work with emojis yet - tested on mac but not other platforms
1 parent 6f8d2b6 commit 7236ff3

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

src/keypress.c

+35-4
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,13 @@ void tapKey(char c, MMKeyFlags flags)
191191
}
192192

193193
#if defined(IS_MACOSX)
194-
void toggleUniKey(char c, const bool down)
194+
void toggleUnicodeKey(UniChar ch, const bool down)
195195
{
196196
/* This function relies on the convenient
197197
* CGEventKeyboardSetUnicodeString(), which allows us to not have to
198198
* convert characters to a keycode, but does not support adding modifier
199199
* flags. It is therefore only used in typeString() and typeStringDelayed()
200200
* -- if you need modifier keys, use the above functions instead. */
201-
UniChar ch = (UniChar)c; /* Convert to unsigned char */
202-
203201
CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, 0, down);
204202
if (keyEvent == NULL) {
205203
fputs("Could not create keyboard event.\n", stderr);
@@ -211,6 +209,12 @@ void toggleUniKey(char c, const bool down)
211209
CGEventPost(kCGSessionEventTap, keyEvent);
212210
CFRelease(keyEvent);
213211
}
212+
213+
void toggleUniKey(char c, const bool down)
214+
{
215+
UniChar ch = (UniChar)c; /* Convert to unsigned char */
216+
toggleUnicodeKey(ch, down);
217+
}
214218
#else
215219
#define toggleUniKey(c, down) toggleKey(c, down, MOD_NONE)
216220
#endif
@@ -223,8 +227,35 @@ static void tapUniKey(char c)
223227

224228
void typeString(const char *str)
225229
{
230+
uint c, c1, c2, c3, n;
231+
226232
while (*str != '\0') {
227-
tapUniKey(*str++);
233+
c = *str++;
234+
235+
// warning, the following utf8 decoder
236+
// doesn't perform validation
237+
if (c <= 0x7F) {
238+
// 0xxxxxxx one byte
239+
n = c;
240+
} else if ((c & 0xE0) == 0xC0) {
241+
// 110xxxxx two bytes
242+
c1 = (*str++) & 0x3F;
243+
n = ((c & 0x1F) << 6) | c1;
244+
} else if ((c & 0xF0) == 0xE0) {
245+
// 1110xxxx three bytes
246+
c1 = (*str++) & 0x3F;
247+
c2 = (*str++) & 0x3F;
248+
n = ((c & 0x0F) << 12) | (c1 << 6) | c2;
249+
} else if ((c & 0xF8) == 0xF0) {
250+
// 11110xxx four bytes
251+
c1 = (*str++) & 0x3F;
252+
c2 = (*str++) & 0x3F;
253+
c3 = (*str++) & 0x3F;
254+
n = ((c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
255+
}
256+
257+
toggleUnicodeKey(n, true);
258+
toggleUnicodeKey(n, false);
228259
}
229260
}
230261

0 commit comments

Comments
 (0)