* Add procmon plugin with live process panel
New Noctalia plugin: bar widget shows CPU/RAM usage and process
count; floating panel has a sortable, searchable process table
with per-process kill. Background service samples ps and /proc
stats and publishes via plugin state.
* Throttle data-driven panel renders
Rebuild table at most every 500ms to stay within the panel update
CPU budget. User interactions still render immediately; only state
watches and the tick go through maybeRender().
* Update procmon deps and fix timestamp precision
Document head, grep, and cat as required commands. Correct refresh
interval default to 1000 ms. Sample refreshedAtMs in milliseconds.
* Add 9Router panel plugin
This commit introduces the initial version of the 9Router panel plugin.
It provides a Noctalia panel to manage 9Router model combos directly
from the bar, without requiring the web dashboard.
Key features:
- List, create, rename, and delete model combos.
- Reorder models within a combo via drag-and-drop.
- Change combo routing kind (fallback, round-robin, fusion).
- Search and filter combos.
- Supports 9Router dashboard authentication via CLI token or password.
Includes a bar widget showing connection status, a full UI panel,
and a background service to interact with the 9Router REST API.
Translations for English and Vietnamese are included.
* Rename 9Router Panel to 9Router Control
Update plugin IDs, IPC commands, and internal references.
* Quote shell args in service commands
Add shell_quote() for URLs, bodies, and file paths passed to
noctalia.runAsync. Declare required external commands in plugin.toml
and document them in the README.
* Add Quick Shell plugin for launcher commands
Introduces `/qs` launcher prefix to run shell commands in an interactive
terminal. Features dynamic shell completions (Fish/Bash), command
history, user snippets, and directory navigation.
* Rename quick-shell plugin to shell command plugin
* Update thumbnail.webp
* Document shell dependencies and filter completions by current word
Filter bash compgen completions to the current word being typed. Declare
`sh`, `ls`, `fish`, and `bash` as plugin dependencies.
Switch the system DNS between popular providers, custom servers, or the ISP
default, from a panel on the bar — no reconnect, no captive-portal re-run.
Detection reads the active connection's own ipv4.dns/ipv4.ignore-auto-dns
instead of guessing, so a manually configured resolver (LAN ones included)
shows as its provider and DHCP-assigned DNS shows as Default (ISP). A
singleton service entry owns detection/apply so multiple bars share one
engine.
Every bar gesture (left/right/scroll) is a manifest [widget.actions] default,
resolved through noctalia's own IPC registry, so any of them can be remapped
from the bar's own gesture settings without touching the plugin. The panel
also carries a DNS lookup tester: resolve a name against the active
provider's own address with dig/nslookup, to confirm a switch took effect or
that a provider blocks a domain.
Co-authored-by: nightwatch75 <nightwatch75@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* fix(arch-updater): tighten package list spacing and icon size
* fix(arch-updater): make Dismiss actually clear the pending list
* fix(arch-updater): make hitting update close the panel
* feat(arch-updater): add per-source icons to the package list header
* feat(arch-updater): add an activity graph to the panel
Tracks the pending-update count across recent checks and when the last
update ran, persisted to disk so it survives restarts. Off also stops
recording history, not just hiding it.
* feat(arch-updater): show per-point detail on activity graph hover
ui.graph has no pointer props of its own, so a row of ghost buttons
sits under the line as per-point hit targets, each with a native
tooltip. History entries now carry a timestamp and whether the check
followed an update run, so hovering a point says when it happened and
either its pending count or "Updated".
* fix(arch-updater): load activity history at startup, not on first check
loadHistoryState() only ran lazily inside recordCheck/recordUpdateRun,
so a freshly started service published an empty history until a check
completed, hiding the graph even when prior sessions had data on disk.
* fix(arch-updater): render activity graph with sharp points, not curves
* feat!: init plugin
* fix: fix widget not found on bar setting
* feat!: add creation folder for plugin
* feat!: add first version of Config Swap (simple modification test)
* feat!: update toml with new feature
* docs: prepare docs
* feat!: add more place for view preview
* feat!: add new page for store and allerady download
* docs: improve lisibility
* feat!: add description emplacement
* feat!: add wallpaper support for install and set
* docs: add more info to readme
* feat: add cp depedencie
* docs: add more info
* feat!: add trad support
* fix: change order for set wallpaper after change config
* feat!: add settingsPath for data.json
* feat!: add data.json creation if not exist
* docs: add more docs info
* feat!: rm useless preview image
* docs: improve docs
* feat!: change false description
* feat!: add shellQuote for protect bad command
* feat!: add path var in infoConfig.Change config type for infoConfig Type
* feat!: add secure delete config and confirmation for delete config
* feat!: add save function for save current config
* feat!: add welcome warning and confirmation switch
* feat!: add info for store section
* docs: add new info in setting section
* feat!: add resolve state dir for check all state dir possibility
* feat!: add english translation compatibility
* feat!: change thumbnail
* docs: add more information on the readme
* fix: rm useless button
* docs: add comment
* fix: add depedencie missing
* fix: rm death code
* fix: rm update interval not use
* feat!: add delete, save and apply protection, reject invalid name
* docs: add more info in info section
* feat!: add more charactere in match string in isDetect function
* fix: change wrong name function
* feat!: add protection for invalid name in dowload Config
* fix(plugin): Feed text encoding fix and panel UI improvements V1.0.2
* fix(plugin): Feed text encoding fix and panel UI improvements V1.0.2
* Add xdg-open dependency to plugin.toml
Added 'xdg-open' as a dependency for the plugin.
* Add spotify-lyrics plugin
* fix(spotify-lyrics): resolve race conditions and add plugin_api
* fix(spotify-lyrics): update plugin_api to 3
* fix(spotify-lyrics): resolve github actions validation errors
* fix(spotify-lyrics): resize thumbnail to 960x540 to fix validation error
* fix(spotify-lyrics): bump version to 1.2.1
* fix(spotify-lyrics): update namespace and replace misleading thumbnail
* fix(spotify-lyrics): declare runtime dependencies in plugin.toml and update README requirements
* feat(lyrics): implement dynamic panel width sizing
* Revert "feat(lyrics): implement dynamic panel width sizing"
This reverts commit ef91e6f9f688df7deeb41ba9e5c7606a4904b47a.
* feat(spotify-lyrics): implement dynamic panel width sizing
* fix(spotify-lyrics): correct target width pre-calculation for upcoming lines
* fix(spotify-lyrics): prevent vertical spill by enforcing maxLines=1
* fix(spotify-lyrics): implement dynamic height resizing to encapsulate wrapped text
* fix(spotify-lyrics): remove horizontal cap to prevent vertical spill
* fix(spotify-lyrics): restore minHeight and implement perfectly safe wrapping height prediction
* fix(spotify-lyrics): lock panel width and use vertical dynamic resizing exclusively
* fix(spotify-lyrics): implement dynamic font scaling and remove panel dimension animations
* fix(spotify-lyrics): restore robust dynamic height logic and discard font scaling
* refactor(spotify-lyrics): rewrite height estimation and clean up codebase
Root cause: the charUnits per-character width estimation consistently
underestimated real rendered widths because the 0.80 multipliers in
getLineWidth and getLinesCount cancelled each other out, making the
effective calculation ignore the safety margin entirely.
Fix: replaced the complex charUnits/toChars/getLineWidth machinery with
a simple #text / chars-per-line heuristic using a conservative 0.60x
character width factor. This reliably overestimates line count, ensuring
the panel always allocates enough height for wrapped text.
Quality of life improvements:
- Split monolithic render() into renderEmpty/renderPaused/renderPlaying
- Reduced update interval from 33ms (30 FPS) to 100ms (10 FPS)
- Removed file-read timer (reads every frame at lower FPS instead)
- Added clear section headers and inline documentation
- Removed all dead code (charUnits, toChars, getLineWidth, etc.)
* fix(spotify-lyrics): set panel height=280 in plugin.toml — the actual fix
The root cause of the lyrics spilling was never in the Lua code.
Noctalia panels are sized exclusively by plugin.toml, not by minHeight
on the column layout. Since we had removed width/height from plugin.toml
to make sizing 'dynamic', noctalia used a tiny default that couldn't
contain wrapped lyrics. minHeight on ui.column had zero effect on the
actual panel window size.
Set height=280 to comfortably fit 3 lyrics lines even when they wrap.
* feat(spotify-lyrics): add dynamic font scaling for long lyrics
Long lyrics (>40 chars) now get progressively smaller fonts:
- Every 15 chars beyond 40 reduces font by 2px
- Minimum font: 10px (panel) / 11px (widget)
This prevents vertical overflow regardless of container size by
ensuring long lines take up less vertical space when they wrap.
* fix(spotify-lyrics): fix plugin IDs and tilde path expansion
- Updated bar.luau to toggle correct panel ID
- Replaced ~ in noctalia.readFile with absolute path since Lua doesn't auto-expand it
- Updated plugin.toml height to 280 and id to noctalia/spotify-lyrics
* Fix UI bugs, implement reactive updates, and add album art
* Fix plugin manifest validation errors
* fix(spotify-lyrics): address PR review comments
- Change plugin id from noctalia/ to goatnath/ namespace
- Declare runtime dependencies: playerctl, python3, syncedlyrics
- Replace hardcoded /home/goatnath path with noctalia.expandPath()
- Add [[desktop_widget]] manifest entry for widget.luau
- Rewrite README to follow README_TEMPLATE.md structure
- Update all references to use corrected plugin id
---------
Co-authored-by: goatnath <aadinathkeshav1978@gmail.com>