Skip to content

YAKC 2.8.0 — full cross-platform input visualizer (keyboard, mouse, gamepad, OBS, profiles) - #5

Merged
iammodev merged 11 commits into
mainfrom
feat/virtual-keyboard
Jul 30, 2026
Merged

YAKC 2.8.0 — full cross-platform input visualizer (keyboard, mouse, gamepad, OBS, profiles)#5
iammodev merged 11 commits into
mainfrom
feat/virtual-keyboard

Conversation

@iammodev

@iammodev iammodev commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Turns YAKC from a keycaster into a complete cross-platform input visualizer — keyboard, mouse (clicks, movement, scroll) and gamepad — displayable on screen or as a transparent OBS browser source. Version bumped 2.0.0 → 2.8.0 (8 feature slices).

Features

  1. Mouse-movement + scroll + gamepad visualizers — dot-in-a-ring mouse widget (works on Wayland), scroll tokens, and a controller widget (sticks/triggers) via gilrs. Each independently toggleable.
  2. OBS browser source — serves the overlay at http://localhost:<port>/overlay over a hand-rolled SSE server; option to show only in OBS.
  3. Drag-to-position — a temporary non-click-through move mode with per-widget positions and magnet-style alignment guides.
  4. On-screen virtual keyboard — caps light up by physical W3C code (universal for QWERTZ/AZERTY, distinct L/R modifiers); labels read from the OS layout per platform.
  5. Pick-which-keys selector — a visual key picker; the trimmed keyboard packs compactly (aligned columns + gravity).
  6. Tabbed settings + cross-platform process filter — live process checklist with search/chips, monitor dropdown, font combobox, color swatches. The process filter now works on Wayland (KDE via KWin D-Bus), X11, Windows and macOS, event-driven and panic-proof.
  7. Profiles + presets — named config snapshots (tray + settings), bundled Minimal/Streamer/Gamer presets, JSON import/export.
  8. Independent widget positioning + alignment guides — mouse/gamepad rings each have their own draggable position; move mode shows every object with a name tag + hover highlight and magnet-style snap guides.

Plus a README refresh positioning YAKC against input-overlay and the other keycasters, with new config docs, FAQ and SEO.

Cross-platform notes

  • New deps: gilrs (all), sysinfo (all), zbus (Linux, for the KWin focus watcher).
  • Per-OS keyboard-label enumerators (Windows ToUnicodeEx, macOS UCKeyTranslate) — now verified compiling on all targets in CI.

Testing

  • cargo test green (39 tests); verified on Linux (KDE Wayland) via cargo tauri dev across all features. CI green on ubuntu (x64 + arm), windows (x64 + arm) and macos.

iammodev added 11 commits July 29, 2026 23:05
…zers

Phase 1 of the input-visualizer expansion. Each visualizer is an independent, opt-in toggle (all default off except keyboard): mouse movement (dot-in-ring), scroll wheel, mouse clicks, gamepad buttons, and gamepad sticks/triggers.

Rust: new RawInput variants (MouseMotion/Scroll/GamepadButton/GamepadAxis/GamepadConnection); gilrs gamepad backend; evdev REL_X/Y + wheel and rdev MouseMove/Wheel capture; a ~60Hz coalesced device-state emitter; scroll + gamepad labels overridable via keyLabelOverrides. Frontend: devices.js renders a mouse ring and gamepad stick/trigger widget; new Mouse & Gamepad settings sections. Also fixes the PR #3 save bug where the link-type field clobbered keyLabelOverrides.
Serves the overlay over a tiny std::net HTTP server (opt-in, localhost) so OBS can use it as a transparent Browser source at http://localhost:<port>/overlay. The page reuses the exact overlay.js/devices.js via a window.__TAURI__ shim: config over fetch(/config), live input over a flushed Server-Sent-Events stream (/events). Enabling starts the server immediately; a broadcaster mirrors click-event/device-state/config-updated/yakc-error to every browser client, skipping serialization when none are connected.

Adds 'Show overlay on this screen' (default on): turn off to display only in OBS, so the overlay isn't captured twice or seen locally. New config: obsServerEnabled, obsServerPort (7238), showOverlayOnScreen.
Completes the last README TODO. A tray item ('Move overlay position') and a settings button drop the overlay's click-through so the user can drag a handle to where popups should anchor, then Save (persists position=top-left + left/top offsets, live-applied and propagated to the OBS source) or Cancel. Rust: begin_move/end_move in overlay.rs + begin_overlay_move/end_overlay_move commands. Frontend: move-mode handle/toolbar in overlay.js, styles, and a reusable 'action' settings field type. Works in OBS-only mode by temporarily showing the overlay and restoring visibility on exit.
New displayStyle=keyboard renders an on-screen keyboard whose caps light up as you type, alongside the existing popups. Driven by physical key position (W3C codes) not characters, so it lights the correct cap on any layout (QWERTY/QWERTZ/AZERTY/…) and distinguishes left/right modifiers (hold-highlight). Works in the native overlay and the OBS browser source.

