And the behavior is not the same as when I choose "Insert Text by Pasting".
Here is what I've observed:
Insert Text by Typing: Works everywhere except in Spotlight and the terminal.
Insert Text by Pasting: Works everywhere except in Gmail's compose window, where, for some reason, pasting the emoji moves the cursor to the beginning of the line.
So something different is definitely happening.
May I know what is the difference in BTT when using these two modes with an emoji? How is BTT trying to insert them in each case?
ah true I once added basic support for Emoji when typing via a macOS function CGEventKeyboardSetUnicodeString. However Apple's docs specifically mention that apps might choose to ignore this.
/* Set the Unicode string associated with a keyboard event.
By default, the system translates the virtual key code in a keyboard
event into a Unicode string based on the keyboard ID in the event source.
This function allows you to manually override this string. Note that
application frameworks may ignore the Unicode string in a keyboard event
and do their own translation based on the virtual keycode and perceived
event state. */
The difference is:
when inserting text by pasting, BTT copies the text to the clipboard and then sends a paste command to the app (e.g. cmd+v)
when inserting text by typing BTT actually generates key events wherever possible (and falls back to the CGEventKeyboardSetUnicodeString for characters that can not be represented as a key press - but apps might choose to ignore that..
How does BTT determine whether a unicode character can be represented as a key press or not? I have my own keyboard layout, with 48 character keys, 16 modifier combinations and two dead key states, which means 1536 different unicode symbols. Add 128 different diacritics, combinable on each of the 1536 symbols...
The combining results are technically two characters, but they're still generated by a keypress. That means I can generate almost 200,000 symbols with a key press...
It just uses CGEventKeyboardSetUnicodeString for these and let's macOS handle the work of figuring out the internals
I think I figured out why some apps like terminal didn't accept emoji. @luisherranz could you check whether 5.585 alpha (uploading now) works in all apps?
So, basically that means that if MacOS can't generate the symbols from key presses (and in my case it can for all 200,000 symbols), the CGEventKeyboardSetUnicodeString fallback will be used?
So the "Insert Text..." actions are actually sending key presses, and not text (as the action name would lead you to believe)? Does that mean that the same action would send a different string (but the same keycodes) if I change the keyboard layout?
But in any case it will type or paste the same string for all keyboard layouts.
Maybe a misunderstanding due to my previous message: CGEventKeyboardSetUnicodeString is used to produce a keypress
But that would mean different key presses for different layouts? You said that BTT will send key events "when possible". The ? on a US keyboard is β§ + key code 44, but the same ? on a Swedish keyboard is β§ + key code 27. So BTT would need to generate different key events depending on what layout is active?
Sorry for hijacking this thread with this keyboard nerdery, but this is interesting.
I guess you are letting MacOS figure that out for you. So that means if I put a "κ" into that text box, and I'm using my 200k keyboard layout, BTT would ask MacOS "what key code is used to produce a κ?" and MacOS would search through the 200k options and come up with "Dead key state #1, Caps Lock on, Shift down, Option down, Key code 35"?
However in most situations BTT doesn't need to create the low level key events with the correct key codes itself - when posting key events to a session event tap it is enough to use CGEventKeyboardSetUnicodeString and macOS will figure out the rest. (There are some rare situations where BTT needs to post to a HID event tap, in that case it tries to figure out the key codes itself, but limits to standard ASCII characters)
Funny thing, I was testing this out myself in a testing swift app after you mentioned the use of CGEventKeyboardSetUnicodeString and I was able to make it work in both the terminal and spotlight using this code:
let utf16Chars = Array(emoji.utf16)
if let keyDownEvent = CGEvent(keyboardEventSource: source, virtualKey: 0, keyDown: true) {
keyDownEvent.keyboardSetUnicodeString(stringLength: utf16Chars.count, unicodeString: utf16Chars)
keyDownEvent.post(tap: .cghidEventTap)
}
if let keyUpEvent = CGEvent(keyboardEventSource: source, virtualKey: 0, keyDown: false) {
keyUpEvent.keyboardSetUnicodeString(stringLength: utf16Chars.count, unicodeString: utf16Chars)
keyUpEvent.post(tap: .cghidEventTap)
}
but... I couldn't make it work in Gmail. It still moves the cursor to the beginning of the line for some reason.
BTT 5.585 alpha does work on the terminal, spotlight and Gmail
I guess this makes sense, since the key code -> symbol translation is just a plain XML file. Search the file for "κ" (or Ꝑ / Ꝑ) and check the XML context, and you have your key code / modifier / state combination.
There could be several "κ" in the keyboard layout definition, but it doesn't really matter which one is chosen by MacOS in this case.