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.

52zmLKolohdRQ5v.png

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
  • 0x90shell@piefed.socialOP
    link
    fedilink
    English
    arrow-up
    3
    arrow-down
    1
    ·
    edit-2
    10 hours ago

    Yeah, if it only handles the display side and relies on an accessibility framework like AT-SPI or IBus for input injection. That’s how Onboard and GNOME’s built-in keyboard work. But those frameworks need a cooperative desktop environment and don’t work consistently across compositors.

    This tool needs raw device access because it does more than just display a keyboard:

    • Reads gamepad input directly from evdev (d-pad, sticks, buttons, triggers). Accessibility frameworks don’t handle gamepad input, only keyboard/mouse.
    • Injects keyboard and mouse events via uinput. AT-SPI/IBus can inject keystrokes but not mouse movement or arbitrary key combos like Ctrl+Z.
    • Grabs the gamepad exclusively while visible so input doesn’t bleed to the game. No framework exposes device grabbing.
    • Emulates a mouse cursor from analog stick input. Continuous analog-to-mouse translation isn’t something accessibility buses are built for.

    TL;DR
    Raw evdev/uinput is what lets it work standalone on any compositor without depending on desktop-specific APIs. The trade-off is device permissions instead of accessibility bus access.

    • mrbigmouth502@piefed.zip
      link
      fedilink
      English
      arrow-up
      1
      ·
      2 hours ago

      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.

      • 0x90shell@piefed.socialOP
        link
        fedilink
        English
        arrow-up
        1
        ·
        2 hours ago

        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.