Feature/ibiticu/plugin new cpu bars#48
Open
ioandev wants to merge 3 commits into
Open
Conversation
added 2 commits
July 18, 2026 19:52
A bar widget drawing one vertical bar per logical core, filling bottom-up from noctalia.systemStats().cpu.cores, so an unbalanced load or a single pegged thread stays visible where an averaged percentage would hide it. - Bars are composed from ui.column/ui.box; there is no meter primitive. Height is strictly proportional with no minimum, so an idle core shows an empty track. - Colours are theme role tokens, so they follow the active scheme; a core at or above the threshold (default 90%) switches to the warning role. - Rotates for a vertical bar: cores stack downward, each bar fills from the left. - Updates once a second aligned to the top of the second. The host adds a fixed per-widget phase to timer restarts and the script runs a moment after the timer fires, so the interval is corrected each tick from an observed round trip via noctalia.nowMs(), biased a few ms past the boundary to stay on the correct side of the second. Requires plugin API 5 for noctalia.systemStats() and noctalia.nowMs().
Adds a validator rule and its unit tests. Two failure modes that CI could not previously see: - Reading a key that plugin.toml does not declare. The host only resolves manifest-declared keys, so a typo in getConfig() yields nil rather than an error — the setting silently does nothing. - Declaring a setting nothing reads, which puts a dead control in the user's settings UI. The unused-setting half is skipped for plugins that call getConfig with a non-literal argument, since a key read through a variable cannot be seen and flagging it would be a false positive. Six plugins in this repo do that. The undeclared-read half still applies to them. Factors the existing Luau comment/string masking out of obsolete_config_accessors() into mask_luau(mask_strings=...), because reading a key literal needs comments masked but strings visible. obsolete_config_accessors() keeps its previous behaviour. Verified against all 24 plugins before wiring it in: no existing plugin trips either half, so this does not break CI for anyone. Mutation-tested — disabling the undeclared-read check, and disabling comment masking so a commented-out getConfig counts as a read, both fail the new tests.
Author
|
There is a problem with this plugin. Every time a change in the bar takes place, the plugin gets reloaded and it waits a second between it redraws. I will fix.
|
The widget vanished for over a second whenever the bar reloaded. Every bar reload recreates the widget, and update() called setVisible(false) whenever cpu.cores came back empty, so a momentary gap in the data became a visible disappearance rather than a stale frame. Keep whatever is already drawn instead, and only hide when nothing has ever been rendered — the genuine first-tick case, where there is no previous reading to diff against. The host half of this is fixed separately in noctalia: releasing the last per-core reference used to clear the samples, and recreating a widget drops the refcount to zero for a few milliseconds. Either fix alone hides the symptom; this one also makes the widget robust against any future gap.
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
ioandev/cpu-barsplugin.toml)What it does
Depends on noctalia-dev/noctalia#3515, which adds the
noctalia.systemStats()andnoctalia.nowMs()bindings this plugin needs and raises the plugin API to 5. This cannot merge before that ships — until thenplugin_api = 5is too new and the plugin will not load. Happy to keep this as a Draft until #3515 lands.Draws one thin vertical bar per logical CPU core in the bar, each filling from the bottom in proportion to that core's usage over the last second. A core at or above the warning threshold (90% by default) switches to the warning colour.
The point is what an averaged CPU percentage hides. A single pegged thread and mild uniform load across every core produce the same "8%" readout, but they mean very different things — one is a runaway process, the other is a machine working normally. Per-core bars make that visible at a glance, in roughly the width of a normal bar widget.
Idle cores show an empty track rather than a sliver, so a busy core stands out instead of blending into a solid line. Colours are theme role tokens, so they follow the active colour scheme, including light/dark switches. On a vertical bar the widget rotates: cores stack downward and each bar fills from the left.
Eight settings: bar width, gap, length, warning threshold, bar/warning/track colours, and an icon toggle.
External dependencies
None. No network calls, no spawned processes, no filesystem writes. Per-core usage comes from the host via
noctalia.systemStats(), which reads/proc/stat, so the plugin is Linux-only.Testing
Added the widget to a bar and exercised it end-to-end against a local build of noctalia#3515.
Correctness of the per-core mapping was checked against ground truth rather than eyeballed: load was pinned to known cores with
tasksetand the matching bars confirmed, so bar N really is core N-1. Cores 3 and 17 pinned lit exactly bars 4 and 18; repeated with cores 0-3 + 12-13, and with 6/7/15. Partial load viastress-ng --cpu-loadat 100% / 75% / 55% / 25% produced proportional bar heights, and the warning colour appeared only on bars at or above the threshold, clearing when the load stopped.All eight settings were changed and confirmed to take effect: bar width, gap and length visibly resize the widget, and lowering the warning threshold to 50 turned the mid-load bars red. The tooltip was checked for the total plus the per-core breakdown. The wallpaper was changed mid-run — the palette here is wallpaper-derived — and the bars followed the new scheme, confirming the role tokens resolve live rather than being sampled once.
Tick alignment was measured by logging
noctalia.nowMs() % 1000each update: it converges within a couple of ticks and holds at 4-16 ms past the second, one update per second with no skipped or doubled seconds.Not exercised: the vertical-bar orientation. The code path exists —
barWidget.isVertical()swaps the container and fills each bar from the left — but the test bar was horizontal throughout, so I cannot claim it works. Also untested: machines with a very low or very high core count (this is a 24-core box), and CPU hotplug.v5.0.0-beta.3-35-ge83f7ab59b42Screenshots / Videos
To attach: the widget under mixed load — some cores pegged and red, some at partial height, the rest idle — plus an idle shot showing empty tracks.
Checklist
idafter the/inplugin.tomlexactly.plugin.toml,README.md,thumbnail.webp, andtranslations/en.json.README.mdfollows the README template, documents every entry id and dependency, and includes exact panel IPC commands and launcher prefixes where applicable.thumbnail.webpwith the thumbnail generator.versionfollows semver and is bumped in this PR;plugin_apiis the oldest API level this plugin requires.catalog.toml; CI generates it.This PR adds only
translations/en.json. No other locales are included, so there is nothing machine-translated to review.Code review attestation
licensedeclared inplugin.toml.The plugin is a single 148-line Luau file with no dependencies and no I/O of any kind: it reads
noctalia.systemStats()andnoctalia.getConfig(), builds aui.rowof boxes, and sets a tooltip. The only non-obvious part isscheduleNextTick(), which corrects its own update interval to land on the second boundary; it is commented in place, since the reason is not guessable from the code.