Sending arbitrary keysyms/Unicode without xcb_change_keyboard_mapping()
Uli Schlachter
psychon at znc.in
Mon Sep 23 13:58:53 UTC 2024
Hi,
first: Keyboard input in X11 is "fun".
Am 22.09.24 um 11:54 schrieb Diego Alonso Cortez:
[...]
> I'm trying to send arbitrary Unicode codepoints (and, just as importantly, sequences of codepoints) to the X11 application/window currently in focus.
>
> I know this is possible because "every possible Unicode character has already a keysym string defined algorithmically" (source: /usr/include/X11/keysymdef.h).
But a keysym is not what one enters, as you noticed.
>
>
>
> To send, eg., Unicode codepoint U+1f3f4, I'm doing:
>
>
>
>
>
> #define X11_UNICODE_BASE 0x01000000
>
> xcb_change_keyboard_mapping(connection, 1,255, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x01f3f4});
>
> xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 255);
You are using X11 core input. Since 1996, there is X keyboard extension
that, well, "can do things". See [1] (and no, I do not have a better
link than that and I feel like I do not know enough about XKB).
> where I'm remapping keycode 255 (last X11 keycode) on-the-fly to the desired Unicode codepoint.
Random idea from Wikipedia [2]: Input the unicode codepoint as a hex
sequence. I just tried it with GVim and the described method works.
Of course, this does not work with XTerm nor urxvt. I guess because they
does not use XKB / libxkbcommon? I do not have gnome-terminal around,
but I would expect this to work there.
[...]
> What would much more sense is to do something like:
>
>
>
>
>
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x01f3f4);
>
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0067);
>
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0062);
>
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0065);
>
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e006e);
>
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0067);
>
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e007f);
>
>
>
>
>
> without the freeze that multiple calls to xcb_change_keyboard_mapping() cause.
>
>
>
> So, how can I do that?
I don't think that's possible. X11 keyboard input works by pressing keys
on the keyboard (identified by their keycode), not unicode symbols.
(Also, your code only presses the keys but never releases them)
Another option than sending "weird" keyboard events directly to programs
might be to use the XTest extension [3]. That does not solve any of your
problems, but at least that way XKB-using applications get the events in
the format they expect and not as core events. This also has a higher
chance of working with multiple, different keyboards attached (see
output of e.g. "xinput list" for how many input devices your X11 server
announced to application; in normal input processing, the app can see
which event some input originated from).
I hope this somewhat helps. Sorry for the "X11 does not really allow that".
Cheers,
Uli
[1]: https://en.wikipedia.org/wiki/X_keyboard_extension
[2]:
https://en.wikipedia.org/wiki/Unicode_input#In_X11_(Linux_and_other_Unix_variants_including_ChromeOS)
[3]:
https://www.x.org/releases/X11R7.7/doc/xextproto/xtest.html#Server_Requests
--
I'd be delighted to offer any advice I can. When I have some, I'll let
you know.
More information about the Xcb
mailing list