From 7ab4d2f18db48e8713ec280d27388a6e5056250b Mon Sep 17 00:00:00 2001 From: felixzsh Date: Tue, 11 Aug 2026 10:52:54 -0500 Subject: [PATCH] Linger on screen after release, keyviz-style Previously the chips cleared the instant the keys were released, so the 120ms hide delay was invisible. Keep the last combo rendered for the whole linger window and only clear it when the timer fires, so a quick tap stays readable (keyviz keeps keys for lingerDurationMs, 5s by default). Default 1000ms, tunable via lingerMs. --- KeyVisualizer.qml | 20 +++++++++++++------- README.md | 5 +++-- manifest.json | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/KeyVisualizer.qml b/KeyVisualizer.qml index 61f30f4..4af4e8d 100644 --- a/KeyVisualizer.qml +++ b/KeyVisualizer.qml @@ -10,7 +10,7 @@ import qs.Ui // to the compositor's key events and writes the current combination to // $XDG_RUNTIME_DIR/omarchy-key-visualizer.json. This panel watches that file // and renders. No images, no animations: the combo appears while held and -// disappears the moment the keys are released. +// lingers briefly after release (like keyviz's Duration), then vanishes. // // On first load the panel also appends a small guarded block to // ~/.config/hypr/hyprland.lua that dofiles the capture script, so install @@ -21,9 +21,10 @@ Item { property bool opened: false property var keys: [] - // Grace period after the last key is released. Small enough to feel - // immediate, long enough that a quick tap is still readable. - property int hideDelayMs: 120 + // How long the last combination stays on screen after the keys are + // released (keyviz's "Duration"; keyviz defaults to 5000ms). The combo + // lingers intact, then vanishes in one frame — no fade. + property int lingerMs: 1000 // Drop state written more than this long ago (e.g. from a previous shell // session after a restart) so a stale combo never sticks on screen. readonly property int maxStateAgeMs: 1500 @@ -79,19 +80,24 @@ Item { if (age <= Math.ceil(root.maxStateAgeMs / 1000)) next = parsed.keys } } catch (e) {} - root.keys = next if (next.length === 0) { + // Keys were released: keep the last combo on screen for the linger + // window, then clear it. A fresh press restarts the timer below. hideTimer.restart() } else { hideTimer.stop() + root.keys = next root.opened = true } } Timer { id: hideTimer - interval: root.hideDelayMs - onTriggered: root.opened = false + interval: root.lingerMs + onTriggered: { + root.keys = [] + root.opened = false + } } FileView { diff --git a/README.md b/README.md index 47df355..eb900a0 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,8 @@ The panel starts with the shell, so it works after the next login too. - Modifiers that produce the shifted character (`Shift` with a letter) are folded into the character itself: `Shift + 1` shows `!`. - Key repeat is ignored; a held key shows once. -- The combo disappears immediately after the last key is released. +- After the last key is released the combo lingers briefly (1s by default, + keyviz-style "Duration") and then vanishes in one frame — no fade. ## Customize @@ -81,7 +82,7 @@ automatically. | Want to change... | Edit | |-----------------------------------|-----------------------------------------| -| How long a released combo lingers | `hideDelayMs` in `KeyVisualizer.qml` (default `120`) | +| How long a released combo lingers | `lingerMs` in `KeyVisualizer.qml` (default `1000`; keyviz defaults to `5000`) | | Chip font / padding | `chipFont`, `chipPadX/Y` in `KeyVisualizer.qml` | | Key labels or layout mapping | `KEYS` / `CHARS` / `SHIFTED` tables in `key-visualizer.lua` | diff --git a/manifest.json b/manifest.json index 42fd7bd..5de976f 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "felixzsh.key-visualizer", "name": "Key Visualizer", - "version": "1.0.0", + "version": "1.1.0", "description": "Shows the keys you press on screen. Great for keybinding tutorials, demos, and screencasts.", "kinds": ["panel"], "keepLoaded": true,