As on phone keyboards: a sideways move on space moves the cursor right away, along the line only, without blanking the keys. Long-press space still opens the full trackpad. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
88 lines
5.9 KiB
Markdown
88 lines
5.9 KiB
Markdown
# 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, 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
|
||
- 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
|
||
- 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
|
||
|
||
```sh
|
||
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. Dead keys compose with the locale's XKB compose table.
|
||
|
||
Everything else is `layouts/template.json`; `~/.local/share/sloposk/template.json` replaces it.
|
||
|
||
```json
|
||
{"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"`; `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.
|