Re: Sending arbitrary keysyms/Unicode without xcb_change_keyboard_mapping()
Uli Schlachter <[email protected]> Mon, 23 Sep 2024 15:58:53 +0200
| Newsgroups | gmane.comp.freedesktop.xcb |
|---|---|
| Message-ID | <[email protected]> |
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 important=
ly, sequences of codepoints) to the X11 application/window currently in f=
ocus.
>=20
> I know this is possible because "every possible Unicode character has a=
lready a keysym string defined algorithmically" (source:=C2=A0/usr/includ=
e/X11/keysymdef.h).
But a keysym is not what one enters, as you noticed.
>=20
>=20
>=20
> To send, eg., Unicode codepoint U+1f3f4, I'm doing:
>=20
>=20
>=20
>=20
>=20
> #define X11_UNICODE_BASE=C2=A0 0x01000000
>=20
> xcb_change_keyboard_mapping(connection, 1,255, 1,(const xcb_keysym_t[])=
{X11_UNICODE_BASE|0x01f3f4});
>=20
> xcb_send_key_press(connection, screen->root, get_input_focus_reply->foc=
us, 255);
You are using X11 core input. Since 1996, there is X keyboard extension=20
that, well, "can do things". See [1] (and no, I do not have a better=20
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 de=
sired Unicode codepoint.
Random idea from Wikipedia [2]: Input the unicode codepoint as a hex=20
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=20
does not use XKB / libxkbcommon? I do not have gnome-terminal around,=20
but I would expect this to work there.
[...]
> What would much more sense is to do something like:
>=20
>=20
>=20
>=20
>=20
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x01f3f4);
>=20
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0067);
>=20
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0062);
>=20
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0065);
>=20
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e006e);
>=20
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0067);
>=20
> xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e007f);
>=20
>=20
>=20
>=20
>=20
> without the freeze that multiple calls to=C2=A0xcb_change_keyboard_mapp=
ing() cause.
>=20
>=20
>=20
> So, how can I do that?
I don't think that's possible. X11 keyboard input works by pressing keys=20
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=20
might be to use the XTest extension [3]. That does not solve any of your=20
problems, but at least that way XKB-using applications get the events in=20
the format they expect and not as core events. This also has a higher=20
chance of working with multiple, different keyboards attached (see=20
output of e.g. "xinput list" for how many input devices your X11 server=20
announced to application; in normal input processing, the app can see=20
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]:=20
https://en.wikipedia.org/wiki/Unicode_input#In_X11_(Linux_and_other_Unix_=
variants_including_ChromeOS)
[3]:=20
https://www.x.org/releases/X11R7.7/doc/xextproto/xtest.html#Server_Reques=
ts
--=20
I'd be delighted to offer any advice I can. When I have some, I'll let=20
you know.