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