Files
sloposk/README.md
T
ericek111andClaude Opus 5.5 032fbd8ba4 Shrink to a floating button instead of hiding
With "Shrink to Button" on, the dismiss key shrinks the window to just
itself: a see-through button that can be dragged anywhere. Tapping it
grows the keyboard back around it, kept on screen. KWin moves and
resizes the window through a one-off script, as Wayland clients can't
place themselves.

Also moves the window back on screen whenever it appears (KWin remembers
where the button was), and releases the mouse after a window manager
move or resize, which used to eat the next press on the grab bar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 01:05:37 +01:00

6.2 KiB
Raw Blame History

sloposk

iPad-style floating on-screen keyboard for Plasma Wayland. Qt 6, C++ core, QML UI.

  • Flick a key down for its secondary symbol; long-press for accented alternates
  • iOS shift: tap = one letter, double-tap = caps lock, hold = shift while held
  • Works everywhere, not just in text fields: with none focused, keys reach the focused window like a hardware keyboard (shortcuts, terminals, the desktop); "Always Show" in ⚙ keeps it up
  • "Hold Keys" (⚙): keys stay down while touched, like a hardware keyboard (games, Shift+click, system key repeat); modifiers are plain keys, dead keys compose in the app; touch conveniences off
  • Letters follow the system keyboard layout; the globe key switches it
  • Auto-capitalization, double-space → ". " (both optional, ⚙ on the bottom bar), backspace repeat → word delete
  • Slide sideways on space to move the cursor; long-press space = trackpad (lines too); slide from .?123 onto a symbol and release
  • Compact (iPad) or full (iPad Pro) keyboard: number row, punctuation, tab, caps lock, ctrl/alt/super/alt gr, dead keys
  • Ctrl/Alt/Super stick like shift (tap, double-tap, hold) and turn keys into shortcuts; a tapped or held shift joins them (Shift+F5, Shift+Tab, Shift+arrows), auto-shift and caps lock don't
  • Alt Gr (right of space in full mode) types the keymap's AltGr symbols (sk: Alt Gr+J = '), sticky like the others
  • Optional PC key blocks: function row, navigation (ins/home/pg up, del/end/pg dn, arrows), numeric keypad; any mix, typing keys included (⚙)
  • Floating: drag the bottom bar, resize from the corner; geometry is remembered per screen
  • "Shrink to Button" (⚙): ⌨ leaves just itself as a see-through floating button (drag it anywhere); tap it for the keyboard back, around the button and kept on screen
  • Follows Plasma's virtual keyboard setting (tray toggle): off never pops up on focus, the default only after touch or a pen; "Always Show" and D-Bus Show/Toggle still show it
  • See-through background (opacity slider in ⚙) with optional blur behind it (KWin's blur effect)

Build & test

cmake -B build -G Ninja && cmake --build build
ctest --test-dir build

Needs Qt ≥ 6.8 (Quick, WaylandClient, DBus, Test), KF6 WindowSystem, KF6 Config, xkbcommon, wayland-protocols.

Run

KWin offers the input-method protocol and fake input (held keys, shortcuts, typing outside text fields) to the keyboard it launches itself, so launch sloposk through KWin.

Where How
Nested session (safe) kwin_wayland --no-lockscreen --socket sloposk-dev --width 1400 --height 900 --inputmethod $PWD/build/src/sloposk kwrite
Desktop cmake --install build --prefix ~/.local, then System Settings → Keyboard → Virtual Keyboard → sloposk
Desktop, from the build ln -s $PWD/build/src/org.sloposk.keyboard.desktop ~/.local/share/applications/, then pick sloposk as above
UI only build/src/sloposk (stays visible, types nowhere)

Started any other way (e.g. kioclient exec), KWin grants neither protocol; the ⚙ panel lists what's missing.

Show/hide, e.g. from a global shortcut: qdbus org.sloposk.Keyboard /Keyboard org.sloposk.Keyboard.Toggle

Dev hooks: SLOPOSK_AUTOTYPE=text commits on focus; SLOPOSK_SCREENSHOT=file.png saves the window and quits.

Layouts

Letters come from the system keymap (what KWin sends to every client): its Q/A/Z rows become the three letter rows. Letters elsewhere, e.g. Slovak ľščťž on the number row, become long-press alternates. The globe key switches the system layout over org.kde.keyboard, so the physical keyboard follows.

In full mode every typing key comes from the keymap (number row, [ ] \ ; ' , . / or the layout's equivalents), with the shifted symbol shown above (and flickable); letters, whose shift only capitalizes, show their AltGr symbol instead. Dead keys compose with the locale's XKB compose table.

Everything else is layouts/template.json; ~/.local/share/sloposk/template.json replaces it.

{"type": "letters", "row": 0, "flicks": ["1", "2", "3"]},
{"type": "backspace", "width": 1.5, "stretch": true}
  • Key: a string, or an object with type (char space backspace enter shift layer globe dismiss spacer letters keysym), label, shifted, flick, alternates, width (key units), target (for layer), stretch
  • keysym: sends the XKB keysym named by keysym (Home, F5, Left...) on press; repeat auto-repeats while held
  • letters: the keymap's letters in row row (0–2), with flicks handed out left to right
  • keys: every typing key in keymap row row (0 = number row … 3 = bottom)
  • modifier: "modifier": "ctrl" | "alt" | "super" | "altgr"; capslock
  • Layer full: rows used instead of rows in full-keyboard mode
  • stretch: the key grows so its row is as wide as the layer's widest (letter counts vary by layout)
  • Top-level alternates: long-press choices per letter, after the keymap's own
  • Top-level sections: optional blocks, {"id", "name", "placement": "above" | "right", "fillHeight", "rows"}; the user picks which show; fillHeight stretches a right-hand block over the full keyboard height

Settings

~/.config/sloposk/sloposk.conf, also editable from the ⚙ panel: typing/autoCapitalize, typing/doubleSpacePeriod, typing/holdKeys, layout/visibleSections (main plus section ids), layout/fullKeyboard, window/alwaysVisible, appearance/backgroundOpacity (0.1–1), appearance/blurBackground.

Architecture

qml/        view only
input/      touch → PointerTracker gestures → KeyboardController rules
engine/     key output → text ops (DirectEngine; prediction/swipe later)
backend/    text ops → compositor (KWin input-method-v1, or fake input with no text field); the compositor's keymap
layout/     template JSON + keymap letters → Layout → LayoutModel (geometry, hit testing)
window/     floating window (KWin rule: on top, no focus), visibility, saved geometry
app/        D-Bus control and system layouts, dev hooks
settings/   persisted user preferences

sloposk_core (everything compositor-independent, plus the Sloposk QML module) is a static library shared by the app and the tests.

protocols/fake-input.xml is KDE's org_kde_kwin_fake_input (LGPL-2.1-or-later), vendored from plasma-wayland-protocols.