Commit Graph
36 Commits
Author SHA1 Message Date
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
ericek111andClaude Opus 5.5 ac5f43ca5f Add quick toggles to the grab bar
Beside the gear: full keyboard, hold keys, and the numeric keypad,
navigation and function key sections, each behind a drawn icon and lit
while on. Section toggles hide when the layout lacks the section. The
grab pill narrows when a small window leaves it less room.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:29:48 +01:00
ericek111andClaude Opus 5.5 b94463a277 Show the keyboard at startup when "Always Show" is on
The initial visibility was applied before the window listened for it, so
with "Always Show" on the controller thought it was shown while no window
existed, and neither field focus nor D-Bus Show could bring it up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:29:48 +01:00
ericek111andClaude Opus 5.5 b50667e508 Add an AltGr key; full-mode letters flick to their AltGr symbol
The right alt in full mode is now AltGr: sticky like the other modifiers,
it types the keymap's third/fourth level (sk: AltGr+J = ') instead of an
Alt shortcut. In hold-keys mode it holds the physical right alt, since
KWin resets the modifier state after an ISO_Level3_Shift keysym.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:59:37 +01:00
ericek111andClaude Opus 5.5 441c1d615b Slide sideways on space to move the cursor
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>
2026-10-25 17:51:09 +01:00
ericek111andClaude Opus 5.5 b745e9da1b Follow Plasma's virtual keyboard setting
KWin activates the input method for every text field; its policy (the
tray toggle) only gates the input panel, which sloposk doesn't use. sloposk
now asks KWin over D-Bus whether a focused field should show the
keyboard: never when off, only after touch or a pen by default.
"Always Show" and D-Bus Show/Toggle still show it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 17:31:13 +01:00
ericek111andClaude Opus 5.5 499e5ee76e Report unavailable protocols and services; send combos as real keys
Diagnostics collects what this session doesn't allow, logs it, and lists
it in the settings panel (with a dot on the gear): KWin not launching
sloposk as its keyboard (detected by WAYLAND_SOCKET, since KWin offers the
input-method global to every client), fake input missing or too old,
org.kde.keyboard unreachable, and the D-Bus control name taken.

Modifier combos go through fake input even in text fields: KWin drops
the input method's modifier mask for most clients, so Ctrl+A typed "a".

