diff --git a/pulsar-mouse/README.md b/pulsar-mouse/README.md index ba6522d..aab7494 100644 --- a/pulsar-mouse/README.md +++ b/pulsar-mouse/README.md @@ -30,7 +30,7 @@ noctalia msg plugins enable harveywuk/pulsar-mouse ### Bar Widget -Add the `bar` bar widget to your bar. Shows a battery glyph, icon-only, with a tooltip for the full status (percentage, charging, signal strength when available) - the glyph is the only thing rendered regardless of bar orientation; the glyph turns a secondary accent color while charging, or red once battery drops to the mouse's configured Low Power Mode threshold (see Controls Panel; falls back to 15% on a driver that doesn't expose that threshold, e.g. nordic.py). On a wired mouse (no battery to show) it stays visible as a plain neutral glyph rather than hiding, since it's the only way to open the controls panel - DPI/lighting controls still work on a wired mouse, only the Power tab doesn't apply. If `pulsar-mouse-gui` isn't installed or running at all, this widget still works, it just always reads a fresh value directly from the mouse instead of the GUI's cached one (see Data source). +Add the `bar` bar widget to your bar. Shows a battery glyph, icon-only, with a tooltip for the full status (percentage, charging, signal strength when available) - the glyph is the only thing rendered regardless of bar orientation; by default the glyph turns a secondary accent color while charging, or red once battery drops to the mouse's configured Low Power Mode threshold (see Controls Panel; falls back to 15% on a driver that doesn't expose that threshold, e.g. nordic.py) - each of those state colors is configurable, see Settings. On a wired mouse (no battery to show) it stays visible as a plain neutral glyph rather than hiding, since it's the only way to open the controls panel - DPI/lighting controls still work on a wired mouse, only the Power tab doesn't apply. If `pulsar-mouse-gui` isn't installed or running at all, this widget still works, it just always reads a fresh value directly from the mouse instead of the GUI's cached one (see Data source). ### Controls Panel @@ -77,16 +77,27 @@ The `bar` and `battery` entries both read battery percentage/charging/low-power- | Setting | Type | Default | Description | | --- | --- | --- | --- | | `glyph_size` | `int` | `16` | Glyph size, 10-32. | +| `normal_color` | `color` | `on_surface` | Glyph color at a normal battery level, and on a wired mouse. | +| `charging_color` | `color` | `secondary` | Glyph color while charging. | +| `warning_color` | `color` | `error` | Glyph color at or below the Low Power Mode threshold. | +| `error_color` | `color` | `error` | Glyph color when the mouse or the CLI can't be found. | ### Desktop Widget | Setting | Type | Default | Description | | --- | --- | --- | --- | -| `color` | `color` | `primary` | Accent color for the percentage text and progress bar. | +| `color` | `color` | `primary` | Accent color for the percentage text and progress bar at a normal battery level. | +| `charging_color` | `color` | `secondary` | Used while charging. | +| `warning_color` | `color` | `error` | Used at or below the Low Power Mode threshold. | +| `error_color` | `color` | `error` | Used when the mouse or the CLI can't be found. | | `show_progress` | `bool` | `true` | Shows or hides the battery-level progress bar. | | `show_percent` | `bool` | `true` | Turn off to rely on just the glyph and progress bar. | | `glyph_size` | `int` | `28` | Glyph size, 16-64. | +The four state colors are per-widget, so the bar and desktop widgets can differ. All of them (bar's `normal_color` included) sit behind the settings UI's **advanced** toggle, except the desktop widget's `color`. The defaults reproduce exactly what these were before they were configurable, so an existing setup looks unchanged until you touch one. + +The normal-state setting is called `normal_color` on the bar widget but `color` on the desktop widget. That asymmetry is deliberate: a bar widget's plugin settings share a TOML table with Noctalia's own per-widget presentation settings, where `color` is already taken ("Color role for this widget's icon and label"). A plugin declaring `color` there does not shadow it, it aliases it - one key backs both pickers, so setting either silently moves the other. Desktop widgets have no such clash, and renaming that one would break existing configs. + ## Notes - **No network access.** Every entry talks only to the local `pulsar-mouse` CLI (a spawned process, never a daemon) and, for the bar/desktop widgets, reads a local cache file. diff --git a/pulsar-mouse/bar.luau b/pulsar-mouse/bar.luau index da39082..7f9f5cf 100644 --- a/pulsar-mouse/bar.luau +++ b/pulsar-mouse/bar.luau @@ -17,9 +17,10 @@ -- -- Icon-only (no percentage label): battery level and charging state are -- already in the hover tooltip, so a bar-row number would just be the same --- fact twice. Just the Tabler "mouse-filled" glyph, tinted red by --- statusColor() same as before, swapping to "mouse-off" for a genuine --- error/no-mouse state. +-- fact twice. Just the Tabler "mouse-filled" glyph, tinted per state by +-- statusColor(), swapping to "mouse-off" for a genuine error/no-mouse state. +-- Each of those state colors is a setting (normal/charging/low/error), +-- defaulting to what they were previously hardcoded to. -- -- Signal quality has no synchronous getter (see gui.py's own comment on -- this) - it only arrives via an async hidraw event the GUI listens for, so @@ -57,6 +58,17 @@ local checkingCli = false local isVertical = false local glyphSize = noctalia.getConfig("glyph_size") +-- Per-state colors, defaulted in plugin.toml to the values these used to be +-- hardcoded to. Read once here rather than per-render, same as glyph_size - +-- a settings change reloads the widget anyway. +-- +-- `normal_color`, not `color` - see plugin.toml for why that name is +-- unusable on a bar widget. +local normalColor = noctalia.getConfig("normal_color") +local chargingColor = noctalia.getConfig("charging_color") +local warningColor = noctalia.getConfig("warning_color") +local errorColor = noctalia.getConfig("error_color") + local function statusGlyph(color) local name = (errorText ~= nil or percent == nil) and "mouse-off" or "mouse-filled" return ui.glyph({ name = name, size = glyphSize, color = color }) @@ -64,15 +76,15 @@ end local function statusColor() if errorText ~= nil then - return "error" + return errorColor end if charging then - return "secondary" + return chargingColor end if percent ~= nil and percent <= (lowPowerThreshold or LOW_POWER_DEFAULT) then - return "error" + return warningColor end - return "on_surface" + return normalColor end local function tooltipText() @@ -98,8 +110,10 @@ local function render() local glyph if not wireless then -- No battery to show, but still clickable - a wired mouse still has - -- DPI/lighting controls in the panel, just not the Power tab. - glyph = ui.glyph({ name = "mouse-filled", size = glyphSize, color = "on_surface" }) + -- DPI/lighting controls in the panel, just not the Power tab. Takes the + -- normal-state color: there's nothing wrong here, it's just permanently + -- the only state this mouse has. + glyph = ui.glyph({ name = "mouse-filled", size = glyphSize, color = normalColor }) barWidget.setTooltip(noctalia.tr("ui.wired")) else glyph = statusGlyph(statusColor()) diff --git a/pulsar-mouse/desktop.luau b/pulsar-mouse/desktop.luau index 5d760bf..a888449 100644 --- a/pulsar-mouse/desktop.luau +++ b/pulsar-mouse/desktop.luau @@ -25,6 +25,11 @@ local LOW_POWER_DEFAULT = 15 -- used when the driver has no low-power-threshold -- getter (e.g. nordic.py) or it hasn't been read yet local color = noctalia.getConfig("color") +-- The other three states. Defaulted in plugin.toml to the values these were +-- previously hardcoded to, so an existing install renders identically. +local chargingColor = noctalia.getConfig("charging_color") +local warningColor = noctalia.getConfig("warning_color") +local errorColor = noctalia.getConfig("error_color") local showProgress = noctalia.getConfig("show_progress") local showPercent = noctalia.getConfig("show_percent") local glyphSize = noctalia.getConfig("glyph_size") @@ -38,13 +43,13 @@ local checkingCli = false local function statusColor() if errorText ~= nil then - return "error" + return errorColor end if charging then - return "secondary" + return chargingColor end if percent ~= nil and percent <= (lowPowerThreshold or LOW_POWER_DEFAULT) then - return "error" + return warningColor end return color end @@ -77,7 +82,7 @@ local function render() if errorText ~= nil then -- Diagnostic, not decorative - stays visible even with show_percent off, -- since otherwise a broken setup would just silently show a bare glyph. - table.insert(rows, ui.label({ key = "status", text = errorText, fontSize = 12, color = "error" })) + table.insert(rows, ui.label({ key = "status", text = errorText, fontSize = 12, color = errorColor })) elseif showPercent and percent == nil then table.insert(rows, ui.label({ key = "status", text = "--", fontSize = 20, color = "outline" })) elseif showPercent then diff --git a/pulsar-mouse/plugin.toml b/pulsar-mouse/plugin.toml index 073d7c1..996450f 100644 --- a/pulsar-mouse/plugin.toml +++ b/pulsar-mouse/plugin.toml @@ -19,7 +19,7 @@ id = "harveywuk/pulsar-mouse" name = "Pulsar Mouse" -version = "1.6.1" +version = "1.7.0" plugin_api = 9 author = "harveywuk" license = "MIT" @@ -41,6 +41,50 @@ entry = "bar.luau" max = 32 step = 1 + # Per-state glyph colors. The defaults reproduce what used to be hardcoded, + # so an existing install looks identical until someone changes one. Marked + # advanced since the interesting knob for most people is glyph_size - these + # are for matching a specific colorscheme. + # + # Deliberately NOT called `color`: a bar widget's settings share one TOML + # table with Noctalia's own per-widget presentation settings, and `color` + # is already taken there (the "Color role for this widget's icon and + # label" one). Declaring it here doesn't shadow that setting, it aliases + # it - one `color = ...` key ends up backing both pickers, so setting + # either silently moves the other. The desktop widget has no such clash, + # which is why its equivalent is still plain `color`. + [[widget.setting]] + key = "normal_color" + type = "color" + label_key = "settings.normal_color.label" + description_key = "settings.normal_color.description" + default = "on_surface" + advanced = true + + [[widget.setting]] + key = "charging_color" + type = "color" + label_key = "settings.charging_color.label" + description_key = "settings.charging_color.description" + default = "secondary" + advanced = true + + [[widget.setting]] + key = "warning_color" + type = "color" + label_key = "settings.warning_color.label" + description_key = "settings.warning_color.description" + default = "error" + advanced = true + + [[widget.setting]] + key = "error_color" + type = "color" + label_key = "settings.error_color.label" + description_key = "settings.error_color.description" + default = "error" + advanced = true + [[panel]] id = "controls" entry = "panel.luau" @@ -61,6 +105,32 @@ entry = "desktop.luau" description_key = "settings.color.description" default = "primary" + # The other three states (see bar's copy of these) - `color` above stays + # non-advanced since it's the one that was always here. + [[desktop_widget.setting]] + key = "charging_color" + type = "color" + label_key = "settings.charging_color.label" + description_key = "settings.charging_color.description" + default = "secondary" + advanced = true + + [[desktop_widget.setting]] + key = "warning_color" + type = "color" + label_key = "settings.warning_color.label" + description_key = "settings.warning_color.description" + default = "error" + advanced = true + + [[desktop_widget.setting]] + key = "error_color" + type = "color" + label_key = "settings.error_color.label" + description_key = "settings.error_color.description" + default = "error" + advanced = true + [[desktop_widget.setting]] key = "show_progress" type = "bool" diff --git a/pulsar-mouse/translations/en.json b/pulsar-mouse/translations/en.json index 2781052..d16d66a 100644 --- a/pulsar-mouse/translations/en.json +++ b/pulsar-mouse/translations/en.json @@ -1,18 +1,34 @@ { "settings": { + "charging_color": { + "description": "Used while the mouse is charging", + "label": "Charging Color" + }, "color": { "description": "Accent color for the percentage text and progress bar", "label": "Color" }, + "error_color": { + "description": "Used when the mouse or the pulsar-mouse CLI can't be found", + "label": "Error Color" + }, "glyph_size": { "label": "Glyph Size" }, + "normal_color": { + "description": "Glyph color at a normal battery level, and on a wired mouse", + "label": "Normal Color" + }, "show_percent": { "description": "Turn off to rely on just the glyph (and progress bar, if shown)", "label": "Show Percentage Text" }, "show_progress": { "label": "Show Progress Bar" + }, + "warning_color": { + "description": "Used at or below the mouse's Low Power Mode threshold", + "label": "Low Battery Color" } }, "ui": {