There’s no good standalone controller-driven on-screen keyboard on Linux. Steam’s keyboard requires Steam running. Other virtual keyboards (Onboard, Florence) need a mouse pointer or are dead projects. I wanted something that takes D-pad and stick input directly, like a console, but can be launched independently of specific games or platforms.
So I built one written in Go with SDL2 originally, but I have a vastly updated SDL3/Wayland branch that’s WIP and ready for testing. It works as a daemon with a configurable controller combo to toggle show/hide.
The SDL3/Wayland branch adds layer-shell support, fullscreen-aware positioning, and a lot of improvements over the v1.1 release. Getting Wayland functional doubled the codebase. X11 is solid, but I need more testing in Wayland compositors (Sway, Hyprland, KDE, GNOME) before merging since I don’t run Wayland on my machines.
If you’re on Wayland with a gamepad, I’d appreciate testers. Bug reports and PRs welcome. AUR packages won’t be updated until the SDL3 branch is confirmed stable and I bump to v2.

Features :
- Full QWERTY with shortcuts row (undo, redo, cut, copy, paste, select all, Alt+Tab, media keys)
- D-pad navigation with stick-driven mouse cursor
- Modifier support (Shift, Ctrl, Alt, Super, Caps) with visual status indicators
- Button-hold key repeat for backspace, space, enter
- Alt+Tab key for multiple Tab presses
- Auto-reconnect on controller disconnect/timeout
- Configurable button mapping, 60 themes, adjustable opacity
- Sub-1% CPU idle, under 4% during active input



I see. I wonder, does any of this have issues on Wayland? I try to use it wherever I can for its security benefits, though I know it’s not as flexible as X11 in some cases.
Also, I don’t know where that downvote came from, but it wasn’t me. I gave you an updoot to bring you back above 0.
No worries about the downvote. evdev and uinput are kernel interfaces, they work the same on Wayland and X11. The display side has native Wayland support via wlr-layer-shell (Sway, Hyprland, KDE Plasma). Steam does the same thing I’m doing for gamepad input - reads /dev/input/event* directly via SDL, creates virtual devices via uinput for remapping. Same kernel interfaces, same udev rules.