Parse plain hyprctl binds output to survive Hyprland 0.56's broken JSON
Hyprland 0.56.0 emits invalid JSON from `hyprctl -j binds`: the new allow_input_capture field was added to the format template at slot 16 but its argument at position 8, shifting every value from has_description onward and landing unquoted strings in numeric slots. The jq parse failure emptied the keybindings menu down to the two static web-app entries — and the empty result got cached under a stable key, permanently. Parse the plain-format output instead, which is unaffected (and also immune to the older quotes-in-args JSON breakage), refuse to cache a record set with zero dynamic binds, and bump the cache version so poisoned caches invalidate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
79e9f38c0c
commit
994e4dfa7d
@@ -3,9 +3,8 @@
|
||||
# omarchy:summary=Display Hyprland keybindings defined in your configuration using an interactive search menu.
|
||||
|
||||
# Hyprland's Lua config provider currently reports Lua binds as dispatcher
|
||||
# __lua and code:... binds from hl.bind() as key="" and keycode=0 in
|
||||
# `hyprctl -j binds`. Keep a lightweight source-derived cache so the menu can
|
||||
# still show and dispatch those bindings.
|
||||
# __lua in `hyprctl binds`. Keep a lightweight source-derived cache so the
|
||||
# menu can still show and dispatch those bindings.
|
||||
declare -A LUA_BIND_KEY_MAP
|
||||
declare -A LUA_BIND_DISPATCHER_MAP
|
||||
declare -A LUA_BIND_ARG_MAP
|
||||
@@ -65,7 +64,7 @@ parse_keycodes() {
|
||||
'
|
||||
}
|
||||
|
||||
# Supplement `hyprctl -j binds` for Lua-only binds that Hyprland currently
|
||||
# Supplement `hyprctl binds` for Lua-only binds that Hyprland currently
|
||||
# reports as dispatcher __lua and without their original key for code: binds.
|
||||
build_lua_bind_cache() {
|
||||
local modmask description key dispatcher arg cache_key
|
||||
@@ -271,9 +270,24 @@ modmask_to_text() {
|
||||
dynamic_bindings() {
|
||||
local modmask key keycode description dispatcher arg modifiers cache_key
|
||||
|
||||
hyprctl -j binds |
|
||||
jq -r '.[] | [.modmask, (.key // ""), (.keycode // 0), (.description // ""), (.dispatcher // ""), (.arg // "") | tostring] | join("\u001f")' |
|
||||
# Parse the plain `hyprctl binds` output rather than `hyprctl -j binds`:
|
||||
# Hyprland 0.56.0 emits invalid JSON for binds (misaligned fields in
|
||||
# bindsRequest), and older versions broke on quotes in bind args.
|
||||
hyprctl binds | awk '
|
||||
function emit() {
|
||||
if (!seen) return
|
||||
seen = 0
|
||||
printf "%s\x1f%s\x1f%s\x1f%s\x1f%s\x1f%s\n", f["modmask"], f["key"], f["keycode"], f["description"], f["dispatcher"], f["arg"]
|
||||
}
|
||||
/^bind/ { emit(); seen = 1; delete f; next }
|
||||
seen && match($0, /^\t[a-z]+: /) { f[substr($0, 2, RLENGTH - 3)] = substr($0, RLENGTH + 1) }
|
||||
END { emit() }
|
||||
' |
|
||||
while IFS=$'\x1f' read -r modmask key keycode description dispatcher arg; do
|
||||
# Lua binds report their full display key ("SUPER + code:20"); the
|
||||
# modifiers are already carried separately in modmask.
|
||||
key="${key##* + }"
|
||||
|
||||
if [[ -z $key && $keycode != "0" ]]; then
|
||||
key="code:$keycode"
|
||||
fi
|
||||
@@ -421,23 +435,30 @@ prioritize_entries() {
|
||||
}
|
||||
|
||||
output_binding_records_uncached() {
|
||||
local dynamic
|
||||
|
||||
build_lua_bind_cache
|
||||
dynamic=$(dynamic_bindings)
|
||||
|
||||
{
|
||||
dynamic_bindings
|
||||
[[ -n $dynamic ]] && printf '%s\n' "$dynamic"
|
||||
static_bindings
|
||||
} |
|
||||
sort -u |
|
||||
parse_keycodes |
|
||||
parse_binding_records |
|
||||
prioritize_entries
|
||||
|
||||
# Fail when Hyprland reported no binds so the fallout of a broken hyprctl
|
||||
# is never cached.
|
||||
[[ -n $dynamic ]]
|
||||
}
|
||||
|
||||
keybindings_cache_key() {
|
||||
{
|
||||
printf 'v5\n'
|
||||
hyprctl -j devices 2>/dev/null | jq -r '.keyboards[].active_keymap' 2>/dev/null
|
||||
hyprctl -j binds 2>/dev/null
|
||||
printf 'v6\n'
|
||||
hyprctl devices 2>/dev/null | grep -F 'active keymap:'
|
||||
hyprctl binds 2>/dev/null
|
||||
} | sha256sum | awk '{ print $1 }'
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user