fix(keybind-cheatsheet): stage the Hyprland Lua refresh across CPU budget windows - #668
Merged
ItsLemmy merged 1 commit intoSep 9, 2026
Conversation
Noctalia-CI
marked this pull request as draft
September 8, 2026 14:45
Contributor
|
The description now contains the required template structure. |
Contributor
|
CC @cheerfulScumbag: this pull request was automatically moved to draft until you have had a chance to look at it. It will be marked ready for review automatically once you reply here. |
sboo
marked this pull request as ready for review
September 8, 2026 14:57
ItsLemmy
marked this pull request as draft
September 8, 2026 18:13
cheerfulScumbag
approved these changes
Sep 9, 2026
cheerfulScumbag
left a comment
Contributor
There was a problem hiding this comment.
looks good to me!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Plugin
kenn/keybind-cheatsheetplugin.toml)What it does
Fixes the panel never loading on mid-size Hyprland Lua configs (#663).
Root cause: the completion callback of
noctalia.runAsync("hyprctl binds -j", ...)performed the entire refresh inside one callback — JSON-decoding the full payload (~40 KB / 88 bindings on a real-world config), building the binding list, runningthe Lua category scan (
scanHyprLua), categorizing, and writing the cache. Noctalia's Luau host enforces a hard ~25 ms CPU budget per callback; when the chain exceeds it, the callback is killed beforefinishRefreshpublishes anything, so the panel stays on "Reading keybinds…" forever, no error is ever shown (the abort is only in the hostlog), and
bindings-cache.jsonis never written, every shell start re-fails.Fix: stage the work across multiple state-watch callbacks, reusing the same state-ping pattern the Niri parser and the self-test already use. The refresh now runs decode → build bindings in slices (
HYPR_BINDING_SLICE = 16) → Lua categoryscan → categorize in slices → publish + cache write, each in its own budget window. Stale pings are dropped via generation/request/step guards; all existing error paths (hyprctl missing/failed, invalid JSON, failed-refresh retention) are preserved.
This is the same CPU-budget failure class as #606; v0.2.6 (PR #639) fixed it by deferring the work into the async completion callback, this PR stages that callback itself.
Authorship disclosure: I am a software developer, but I have no prior experience with Luau. The initial implementation of this patch was produced with AI assistance, then debugged and iterated against real hardware. I reviewed the final diff block by block.
External dependencies
None added.
hyprctlremains the plugin's only dependency (already declared inplugin.toml), used only by the Hyprland Lua path. This PR adds no network calls, no new filesystem writes, and no new spawned processes, only additionalnoctalia.statekeys used to stage the existing refresh.Testing
Tested on Niri
Tested on Hyprland
Tested on Sway
Tested on another compositor:
Noctalia version tested against: 5.0.1-1.1 (Arch/CachyOS package)
Plugin API level: 9
Reproduction machine: CachyOS, Hyprland 0.56.2-2.1, AMD Ryzen 5 5600, native Lua config (
~/.config/hypr/hyprland.luarequiringconfig/*.lua, nohyprland.conf), 88 bindings,hyprctl binds -j= 40,072 bytes.Before this patch: panel stuck on "Reading keybinds…" forever; host log showed
script callback 'async command callback' exceeded its CPU budget(and, with the scan stage alone, the same abort at the categorization loop);bindings-cache.jsonnever written; IPC refresh returnedok: dispatched 1but the snapshot never landed.After this patch: panel populates; refresh works via IPC, panel toggle, and after a full shell restart (startup path); no budget errors across repeated refreshes and hot reloads;
bindings-cache.jsonwritten.noctalia msg plugin kenn/keybind-cheatsheet:data all self-test→ hypr_conf 5/5, hypr_lua 4/4, mango 9/9, niri 5/5,passed: true.Two-machine differential from [keybind-cheatsheet][BUG] Panel stuck on "Reading keybinds…" — async
hyprctl binds -jcallback exceeds CPU budget on mid-size Hyprland Lua configs #663 (identical software, near-identicalbinds.lua): 88 binds / 40,072 B failed pre-patch on Ryzen 5 5600; 82 binds / 37,381 B worked on Ryzen 9 7900X3D.Screenshots / Videos
Before/after captures: (1) panel stuck on "Reading keybinds…" pre-patch, (2) panel


populated post-patch.
Checklist
idafter the/inplugin.tomlexactly.plugin.toml,README.md,thumbnail.webp, andtranslations/en.json.README.mdfollows theREADME template, documents every entry id and dependency, and includes exact panel IPC commands and launcher prefixes where applicable.
thumbnail.webpis present and relevant; for a new plugin I created it with the thumbnail generator, and for an update I regenerated it with the generator if the visual identity or user-facing appearance changed.(Unchanged in this PR — no visual identity change, so not regenerated.)
versionfollows semver and is bumped in this PR;plugin_apiis the oldestAPI level this plugin requires. (0.2.6 → 0.2.7;
plugin_apistays 9.)understand that language well enough to review and maintain it (no unreviewed machine/LLM translations).
catalog.toml; CI generates it.keybind-cheatsheet/:service.luau+plugin.tomlversion bump only.)Code review attestation
Plugins run as trusted, unsandboxed Luau in the user's session. Confirm:
description above accounts for.
licensedeclared inplugin.toml. (MIT, unchanged.)