Files
sloposk/README.md
T
ericek111andClaude Opus 5.5 c6c977eb4c Floating polish: visibility, resize, saved geometry, D-Bus, desktop entry
- VisibilityController: show on field focus, dismiss until next focus,
  manual show/hide/toggle overrides
- FloatingWindow: resize from the corner grip, clamp to screen
- WindowSettings: geometry per screen, debounced saves
- DBusControl: org.sloposk.Keyboard Show/Hide/Toggle for global shortcuts
- org.sloposk.keyboard.desktop so System Settings lists it as a virtual keyboard
- README with build/run/layout docs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 15:02:25 +02:00

2.7 KiB

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
  • Auto-capitalization, double-space → ". ", backspace repeat → word delete
  • Long-press space = trackpad; slide from .?123 onto a symbol and release
  • Floating: drag the bottom bar, resize from the corner; geometry is remembered per screen

Build & test

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

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

Run

KWin only offers the input-method protocol to the process it launches itself.

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
UI only build/src/sloposk (stays visible, types nowhere)

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

JSON in layouts/ (built in) or ~/.local/share/sloposk/layouts/ (overrides by id). The globe key cycles them; the system locale's comes first.

{
  "id": "sv-SE", "name": "Svenska", "locale": "sv_SE",
  "base": "en-US",
  "layers": [{"name": "letters", "rows": [[
    "q",
    {"label": "e", "flick": "3", "alternates": ["é", "è"]},
    {"type": "backspace", "width": 1.5}
  ]]}]
}
  • Key: a string, or an object with type (char space backspace enter shift layer globe dismiss spacer), label, shifted, flick, alternates, width (key units), target (for layer)
  • base: take layers this layout doesn't define (e.g. numbers/symbols) from another layout
  • Rows in a layer should add up to the same width; tst_layoutloader checks the built-ins

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)
layout/     JSON → Layout → LayoutModel (geometry, hit testing)
window/     floating layer-shell placement, visibility, saved geometry
app/        D-Bus control, dev hooks

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