Skip to content

Add Battery widget plugin - #178

Merged
ItsLemmy merged 11 commits into
noctalia-dev:mainfrom
Yocraft-2000:battery-widget
Aug 1, 2026
Merged

Add Battery widget plugin#178
ItsLemmy merged 11 commits into
noctalia-dev:mainfrom
Yocraft-2000:battery-widget

Conversation

@Yocraft-2000

Copy link
Copy Markdown
Contributor

Plugin

  • Id: yocraft/battery-widget
  • New plugin
  • Update to an existing plugin (version bumped in plugin.toml)

What it does

Desktop/Lockscreen widget to show battery.

External dependencies

None.

Testing

  • Tested on Niri
  • Tested on Hyprland
  • Tested on Sway
  • Tested on another compositor:
  • Noctalia version tested against: v5.0.0
  • Plugin API level: 19

Screenshots / Videos

image

Checklist

  • The directory name matches the part of id after the / in plugin.toml exactly.
  • It ships plugin.toml, README.md, thumbnail.webp, and translations/en.json.
  • README.md follows the
    README template, documents
    every entry id and dependency, and includes exact panel IPC commands and launcher prefixes where applicable.
  • I created thumbnail.webp with the thumbnail generator.
  • version follows semver and is bumped in this PR; plugin_api is the oldest API level this plugin requires.
  • Every non-English translation in this PR uses a locale supported by Noctalia core, and I can read, write, and
    understand that language well enough to review and maintain it (no unreviewed machine/LLM translations).
  • I did not edit catalog.toml; CI generates it.
  • This PR touches exactly one plugin directory.

Code review attestation

Plugins run as trusted, unsandboxed Luau in the user's session. Confirm:

  • The code is readable and not obfuscated, minified, or generated.
  • It does not download and execute remote code.
  • Every network call, filesystem write, and spawned process is something the description above accounts for.
  • I have the right to publish this code under the license declared in plugin.toml.

@Yocraft-2000

Yocraft-2000 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

error: battery-widget/README.md: add a short introduction below the title explaining what the plugin does

There is one so idk...

edit: fixed, the description needs at least 8 words

@Yocraft-2000

Copy link
Copy Markdown
Contributor Author

Also plugin settings don't hot reload idk if that's something I did wrong or if it's a bug

@ItsLemmy

ItsLemmy commented Aug 1, 2026

Copy link
Copy Markdown
Contributor
  1. non-blocking - battery-widget/widget.luau:81

    The refresh path builds a shell string and runs it through noctalia.runAsync:
    "cat " .. path .. batName .. "/capacity " .. path .. batName .. "/status".
    noctalia.runAsync(string) executes via /bin/sh -lc, so batName is interpolated
    into a shell command unescaped. batName comes from the free-form "battery_name"
    string setting when "battery" is set to "custom" (battery-widget/widget.luau:17),
    so shell metacharacters in that value are executed.

    This is user-configures-own-session only, not a remote or cross-user attack
    surface, so it is not a trust blocker. It is still avoidable: the plugin API
    exposes noctalia.readFile, which reads /sys/class/power_supply//capacity
    and /status directly and removes both the shell interpolation and a spawned
    subprocess every refresh interval. If the subprocess is kept, quote and escape
    the value the way battery-graph/battery-desktop.luau:6 does.

  2. non-blocking - battery-widget/widget.luau:117

    The chunk defines update() but never renders once at load. The host arms a
    repeating timer whose first fire is one full interval away, and setUpdateInterval
    on battery-widget/widget.luau:1 raises that interval to refresh_interval (default
    60s). Result: after the widget is added, and after every script reload, nothing is
    drawn for up to 60 seconds. Calling refreshBattery() at the end of the chunk fixes
    the cold start.

  3. non-blocking - battery-widget/widget.luau:1

    setUpdateInterval (line 1) and getBatName() (line 111) are evaluated once at chunk
    load, unlike layout, show_glyph, show_label, hide_plugged, hide_full, color,
    warning_color and charging_color, which are read inside render()/getColor() and
    therefore track settings live. So "refresh_interval", "battery" and "battery_name"
    only take effect when the chunk is reloaded. This is very likely the "plugin
    settings don't hot reload" behavior reported in the PR conversation. Moving both
    calls inside update() matches what battery-graph/battery-desktop.luau:18 does and
    makes all settings live.

@ItsLemmy
ItsLemmy merged commit 6db8390 into noctalia-dev:main Aug 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants