fix(capture): restore key overlay updates
This commit is contained in:
+29
-12
@@ -29,6 +29,11 @@ Item {
|
||||
// it. The history tick prunes entries whose linger window passed. With
|
||||
// historyCount 1 this is exactly "the current combo, lingering".
|
||||
property var entries: []
|
||||
// Epoch (seconds) of the last state payload we successfully parsed. Used
|
||||
// to detect a dead capture: if no new payload arrives within maxStateAgeMs
|
||||
// and the top combo was never released, we treat it as released so the
|
||||
// panel self-heals instead of freezing on a stale combo forever.
|
||||
property real lastStateT: 0
|
||||
// How many combos stay on screen (1..5, default 1). Older entries fade
|
||||
// out via the entryOpacity() gradient; a count of 1 is the classic
|
||||
// current-combo-only display.
|
||||
@@ -467,9 +472,10 @@ Item {
|
||||
if (!root.paused) {
|
||||
try {
|
||||
var parsed = JSON.parse(stateFile.text())
|
||||
if (parsed && Array.isArray(parsed.keys)) {
|
||||
if parsed && Array.isArray(parsed.keys) {
|
||||
var age = Math.floor(Date.now() / 1000) - (parsed.t || 0)
|
||||
if (age <= Math.ceil(root.maxStateAgeMs / 1000)) next = parsed.keys
|
||||
if ((parsed.t || 0) > 0) root.lastStateT = parsed.t
|
||||
}
|
||||
} catch (e) {}
|
||||
} if (next.length > 0 && root.mode === "bindings") {
|
||||
@@ -529,6 +535,16 @@ Item {
|
||||
repeat: true
|
||||
running: root.entries.length > 0
|
||||
onTriggered: {
|
||||
// If the capture stopped updating (crashed, plugin unloaded, or a
|
||||
// config reload disabled it), the top combo may be stuck with
|
||||
// releasedAt === 0 forever because no empty "all keys up" payload
|
||||
// ever arrives. Treat a stale state file as a release so the combo
|
||||
// lingers normally and then clears, instead of freezing on screen.
|
||||
if (root.entries.length > 0 && root.entries[0].releasedAt === 0 &&
|
||||
root.lastStateT > 0 &&
|
||||
Math.floor(Date.now() / 1000) - root.lastStateT > Math.ceil(root.maxStateAgeMs / 1000)) {
|
||||
root.entries[0] = { keys: root.entries[0].keys, releasedAt: Date.now() }
|
||||
}
|
||||
var now = Date.now()
|
||||
var kept = []
|
||||
for (var i = 0; i < root.entries.length; i++) {
|
||||
@@ -995,6 +1011,17 @@ Item {
|
||||
// Debug overlay: live readout of the card's position/dimensions and the
|
||||
// movement state, shown next to the card while moving and after release.
|
||||
// Toggle with: omarchy-shell key-visualizer debug
|
||||
readonly property var debugFont: Qt.font({
|
||||
family: Style.font.family,
|
||||
pixelSize: Style.font.bodySmall,
|
||||
bold: false
|
||||
})
|
||||
|
||||
FontMetrics {
|
||||
id: debugFontMetrics
|
||||
font: debugFont
|
||||
}
|
||||
|
||||
BorderSurface {
|
||||
id: debugOverlay
|
||||
visible: root.debugOverlay
|
||||
@@ -1012,7 +1039,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.cardPad
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font: debugFont
|
||||
font: root.debugFont
|
||||
color: Color.popups.text
|
||||
text: {
|
||||
var lb = "\n"
|
||||
@@ -1026,16 +1053,6 @@ Item {
|
||||
}
|
||||
readonly property bool debugDragging: dragArea.dragging
|
||||
|
||||
FontMetrics {
|
||||
id: debugFontMetrics
|
||||
font: debugFont
|
||||
}
|
||||
readonly property var debugFont: Qt.font({
|
||||
family: Style.font.family,
|
||||
pixelSize: Style.font.bodySmall,
|
||||
bold: false
|
||||
})
|
||||
|
||||
// Combo mode banner — a separate visual stacked against the history
|
||||
// card (below it for bottom positions, above it for top positions).
|
||||
// Shows the combo counter, multiplier and running score; hue and
|
||||
|
||||
@@ -225,7 +225,10 @@ Panel {
|
||||
owner: root
|
||||
bar: root.bar
|
||||
open: root.opened
|
||||
contentWidth: Style.space(250)
|
||||
contentWidth: panel.fittedContentWidth(
|
||||
Math.max(Style.space(250),
|
||||
filterLabel.implicitWidth + Style.spacing.xl + modeButtons.implicitWidth
|
||||
+ panel.padding * 2 + Border.left(panel.borderSpec) + Border.right(panel.borderSpec)))
|
||||
contentHeight: menuColumn.implicitHeight + panel.padding * 2
|
||||
|
||||
Column {
|
||||
@@ -295,6 +298,7 @@ Panel {
|
||||
height: modeButtons.height
|
||||
|
||||
Text {
|
||||
id: filterLabel
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "Filter"
|
||||
|
||||
+5
-9
@@ -32,9 +32,8 @@ local function is_runtime_secure(r)
|
||||
if not r or r == "" then return false end
|
||||
if r == "/tmp" then return false end
|
||||
if r:sub(1, 1) ~= "/" then return false end
|
||||
-- Shell ownership probes fail from Hyprland's embedded Lua environment.
|
||||
-- /run/user is root-controlled, so accepting only this process's systemd
|
||||
-- runtime path still excludes shared or caller-supplied directories.
|
||||
-- runtime path avoids shell probes that fail in Hyprland's Lua runtime.
|
||||
local uid = effective_uid()
|
||||
return uid ~= nil and r == "/run/user/" .. uid
|
||||
end
|
||||
@@ -53,10 +52,8 @@ local SUPER_FLAG = runtime and (runtime .. "/omarchy-key-visualizer-super") or n
|
||||
|
||||
local function secure_write(path, content)
|
||||
if not runtime or (path ~= STATE_FILE and path ~= SUPER_FLAG) then return false end
|
||||
-- FileView watches the existing inode, so replacing the path on every key
|
||||
-- leaves Quickshell attached to an unlinked file. Updating in place keeps
|
||||
-- the watcher live. The containing runtime directory is private to the
|
||||
-- effective user and the two accepted paths are fixed above.
|
||||
-- FileView watches the existing inode. These are fixed paths inside the
|
||||
-- current user's private runtime directory, so update them in place.
|
||||
local f = io.open(path, "w")
|
||||
if not f then return false end
|
||||
f:write(content)
|
||||
@@ -206,9 +203,8 @@ local function emit_super()
|
||||
secure_write(SUPER_FLAG, down and "1" or "0")
|
||||
end
|
||||
|
||||
-- Create both files when the hook loads. This clears stale state after a
|
||||
-- compositor restart and gives FileView stable paths to watch before the
|
||||
-- first keyboard event arrives.
|
||||
-- Create stable files before Quickshell starts watching them and clear stale
|
||||
-- state left by a compositor restart.
|
||||
emit()
|
||||
emit_super()
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"schemaVersion": 1,
|
||||
"id": "felixzsh.key-visualizer",
|
||||
"name": "Key Visualizer",
|
||||
"version": "1.8.1",
|
||||
"version": "1.8.3",
|
||||
"author": "felixzsh",
|
||||
"description": "Shows the keys you press on screen. Great for keybinding tutorials, demos, and screencasts.",
|
||||
"kinds": [
|
||||
|
||||
Reference in New Issue
Block a user