Cap labels are read from the OS's active layout up front (get_key_labels), per-platform and native: Linux xkbcommon (verified), Windows ToUnicodeEx, macOS UCKeyTranslate — with live relabel from typed characters as a universal fallback. Backends now emit the physical code + forward modifier press/release. The keyboard is movable via drag-to-position (drag the real keyboard; snaps to center).

NOTE: the Windows/macOS label enumerators compile only on those targets and are unverified from the Linux dev box — they need a CI/Win/Mac build to confirm.
Add a visual "pick which keys to show" selector for the on-screen
keyboard. Click caps in a keyboard mock-up (labeled in the real OS
layout) to include/exclude them, with Select all / Clear / Invert
helpers; reachable from Settings → Input → "Pick keys…".

New config field `keyboardVisibleKeys` (W3C physical codes); empty =
show the whole keyboard, so existing configs and "select all" both mean
the full board.

When a subset is chosen the keyboard renders in a compact grid: caps
align by column (A under Q), unused columns collapse, and each column's
keys stack upward so empty slots (e.g. an unselected Caps above Shift)
disappear — as tight as the reference WASD layouts. Space stretches to
fill its row. The full keyboard still uses realistic key sizes.

Extract the layout into a shared keyboard-layout.js so the live keyboard
and the selector can't drift; served by the OBS browser source too.
Position YAKC as a full cross-platform INPUT visualizer (keyboard, mouse
and gamepad), not just a keycaster:

- Rewrite the intro/features for the on-screen virtual keyboard + key
  selector, mouse movement/scroll, gamepad, OBS browser source and
  drag-to-position.
- Add an input-overlay column to the comparison table plus rows for the
  new capabilities, and a "works standalone (no OBS)" row.
- Add a gamepad-capture row to the per-platform table and document the
  new config keys (displayStyle, keyboardVisibleKeys, showMouseMovement,
  showGamepad, obsServer*, showOverlayOnScreen, …).
- New FAQ entries (gamepad, input-overlay alternative, mouse movement,
  OBS browser source) and refreshed SEO keywords.
- Tick off the done roadmap items in TODO.
… filter

Settings UX overhaul plus a process filter that finally works everywhere.

Settings:
- Group everything into tabs (Appearance / Position / Input / Devices /
  Streaming / Filter); remembers the last tab; Ctrl/Cmd+S saves.
- Process filter is now a live picker: selected apps as removable chips,
  a search box that filters the running-app list AND adds a typed name on
  Enter, and a checklist of running apps — all kept in sync. Running apps
  come from a new cross-platform get_running_processes (sysinfo).
- Monitor field is a real dropdown of connected monitors (get_monitors);
  font family is a combobox of common stacks; color inputs get swatches.
- Work around a WebKitGTK bug where async-added rows weren't painted
  until interaction (force a reflow after loading the list).

Process filter:
- Make it work on Wayland, where the focused window is hidden from X11
  tools: own a small D-Bus service and load a KWin script that pushes the
  active window's class to us on focus changes (KDE). Event-driven, so
  it's instant with no polling and no journal output.
- X11/Windows/macOS poll at a snappy 100ms, but only while the filter is
  enabled (a disabled filter skips the focus query), so it's essentially
  free when off. Re-evaluates immediately on save too.
- Panic-proof (a focus-query panic no longer kills the thread) and always
  restores capture when it stops gating, so capture can never get stuck.
- Lenient name matching (case-insensitive, .exe/.app-agnostic, handles
  reverse-DNS Wayland classes like org.kde.konsole vs "konsole").
- Drop the obsolete filterCheckEverySecond knob.
Add a Profiles tab (and a tray Profiles submenu) for saving, loading,
renaming and deleting named config snapshots, plus bundled starter
presets (Minimal, Streamer, Gamer) that apply on top of the current
config, and JSON import/export via a native file dialog.

Profiles are <name>.json under a profiles/ dir next to config.json; the
active one is tracked and marked ● in the tray, which rebuilds when
profiles change. Refactor config application into a shared apply_active()
reused by save, profile load, preset apply and import so each live-
updates the overlay identically.
Give the mouse ring and gamepad widget their own positions instead of a
shared, fixed center-bottom box, so they no longer stack on the keyboard
(they default to opposite bottom corners). In drag-to-position mode every
visible object — the keys display, mouse ring and gamepad ring — is now an
independently draggable target with a name tag and a hover highlight, so
overlapping widgets can be told apart; the gamepad ring is revealed even
without a controller so it can be placed.

Add magnet-style alignment guides while dragging: the dragged object's
edges/center snap to the other objects' edges/centers and the screen
center, drawing a guide line on snap. On by default, toggled from the
move toolbar and remembered (config.snapToGuides). Positions persist per
widget in config.widgetPositions.
@iammodev
iammodev force-pushed the feat/virtual-keyboard branch 2 times, most recently from 8cb72a8 to 3fdd298 Compare July 30, 2026 10:24
@iammodev
iammodev merged commit 88548e9 into main Jul 30, 2026
5 checks passed
@iammodev
iammodev deleted the feat/virtual-keyboard branch July 30, 2026 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant