In case someone wonders what's "special" about it:
user perspective: As far as I know, it's the only tool offering somewhat reliable emoji input using faked X11 keyboard events. "x11-emoji-picker" comes close, but delegates faking events to "xdotool", with weird consequences like having to restart it to direct emojis to a different window ;)
hacker perspective: It directly integrates xcb in a different event loop (here based on pselect()) and actually works – xcb is IMHO pretty great except for pretty much enforcing its own async model, internally using poll() and reading from the X server into buffers at many occassions, hidden from the consumer. If all your app does is communicate with the X server, you just happily use xcb's model. As soon as you need different things (e.g. local timers), you have a problem. The typical way to address that is dedicating another thread to xcb (AFAIK also done that way by toolkits offering an X11 backend). I hated that idea enough to be stubborn about doing it directly in my main thread, and with quite some trial-and-error, finally succeeded.
Not sure you really mean the compose mechanism provided by Xlib (and xkbcommon etc ...)? If so, this wouldn't work for all these emojis that are represented by grapheme clusters, ZWJ-sequences or are just "qualified". The result of a compose sequence is limited to a single "key symbol", which can only encode a single unicode codepoint.
Even for those emojis consisting of a singe codepoint, it would really miss the point. There are LOTS of emojis available, an emoji keyboard (or emoji picker) shows them organized in groups and allows searching for them.
One of the major flaws in X11 is its poorly designed keyboard input system. When a key is pressed, the keypress event sends a "keycode" - an 8-bit number that references the current layout. This means you're limited to injecting characters that are present in the current layout.
The implications of this design are frustrating. For instance, if you're connecting to a remote system via VNC and the client and server have different keyboard layouts, you'll run into all sorts of issues. Similarly, how do you create an on-screen keyboard that can inject keypresses for characters not available in the current layout? And what if you want to programmatically send some text, but the user has the wrong layout active? It's a mess.
I guess because of this in Debian most of characters in on-screen keyboard didn't work (they "fixed" it by showing only characters present in active layouts instead of fixing the root issue).
The common workaround for this is an ugly hack: you modify the keyboard layout, find unused spots, add desired characters, send key press event and restore the keyboard layout back. See the code: [2]
Also, Wayland which was supposed to get rid of legacy problems, seems to have inherited this ugly design. Also, there seem to be no sane API for managing layouts or switching them programatically, or subscribing to layout change event. Also, you cannot use modifiers like Ctrl to switch layouts because then combinations like Ctrl + C stop working. Keyboard APIs on Linux are broken in the worst way possible since beginning, probably because most developers use only ASCII and do not have experience using multiple layouts.
A better idea would be to allow to send arbitrary Unicode strings and maybe integrate regular input and IME input (input system for typing Asian characters).
> Also, there seem to be no sane API for managing layouts or switching them programatically, or subscribing to layout change event
X11 has XkbMapNotify/XkbStateNotify.
Wayland has a wl_keyboard.keymap event.
> A better idea would be to allow to send arbitrary Unicode strings and maybe integrate regular input and IME input (input system for typing Asian characters).
Not particularly, the difficulty here is that some clients want text input, and some clients really do want key events (e.g. think games where holding W does not really have much to do with the Unicode code point 'w'). This was discussed for a long time, and the current design was decided as the best option.
IME systems do exist and already work just fine; they are integrated client-side. IME systems cannot really be integrated into the protocol since many of them involve custom UI.
> Not particularly, the difficulty here is that some clients want text input, and some clients really do want key events
I understand this point. For this case it makes sense to send both key code (what character does the key map in Latin layout) and translated code (which characters will be printed when key is pressed in current layout). It seems an easier solution than broadcast large structures to every client and let them have each own implementation for translating codes.
Regarding IME, I meant not integrating IME client into a Wayland server but instead unify the API and events that IME uses to insert text with API and events used to notify about regular keypresses.
> Similarly, how do you create an on-screen keyboard that can inject keypresses for characters not available in the current layout?
I switched the keyboard layout on the fly, on key press, if needed. That works... mostly. Chromium and Chromium-based apps know better what layout I am using, so they will misinterpret some inputs despite having a key map already.
And then you realize that you can't use a physical keyboard at the same time, because key maps go out of sync while keys are pressed on both. I talked to a Wayland dev about having separate keyboards with separate layouts, but the answer was basically "it's an incompatible change, and it's too late to fix this" (it was in an issue tracker, but no link). So the only way to have a non-input-method on-screen keyboard is to limit yourself artificially to the current layout. Which, of course, is an oft requested feature I will never implement.
> A better idea would be to allow to send arbitrary Unicode strings and maybe integrate regular input and IME input (input system for typing Asian characters).
Isn't Mac OS do something like that? I agree this is the way to go. But the stumbling block is - again - that applications like Chromium won't implement this. I created the text-input-v3 protocol some 4 years ago, and it's still basically only used in GNOME.
But with new funding from NLNet I'm gathering a special ops team to push input methods again this year :)
> most developers use only ASCII and do not have experience using multiple layouts.
I'm getting that impression as well after discussing the topic of internationalization on Mastodon: using languages other than English is undervalued by open source devs. I mean, how often do you find variables named in Spanish or Russian in open source software? It's a very anglocentric bubble.
> I'm getting that impression as well after discussing the topic of internationalization on Mastodon: using languages other than English is undervalued by open source devs. I mean, how often do you find variables named in Spanish or Russian in open source software? It's a very anglocentric bubble.
For Wayland, keyboard input is "out of scope". (edit: Not entirely, just verified it does forward very basic events, but it's a thing wayland doesn't want to handle, while X11 originally had its own keyboard/mouse/etc drivers) What's typically used is XKB (inherited from X11) with a different backend ([edit: raw events]). So yes, in practice, you'll have the same broken design.
> Also, there seem to be no sane API for managing layouts or switching
> them programatically
Layouts only exist as "data" as far as the X server is concerned, clients must fetch them and map themselves from the key codes. Libraries like xkbcommon (or even grandfather Xlib) do the job for you. That said, there are APIs to modify the mapping (by publishing messages/events) as you wish. The ugliness is, apart from the fact that you're forced to fiddle with the mapping at all, that you can't guarantee another client will process everything in sequence. It might apply a new mapping before processing all its queued key press events. That's why my code adds delays between fiddling with the mapping and sending the events.
Yes, it's extremely ugly. Still, at least for me, it works. Try it out ;)
And yes, Windows is doing better here, there's a Unicode-flavor of keyboard events available.
It's funny at the end he says "and don't ever suggest me I use Linux, just don't." I felt he expected it to be really hard project on Linux, while iterally his project is a single keyboard layout file.
On Gnome there is the "Characters" application which is pretty handy. I do want to make a few improvement to search, but otherwise it's pretty good. You copy the unicode character to the clipboard and can then paste it wherever you need.
Neat, thanks for sharing! This just replaced "Characters" for me.
Seems really well done, and most importantly the search works well and it has "recents". I do wish it wouldn't automatically close itself after clicking/copying an emoji, but I try not to let perfect be the enemy of good :-)
I'm very glad people made the push! My configuration has been much nicer being based on Wayland for the last 4 years or so than it was on X. Screentearing and limited refresh rates on mixed Hz setups are now a thing of the past :)
By that measure we'd still be using DOS these days (which was also productive and usable... and indeed the initial backlash against this nrefangled "Windows 95" thing kept going for a while, not very dissimilar to the X11 vs Wayland debates)
I mean you're free to fork and continue developing X11; right now there is nobody with both the capability and the desire to do so.
I'd wager that once I get hardware made in 2024, Wayland may work well for me (though in its defense it does work fine on my one machine with an Intel integraded GPU), but for now none of my (very old) discrete GPUs work reliably with Wayland, with 2 GPUs and 3 drivers (nvidia vs nouveau for my old GeForce and "radeon" (not amdgpu) for my old AMD card) causing 3 symptoms:
1. Crashes immediately on login
2. Black Screen
3. Kind-of sort-of works, but sometimes the screen just freezes for no reason and sometimes switching VTs fixes it sometimes not.
x11 is depreciated. It has no active maintainers and barely even qualifies for "maintenance mode" status; the push to remove Xorg can be justified by enumerating the security issues and nothing else.
Strictly speaking Linux is "productive and usable" with nothing but a terminal multiplexer and a shell to work with. With expectations as high as they are in 2024, I don't think former Windows or Mac users will feel at-home with an x11 session. Switching away from bazaar-style software development is a prerequisite for the Year of the Linux Desktop.
Building upon 40+ year old, stable technology that, compared to Wayland, still seems to be in popular demand [1, 2] is the only sensible thing for the lazy maintainer/dev. That's how I felt when I wrote X11-compatible EF*CK emoji keyboard [3].
I just use IBus, since I was already using it for Japanese IME input. It has its own emoji picker but has been kinda buggy before, instead I just use the "Typing Booster" keyboard option. I can type "wolf" and it'll popup a menu including the emoji or related emojis; I guess "cat:" is a better example since there's a lot more (e.g. shows tiger eventually) and I can scroll through them.
user perspective: As far as I know, it's the only tool offering somewhat reliable emoji input using faked X11 keyboard events. "x11-emoji-picker" comes close, but delegates faking events to "xdotool", with weird consequences like having to restart it to direct emojis to a different window ;)
hacker perspective: It directly integrates xcb in a different event loop (here based on pselect()) and actually works – xcb is IMHO pretty great except for pretty much enforcing its own async model, internally using poll() and reading from the X server into buffers at many occassions, hidden from the consumer. If all your app does is communicate with the X server, you just happily use xcb's model. As soon as you need different things (e.g. local timers), you have a problem. The typical way to address that is dedicating another thread to xcb (AFAIK also done that way by toolkits offering an X11 backend). I hated that idea enough to be stubborn about doing it directly in my main thread, and with quite some trial-and-error, finally succeeded.
Even for those emojis consisting of a singe codepoint, it would really miss the point. There are LOTS of emojis available, an emoji keyboard (or emoji picker) shows them organized in groups and allows searching for them.
Deleted Comment
One of the major flaws in X11 is its poorly designed keyboard input system. When a key is pressed, the keypress event sends a "keycode" - an 8-bit number that references the current layout. This means you're limited to injecting characters that are present in the current layout.
The implications of this design are frustrating. For instance, if you're connecting to a remote system via VNC and the client and server have different keyboard layouts, you'll run into all sorts of issues. Similarly, how do you create an on-screen keyboard that can inject keypresses for characters not available in the current layout? And what if you want to programmatically send some text, but the user has the wrong layout active? It's a mess.
I guess because of this in Debian most of characters in on-screen keyboard didn't work (they "fixed" it by showing only characters present in active layouts instead of fixing the root issue).
The common workaround for this is an ugly hack: you modify the keyboard layout, find unused spots, add desired characters, send key press event and restore the keyboard layout back. See the code: [2]
Also, Wayland which was supposed to get rid of legacy problems, seems to have inherited this ugly design. Also, there seem to be no sane API for managing layouts or switching them programatically, or subscribing to layout change event. Also, you cannot use modifiers like Ctrl to switch layouts because then combinations like Ctrl + C stop working. Keyboard APIs on Linux are broken in the worst way possible since beginning, probably because most developers use only ASCII and do not have experience using multiple layouts.
A better idea would be to allow to send arbitrary Unicode strings and maybe integrate regular input and IME input (input system for typing Asian characters).
[1] https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.ht...
[2] https://github.com/Zirias/xmoji/blob/master/src/bin/xmoji/ke...
X11 has XkbMapNotify/XkbStateNotify.
Wayland has a wl_keyboard.keymap event.
> A better idea would be to allow to send arbitrary Unicode strings and maybe integrate regular input and IME input (input system for typing Asian characters).
Not particularly, the difficulty here is that some clients want text input, and some clients really do want key events (e.g. think games where holding W does not really have much to do with the Unicode code point 'w'). This was discussed for a long time, and the current design was decided as the best option.
IME systems do exist and already work just fine; they are integrated client-side. IME systems cannot really be integrated into the protocol since many of them involve custom UI.
That said, there's a proposal for an "input-method" extension which lets you commit text directly, but I don't think anybody is actively championing it. https://gitlab.freedesktop.org/wayland/wayland-protocols/-/b...
I understand this point. For this case it makes sense to send both key code (what character does the key map in Latin layout) and translated code (which characters will be printed when key is pressed in current layout). It seems an easier solution than broadcast large structures to every client and let them have each own implementation for translating codes.
Regarding IME, I meant not integrating IME client into a Wayland server but instead unify the API and events that IME uses to insert text with API and events used to notify about regular keypresses.
Yes, it seems I missed XkbStateNotify and XkbLockGroup that can be used to switch layouts (which X11 calls "groups").
I hit all those Wayland issues while working on Squeekboard. https://gitlab.gnome.org/World/Phosh/squeekboard
> Similarly, how do you create an on-screen keyboard that can inject keypresses for characters not available in the current layout?
I switched the keyboard layout on the fly, on key press, if needed. That works... mostly. Chromium and Chromium-based apps know better what layout I am using, so they will misinterpret some inputs despite having a key map already. And then you realize that you can't use a physical keyboard at the same time, because key maps go out of sync while keys are pressed on both. I talked to a Wayland dev about having separate keyboards with separate layouts, but the answer was basically "it's an incompatible change, and it's too late to fix this" (it was in an issue tracker, but no link). So the only way to have a non-input-method on-screen keyboard is to limit yourself artificially to the current layout. Which, of course, is an oft requested feature I will never implement.
> A better idea would be to allow to send arbitrary Unicode strings and maybe integrate regular input and IME input (input system for typing Asian characters).
Isn't Mac OS do something like that? I agree this is the way to go. But the stumbling block is - again - that applications like Chromium won't implement this. I created the text-input-v3 protocol some 4 years ago, and it's still basically only used in GNOME.
But with new funding from NLNet I'm gathering a special ops team to push input methods again this year :)
> most developers use only ASCII and do not have experience using multiple layouts.
I'm getting that impression as well after discussing the topic of internationalization on Mastodon: using languages other than English is undervalued by open source devs. I mean, how often do you find variables named in Spanish or Russian in open source software? It's a very anglocentric bubble.
And that's a good thing.
> Also, there seem to be no sane API for managing layouts or switching > them programatically
Layouts only exist as "data" as far as the X server is concerned, clients must fetch them and map themselves from the key codes. Libraries like xkbcommon (or even grandfather Xlib) do the job for you. That said, there are APIs to modify the mapping (by publishing messages/events) as you wish. The ugliness is, apart from the fact that you're forced to fiddle with the mapping at all, that you can't guarantee another client will process everything in sequence. It might apply a new mapping before processing all its queued key press events. That's why my code adds delays between fiddling with the mapping and sending the events.
Yes, it's extremely ugly. Still, at least for me, it works. Try it out ;)
And yes, Windows is doing better here, there's a Unicode-flavor of keyboard events available.
edit: It does, libinput exposes keyboard events via evdev.
https://www.youtube.com/watch?v=lIFE7h3m40U
It's funny at the end he says "and don't ever suggest me I use Linux, just don't." I felt he expected it to be really hard project on Linux, while iterally his project is a single keyboard layout file.
Deleted Comment
On Gnome there is the "Characters" application which is pretty handy. I do want to make a few improvement to search, but otherwise it's pretty good. You copy the unicode character to the clipboard and can then paste it wherever you need.
If you run Gnome it's probably already installed. If not: https://gitlab.gnome.org/GNOME/gnome-characters
Seems really well done, and most importantly the search works well and it has "recents". I do wish it wouldn't automatically close itself after clicking/copying an emoji, but I try not to let perfect be the enemy of good :-)
Nevertheless, it looks like a pretty cool tool!
I'd wager that once I get hardware made in 2024, Wayland may work well for me (though in its defense it does work fine on my one machine with an Intel integraded GPU), but for now none of my (very old) discrete GPUs work reliably with Wayland, with 2 GPUs and 3 drivers (nvidia vs nouveau for my old GeForce and "radeon" (not amdgpu) for my old AMD card) causing 3 symptoms:
1. Crashes immediately on login
2. Black Screen
3. Kind-of sort-of works, but sometimes the screen just freezes for no reason and sometimes switching VTs fixes it sometimes not.
Strictly speaking Linux is "productive and usable" with nothing but a terminal multiplexer and a shell to work with. With expectations as high as they are in 2024, I don't think former Windows or Mac users will feel at-home with an x11 session. Switching away from bazaar-style software development is a prerequisite for the Year of the Linux Desktop.
[1]: https://qa.debian.org/popcon-graph.php?packages=xserver-xorg...
[2]: https://qa.debian.org/popcon-graph.php?packages=libwayland-s...
[3]: https://efck-chat-keyboard.github.io
Made me think of the emoji physical keyboard from Tom Scott https://youtu.be/3AtBE9BOvvk
Deleted Comment