The desktop file is generated with an absolute Exec, which KWin needs to
match it: one for the installed binary, one for the build's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 11:36:56 +02:00
ericek111andClaude Opus 5.5 6164839886 Float as a KWin-managed window instead of a layer surface
The grab bar didn't move the window by mouse, and the corner grip never
resized it (the bar's handler took over its drag). The bar and grip now
start the window manager's move/resize, and Super+LMB/RMB work too.

A KWin rule in kwinrulesrc keeps the window above and unfocused, off the
taskbar, pager and switcher, and remembers its position. KWin now places
the window and keeps it on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:44:33 +02:00
ericek111andClaude Opus 5.5 daab2fe0ab Add the audit's open items
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:20:50 +02:00
ericek111andClaude Opus 5.5 cef7d384bb Tests: build without -Wextra warnings
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:56 +02:00
ericek111andClaude Opus 5.5 cfea9ece99 Reject more template mistakes
Empty keys, duplicate layer names and section ids, repeat on non-keysym
keys and stretch on letters/keys placeholders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:56 +02:00
ericek111andClaude Opus 5.5 990d62ffcf Debounce settings writes and save them on SIGTERM
- DebouncedStore, taken out of WindowSettings, now also saves the opacity
  slider once a drag ends instead of on every step
- SIGTERM/SIGINT (how KWin stops the input method) quit normally, so
  pending geometry and settings are written
- The slider's minimum opacity comes from Settings instead of a copy in QML

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:56 +02:00
ericek111andClaude Opus 5.5 cb7cf1e04d Keep the window on screen after screen changes
Re-fits on a resolution change or a move to another screen, without
overwriting the saved geometry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:49 +02:00
ericek111andClaude Opus 5.5 9f3940514b Fake input: check the bound protocol version
Qt binds the lower of the asked and advertised versions; sending
keyboard_keysym (v6) or destroy (v5) to an older KWin makes libwayland
abort. Those requests are skipped there, with a warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:49 +02:00
ericek111andClaude Opus 5.5 5f7873995b Follow KWin's layout service when it appears later
getLayout is asked asynchronously, and again whenever org.kde.keyboard
registers, so a late start or a KWin restart no longer leaves the globe
key switching only locally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:49 +02:00
ericek111andClaude Opus 5.5 536fc12d2f Dead keys: act on compose status at press time
- Two dead keys that compose (´´ → ´) type the result right away; a dead
  key that can't continue the sequence types the old accents and starts anew
- With Ctrl/Alt/Super, a dead key sends its dead keysym, as the physical
  key does, not the spacing accent from its label

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:49 +02:00
ericek111andClaude Opus 5.5 9abd19e5d3 Cancel keys still down when hold-keys mode flips
The surface cancels its fingers under the old rules before the switch, so
a release no longer reaches the other mode (a stuck repeater or held
modifier one way, a second copy of the character the other). Sticky
modifiers, shift and dead keys start over.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:41 +02:00
ericek111andClaude Opus 5.5 3a62599a3f Long-press popups: one owner, always on screen
- A second long-press finishes the first (typing its choice) before
  opening its own popup, instead of sharing one
- Popups move down over their key when the room above is too small
- No popup over an unknown key: an empty rect made every cell zero wide
- A repeated touch id cancels the stale pointer instead of leaking it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:33 +02:00
ericek111andClaude Opus 5.5 139a845151 Track input-method contexts by identity
- deactivate only drops the context it names; one replaced by an activate
  is kept until KWin deactivates it
- Moving focus straight from one field to another ends a manual hide

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:27 +02:00
ericek111andClaude Opus 5.5 d44aab7772 Keep the user's shift; trust the text guess less
- A tapped shift (on or off) survives the field re-reporting its context:
  it lasts until a character is typed, the hint changes or a field is focused
- An input-method reset forgets the guessed text and pending dead key, so
  double-space can't delete a character the keyboard never saw
- Fields that state typing preferences only get capitals if they ask
- Trackpad moves in fields without surrounding text make the guess unknown;
  Backspace removes a whole grapheme cluster from it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:27 +02:00
ericek111andClaude Opus 5.5 076bc14e2f More long-press accents; number-row letters stay choices in full mode
- Template alternates cover Central/Eastern European, Turkish, Romanian,
  Baltic, Nordic and Esperanto letters, at most 11 per key
- Only letters on the letter rows are skipped as choices, so sk ť, ľ, š…
  are offered on their base letter in full mode too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 22:46:13 +02:00
ericek111andClaude Opus 5.5 ac67ceac18 Full keyboard: stagger the letter rows like a hardware keyboard
- The ISO key left of Z takes its room from left shift (2.25 → 1.25 + 1),
  so ISO layouts no longer make the shift row the widest
- Caps lock and left shift keep their width; only right-hand keys stretch,
  so A no longer lines up with the key below it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 22:42:11 +02:00
ericek111andClaude Opus 5.5 ac0bfc2741 Keep blocks still when switching layers
- The main block reserves the width and rows of its biggest layer, so the
  numpad and function row no longer shift between letters and symbols
- Smaller layers stretch into the room: stretch keys widen, rows grow
  taller (rows above the layer, like the function row, keep their height)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 22:35:00 +02:00
ericek111andClaude Opus 5.5 75bbe2e566 Numeric keypad spans the full keyboard height
- Sections take "fillHeight": their rows stretch over the whole key area
  instead of sitting at the bottom at the shared row height
- Rows of other blocks are unaffected; the template turns it on for the numpad

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 22:31:42 +02:00
ericek111andClaude Opus 5.5 2e418bd1f7 See-through keyboard background with optional blur
- Opacity slider for the panel behind the keys (10–100%); keys stay opaque
- Blur Behind: asks the compositor (KWin) to blur under the rounded panel
  via KF6 WindowSystem; skipped at full opacity
- Settings panel draws over the window background so changes show live,
  and scrolls when it doesn't fit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 22:26:01 +02:00
ericek111andClaude Opus 5.5 e02b1a8237 Hold Keys mode: keys stay down while touched, like a hardware keyboard
- HardwareKeys presses a key's unshifted keysym on touch and releases it
  on lift, through fake input; held keys repeat and combine as on a
  physical keyboard (games, Shift+click)
- Shift/Ctrl/Alt/Super are plain held keys, caps lock is the system's,
  dead keys compose in the app
- No long-press, flick, trackpad or rollover in this mode; nothing is
  left held when the mode is turned off or touches are cancelled
- Settings switch; default stays the touch (virtual keyboard) mode

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 22:17:11 +02:00
ericek111andClaude Opus 5.5 f816135162 Type into any window: fake input when no text field is focused
- KWinFakeInput (org_kde_kwin_fake_input v6, offered by KWin to the
  input-method process): keysyms with real modifier keys held
- The KWin backend uses the input method in text fields and fake input
  everywhere else, so shortcuts, terminals and the desktop get keys
- Text rules (auto-capitalization, double-space) only apply in fields
- Always Show setting keeps the keyboard up without a text field

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:59:32 +02:00
ericek111andClaude Opus 5.5 ba2f17d665 Full keyboard mode, Ctrl/Alt/Super, dead keys, shift levels
- Full (iPad Pro) mode: every typing key from the keymap, number row,
  tab, caps lock, ctrl/super/alt; shifted symbol shown above and flickable
- Dead keys compose with the locale's XKB compose table
- Ctrl/Alt/Super stick like shift and turn keys into shortcuts; a tapped
  or held shift joins shortcuts and non-text keys, auto-shift and caps
  lock don't
- Auto-capitalization and caps lock only capitalize letters; the user's
  shift picks the keymap's shifted level
- Mode switch in settings keeps key size by resizing the window

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:29:24 +02:00
ericek111andClaude Opus 5.5 88338fde22 Optional PC key blocks: function row, navigation, numeric keypad
- Template sections placed above or to the right of the typing keys;
  the user picks any mix in settings, typing keys included
- keysym keys send XKB keysyms on press, optionally repeating
- Geometry lays blocks side by side with one key unit; stretch keys are
  resolved at layout time so composed blocks line up
- Toggling a block resizes the window so keys keep their size

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:18:10 +02:00
ericek111andClaude Opus 5.5 e532f5c072 Smooth flick animation: scale the symbol instead of its font size
font.pixelSize is an integer, so the old animation stepped in whole
pixels and re-laid out the text each step: width and height jumped,
centering snapped x sideways and y even moved backwards. Draw at the
final size and animate scale and position, which are continuous.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:30:15 +02:00
ericek111andClaude Opus 5.5 5277ab16ff Fix double-space period, shift double-tap; settings; letters from system keymap
- Double-space replaced the space via a Backspace keysym, which clients
  apply after the commit: use delete_surrounding_text with the commit
- Tests use a shared FakeEngine that applies ops to a simulated field
- Double-tap shift locks at a sentence start; typing between taps doesn't
- Organization name set: config lives in ~/.config/sloposk/
- Settings (auto-capitalization, double-space period) with a ⚙ panel
- Letter rows come from the compositor's XKB keymap; other letters of the
  layout become long-press alternates; globe switches the system layout
  over org.kde.keyboard
- One JSON template for non-letter layers; stretch keys even out rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:28:39 +02:00
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
ericek111andClaude Opus 5.5 92c132c66f Text rules: auto-capitalization, double-space period, backspace repeat
- TextContext: field purpose/hints and text before the cursor, reported by
  the backend (KWin content_type + surrounding_text)
- TextRules: sentence-start and double-space heuristics, deletion helpers
- KeyRepeater: held backspace repeats, then deletes whole words (Ctrl+BS)
- Controller keeps a best-guess of the text before the cursor so rules work
  instantly and in fields that don't report surrounding text
- No auto-capitalization or smart punctuation in password/URL/email fields

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:59:21 +02:00
ericek111andClaude Opus 5.5 2b5edeb365 Gestures: flick, long-press alternates, trackpad, layer slide, rollover
- PointerTracker: per-finger gesture state machine (pure, unit-tested)
- AlternatesPicker + AlternatesPopup.qml: long-press choices, finger selects
- Space long-press trackpad moves the cursor with arrow keysyms
- Slide from .?123 onto a symbol types it and switches back
- New finger commits pending taps (iOS rollover)
- Flick animation: secondary symbol slides down as the finger moves
- Transparent popup margin with an input region that passes clicks through
- tst_keyboardsurface: end-to-end gesture tests on the real QML

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:55:49 +02:00
ericek111andClaude Opus 5.5 be14bbcc62 Layouts, iPad-style rendering, taps, shift and layers
- JSON layouts (en-US, sv-SE inheriting number/symbol layers via base)
- LayoutModel + KeyGeometry: proportional rows, nearest-key hit testing
- KeyboardSurface: multi-pointer touch/mouse routing to the controller
- KeyboardController + ShiftState: iOS shift/caps-lock, layers, globe, dismiss
- QML view with light/dark iPad palette and drag handle
- DevHooks: SLOPOSK_AUTOTYPE, SLOPOSK_SCREENSHOT for headless checks
- Unit tests for shift, loader, geometry and controller

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:50:21 +02:00
ericek111andClaude Opus 5.5 cdef9b4ad0 Spike: KWin input-method backend with floating layer-shell window
Registers as KWin's virtual keyboard (input-method-unstable-v1), shows a
non-focusable layer-shell overlay, and commits Unicode text. Verified in a
nested headless KWin with the textprobe tool.

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