cat: 1.2.0 — click popup panel with the cat and CPU % (#103)

Clicking the bar widget now toggles an attached panel showing the same
cat glyph at panel size plus the CPU percentage, replacing the old
notification. The widget publishes its visible state (glyph, cpu,
color, pace) through the plugin's shared state store and the panel
re-renders on each update, keeping the big cat frame-synced with the
bar cat.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Robert Ward
2026-07-25 19:34:35 -04:00
committed by GitHub
co-authored by Claude Fable 5
parent 793249578c
commit 00da2cd291
4 changed files with 85 additions and 5 deletions
+11 -3
View File
@@ -9,12 +9,18 @@ colored to match your theme, or any color you pick.
| Field | Value |
| --- | --- |
| ID | `dotnetrob/cat` |
| Entries | Bar widget: `cat` |
| Entries | Bar widget: `cat`; panel: `panel` |
## Usage
Add the "Cat" widget to any bar from Settings → Bar → Add Widget. Click the
widget to show a notification with the current CPU percentage.
widget to toggle a popup panel showing the same cat at panel size — animating
in step with the bar cat — plus the current CPU percentage; click anywhere
outside the panel to dismiss it. The panel can also be toggled over IPC:
```sh
noctalia msg panel-toggle dotnetrob/cat:panel
```
## Settings
@@ -32,7 +38,9 @@ widget to show a notification with the current CPU percentage.
Every `poll_interval` seconds the widget reads `/proc/stat` to compute CPU
usage — no other files are read or written, nothing is downloaded, and no
processes are spawned. The cat's shape comes from a small custom icon font
processes are spawned. The panel does no sampling of its own: it mirrors the
bar widget through the plugin's in-process shared state store, so without a
cat widget in any bar it shows a sleeping cat with no CPU reading. The cat's shape comes from a small custom icon font
(`fonts/catwalk2.otf`) traced from the MIT-licensed
[CatWalk](https://store.kde.org/p/2055225) plasmoid by Driglu4it, which lets
it be recolored like normal bar text instead of a fixed-color image.
+18 -1
View File
@@ -100,10 +100,27 @@ local function resolveColor()
return "secondary"
end
-- The click panel (cat_panel.luau) runs in a separate runtime; it mirrors the
-- bar cat from this shared-state snapshot, republished whenever the visible
-- glyph, whole CPU percent, or color changes (so at most once per animation
-- frame, and only on sample/theme changes while idle).
local lastPublished = nil
local function publishState(pace, glyph, color)
local cpu = math.floor(cpuPercent)
local key = `{glyph}|{cpu}|{color}|{pace}`
if key == lastPublished then
return
end
lastPublished = key
noctalia.state.set("cat", { glyph = glyph, cpu = cpu, color = color, pace = pace })
end
local function render(pace)
local glyph = pace == "idle" and GLYPH_IDLE or RUN_GLYPHS[frameIndex]
local color = resolveColor()
publishState(pace, glyph, color)
local children = {
ui.label({ text = glyph, fontFamily = catFont, baseline = "inkCentered", fontSize = catSize, color = color }),
}
@@ -144,7 +161,7 @@ function update()
end
function onClick()
noctalia.notify(noctalia.tr("title"), `CPU {math.floor(cpuPercent)}%`)
noctalia.togglePanel("dotnetrob/cat:panel")
end
function onConfigChanged()
+44
View File
@@ -0,0 +1,44 @@
--!nonstrict
-- Cat panel: the popup opened by clicking the bar widget. Shows the same cat
-- glyph as the bar, just bigger, plus the CPU percentage.
--
-- The panel runs in its own Luau runtime, so it can't share locals with
-- cat.luau. Instead the bar widget publishes { glyph, cpu, color, pace } to
-- the plugin's shared state store under "cat" whenever any of them change,
-- and this script re-renders on every update — which is also what keeps the
-- big cat's run cycle in step with the bar cat, frame for frame. No ticks of
-- its own: with no widget publishing (state.get returns nil) it just shows
-- the sleeping cat with no reading.
local catFont = noctalia.loadFont("fonts/catwalk2.otf")
local PANEL_CAT_SIZE = 120
local snapshot = nil
local function render()
local glyph = snapshot and snapshot.glyph or "a"
local color = snapshot and snapshot.color or "secondary"
local cpuText = snapshot and `CPU {snapshot.cpu}%` or "CPU —"
panel.render(ui.column({ gap = 12, align = "center", padding = 24 }, {
ui.label({
text = glyph,
fontFamily = catFont,
baseline = "inkCentered",
fontSize = PANEL_CAT_SIZE,
color = color,
}),
ui.label({ text = cpuText, fontSize = 20, color = color }),
}))
end
noctalia.state.watch("cat", function(value)
snapshot = value
render()
end)
function onOpen()
snapshot = noctalia.state.get("cat")
render()
end
+12 -1
View File
@@ -1,6 +1,6 @@
id = "dotnetrob/cat"
name = "Cat"
version = "1.1.2"
version = "1.2.0"
plugin_api = 3
author = "DotNetRob"
license = "MIT"
@@ -9,6 +9,17 @@ icon = "paw"
description = "An animated running cat bar widget whose speed reflects CPU usage."
tags = ["bar", "animation", "system", "fun"]
# Popup opened by clicking the bar widget: the same cat, bigger, with the
# CPU percentage. Attached to the bar near the click; the host default
# dismiss-on-outside-click makes it behave like a transient popup.
[[panel]]
id = "panel"
entry = "cat_panel.luau"
width = 280
height = 240
placement = "attached"
open_near_click = true
[[widget]]
id = "cat"
entry = "cat.luau"