From e8139eee2d0ea1e8a2f32db257546523971332b4 Mon Sep 17 00:00:00 2001 From: carlos Date: Tue, 6 Oct 2026 21:23:34 -0400 Subject: [PATCH] plugins: add GoXLR 1.0.0 Land the #62 submission from https://github.com/millerjryan/ryoku-goxlr (pinned at 3507699): a bar capsule for the goxlr-utility daemon with a flash-on-change, mic mute, and per-channel volumes in the panel. The payload is upstream-verbatim; the product manifest and registry row were generated with tools/pack-product.py. The catalogue preview is the contributor's own live capture from the submission issue. Note: New: GoXLR bar plugin in the Ryostore. --- plugins/goxlr/.gitignore | 3 + plugins/goxlr/AGENTS.md | 84 ++++ plugins/goxlr/CLAUDE.md | 4 + plugins/goxlr/LICENSE | 21 + plugins/goxlr/README.md | 104 +++++ plugins/goxlr/assets/preview-panel.png | Bin 0 -> 108273 bytes plugins/goxlr/assets/preview-widget.png | Bin 0 -> 1289 bytes plugins/goxlr/bin/mic-mute-toggle | 31 ++ plugins/goxlr/bin/volume-step | 38 ++ plugins/goxlr/content/Panel.qml | 238 ++++++++++++ plugins/goxlr/content/Widget.qml | 120 ++++++ plugins/goxlr/manifest.json | 192 ++++++++++ plugins/goxlr/product-manifest.json | 113 ++++++ plugins/goxlr/service/Main.qml | 487 ++++++++++++++++++++++++ plugins/registry.json | 30 ++ 15 files changed, 1465 insertions(+) create mode 100644 plugins/goxlr/.gitignore create mode 100644 plugins/goxlr/AGENTS.md create mode 100644 plugins/goxlr/CLAUDE.md create mode 100644 plugins/goxlr/LICENSE create mode 100644 plugins/goxlr/README.md create mode 100644 plugins/goxlr/assets/preview-panel.png create mode 100644 plugins/goxlr/assets/preview-widget.png create mode 100755 plugins/goxlr/bin/mic-mute-toggle create mode 100755 plugins/goxlr/bin/volume-step create mode 100644 plugins/goxlr/content/Panel.qml create mode 100644 plugins/goxlr/content/Widget.qml create mode 100644 plugins/goxlr/manifest.json create mode 100644 plugins/goxlr/product-manifest.json create mode 100644 plugins/goxlr/service/Main.qml diff --git a/plugins/goxlr/.gitignore b/plugins/goxlr/.gitignore new file mode 100644 index 00000000..b8eb3e3c --- /dev/null +++ b/plugins/goxlr/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +*.log +*.tmp diff --git a/plugins/goxlr/AGENTS.md b/plugins/goxlr/AGENTS.md new file mode 100644 index 00000000..793fa88e --- /dev/null +++ b/plugins/goxlr/AGENTS.md @@ -0,0 +1,84 @@ +# Agent guide for the goxlr plugin + +This folder is a Ryoku shell plugin. If you are an AI agent editing it, follow +every rule below. They are the same rules `ryoku plugin validate` enforces, so +work that breaks one will not install. This file is self-contained: you do not +need any other document to work here. + +## The rules + +R1 Place. A plugin is one folder named after its id. Author it under +`$(xdg-user-dir DOCUMENTS)/ryoku-plugins//` (fallback `~/ryoku-plugins//`); +`ryoku plugin new ` creates it there. Never write into +`~/.local/share/ryoku/plugins/` (the store's install root, receipt-owned) or +`~/.config/quickshell/` (the shipped shell). + +R2 Shape. `manifest.json` at the root; `service/Main.qml` (logic, no UI); +`content/Widget.qml` (the one view); optional `content/Panel.qml` (a bar panel); +`README.md`; `LICENSE`; `assets/preview-widget.png` (a real capture); scripts +only under `bin/` with a shebang and the exec bit. Every extra file listed in +manifest `files`. + +R3 Id. Lowercase `[a-z0-9][a-z0-9-]*`, unique, not a built-in widget id. + +R4 Imports. Only `QtQuick*`, `Quickshell*`, `Ryoku.PluginKit`, +`Ryoku.PluginKit.Singletons`, and files inside the plugin folder. Never +`shell.*`, `Ryoku.Ui*` internals, or a relative import that climbs out of the +folder. + +R5 Settings. Declared in `metadata.settings` (types the bar renders: toggle, +choice, multi, int, text); read through `pluginApi.pluginSettings` behind a +default; written only through `pluginApi.saveSetting(key, value)`. Never edit +`shell.json` or `plugins.json` directly. + +R6 Commands. Every external program the plugin runs is either in its own `bin/` +or listed in `dependencies.commands`. No `sudo`, `doas`, `su`. A privileged +action is allowed only through `pkexec`, only on an explicit click, only when +listed in manifest `capabilities.privileged` (exact command strings) and +explained in README. + +R7 Network. Every host the plugin talks to is listed in +`capabilities.network`. No `curl … | sh`, no downloading and running code. + +R8 Files. Write only under `pluginApi.stateDir` +(`$XDG_STATE_HOME/ryoku/plugins/`), `$XDG_CACHE_HOME/ryoku/plugins/`, or +a temp dir. Never touch `~/.ssh`, `/etc`, shell rc files, or another plugin's +folder. + +R9 Shell. No `sh -c` with a string built from settings or program output +(injection). Pass argv arrays. + +R10 Secrets and binaries. No tokens, keys or credentials in the tree; no +compiled binaries (ELF/Mach-O/.so); scripts only. + +R11 Honesty. `official` is never true for a community plugin. `author` is +`Name `. README says what runs, what it reads, what it writes, and every +privileged/network capability. + +## The workflow + +1. `ryoku plugin new ` scaffolds this folder (already done). +2. Edit: `service/Main.qml` for logic, `content/Widget.qml` for the view, and + `content/Panel.qml` for the bar panel. Capture `assets/preview-widget.png`. +3. `ryoku plugin validate ` and fix every blocking finding (warnings are + advisory but read them). +4. `ryoku plugin add --bar --yes` to install it, then verify it on the bar + and under **QS Bar Settings > Community**. +5. `ryoku plugin share ` ONLY when the user asks to publish. Never share a + plugin unless asked. + +## What the host sets + +Every entry point receives, from the host: `pluginApi` (see below), `s` (a scale +factor), `active`, `density`, and `widthBudget`. Read them; never assign them. + +`pluginApi` exposes: + +- `mainInstance`: the live `service/Main.qml` instance every view shares. +- `pluginSettings`: the resolved settings object; read behind a default. +- `pluginDir`: this plugin's folder. +- `stateDir`: `$XDG_STATE_HOME/ryoku/plugins/`; the only place to write. +- `saveSetting(key, value)`: persist one setting. +- `panelOpen` (bool), `openPanel()`, `closePanel()`, `togglePanel()`: the bar + panel controls (present but inert off the bar). The sanctioned widget click is + `onClicked: pluginApi.togglePanel()`. diff --git a/plugins/goxlr/CLAUDE.md b/plugins/goxlr/CLAUDE.md new file mode 100644 index 00000000..3c35c327 --- /dev/null +++ b/plugins/goxlr/CLAUDE.md @@ -0,0 +1,4 @@ +# CLAUDE.md + +Read `AGENTS.md` in this folder before editing anything here. +It holds every rule this plugin must follow and the full authoring workflow. diff --git a/plugins/goxlr/LICENSE b/plugins/goxlr/LICENSE new file mode 100644 index 00000000..4eb437ae --- /dev/null +++ b/plugins/goxlr/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 josh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/goxlr/README.md b/plugins/goxlr/README.md new file mode 100644 index 00000000..cb48a363 --- /dev/null +++ b/plugins/goxlr/README.md @@ -0,0 +1,104 @@ +# GoXLR + +A Ryoku shell plugin (`goxlr`) that ports the core of the Noctalia GoXLR +plugin: a bar capsule showing one channel's volume, a mic-mute toggle, a +flash-style notification when any channel changes, and per-channel volume +controls in the panel. It talks to the [goxlr-utility](https://github.com/GoXLR-on-Linux/goxlr-utility) +daemon's local HTTP API — the same daemon the official GoXLR app and the +Noctalia plugin use. + +## Requirements + +- `goxlr-utility`'s `goxlr-daemon` running and reachable (default + `localhost:14564`). +- `curl` and `jq` on `PATH` (listed in `dependencies.commands`). + +## What it does (and deliberately does not) + +Ported: + +- **Bar capsule**: shows one configured channel's volume (icon, value, or + both), coloured to reflect connection/mute state. +- **Flash as OSD substitute**: Ryoku bar plugins don't get an OSD surface the + way Noctalia widgets can, so instead of a popup, the capsule itself + temporarily switches to show whichever channel just changed — glyph, name, + and new value — for `flashTimeoutMs`, then reverts to the configured + channel. This happens for changes from any source: the GoXLR hardware + itself, the vendor app, or another copy of this plugin on a second + monitor. +- **Mic mute**: right-click the capsule to toggle the mic's cough/mute. +- **Per-channel volumes**: left-click opens the panel, which lists every + channel with a slider and shows live mute state. + +Not ported (out of scope for this port): routing matrix, effects/FX +presets, sampler, lighting, and profile switching. These are higher-risk, +higher-surface-area features that don't fit a single bar capsule + panel; +they're better served by the full GoXLR app for now. + +## Settings + +| key | type | default | description | +| ---------------- | ------ | -------------- | ------------------------------------------------------------ | +| host | text | `localhost` | Daemon host | +| port | int | `14564` | Daemon port | +| refreshMs | int | `1000` | Poll interval while the panel is closed (ms) | +| volumeDisplay | choice | `percent` | Show volumes as percent or raw (0-255) | +| channel | choice | `Mic` | Channel shown on the bar | +| display | choice | `glyph_value` | Bar display: icon only, icon + value, or value only | +| glyph | text | `◆` | Bar icon: a literal character/emoji, or (with `glyphStyle: icon`) a [Material Symbols](https://fonts.google.com/icons) ligature name like `mic`; the mute icon stays `✖` | +| glyphStyle | choice | `text` | Interpret `glyph` as literal text/emoji, or as a Material Symbols icon name | +| showChannelName | toggle | `false` | Prefix the bar value with the channel name | +| scrollStep | int | `2` | Volume change per scroll notch on the capsule (%) | +| muteIndicator | toggle | `true` | Change colour while the shown channel is muted | +| hideWhenAbsent | toggle | `false` | Hide the capsule entirely when no GoXLR is connected | +| flashEnabled | toggle | `true` | Flash the capsule when any channel's volume or mute changes | +| flashTimeoutMs | int | `1500` | How long the flash stays up (ms) | +| flashPollMs | int | `200` | Poll interval while watching for changes to flash (ms) | + +## Usage + +- **Left click** the capsule: open/close the panel (per-channel volume + sliders and mute states). +- **Right click** the capsule: toggle mic mute. +- **Scroll** over the capsule: adjust the configured channel's volume by + `scrollStep`. + +## `bin/` scripts (for compositor keybinds) + +Two standalone scripts talk to the daemon directly over HTTP, independent of +the plugin runtime, for binding to Hyprland/compositor keybinds: + +- `bin/mic-mute-toggle` — toggles the mic's cough/mute. +- `bin/volume-step ` — nudges a channel's volume by a + signed percent (defaults: `Mic 2`). + +Both honour `GOXLR_HOST`/`GOXLR_PORT` env vars (default +`localhost:14564`). `ryoku plugin validate` flags an `undeclared-host` +warning on both — expected, since the host comes from a shell variable the +static analyzer can't resolve to a literal; it is non-blocking. + +## What it reads and writes + +Reads: GoXLR channel volumes and mute state from the daemon's HTTP API only +(`localhost`/`127.0.0.1` per `capabilities.network`). Writes: volume/mute +commands back to the same daemon API, and plugin settings via +`pluginApi.saveSetting`. No files, no privileged actions, no other hosts. + +## Preview + +See `assets/preview-widget.png`. + +## Build, check, install + +``` +ryoku plugin validate . +ryoku plugin add . --bar --yes +``` + +It lists under **Community** in QS Bar Settings. Publish it only when you +want to share it: `ryoku plugin share goxlr`. + +## Author + +josh : this plugin is community-made (`official` is +false). diff --git a/plugins/goxlr/assets/preview-panel.png b/plugins/goxlr/assets/preview-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..69828acb733ff61f3afdb244e6fe5de9cb0a249c GIT binary patch literal 108273 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 B814W7 literal 0 HcmV?d00001 diff --git a/plugins/goxlr/assets/preview-widget.png b/plugins/goxlr/assets/preview-widget.png new file mode 100644 index 0000000000000000000000000000000000000000..ee7026f18e785d702a79baa9954d425a34edc9ce GIT binary patch literal 1289 zcmV+k1@`)hP)Q;yy6ICAu*yg~4EP83DJobWWMW4^H_zg%Z&S zX4;Iu1|}e|4+Fl)z6>L5?oSj+lrifDLLD-|E^B#9AMj|)Yu|eXmYDt0w0-xSd(Qpc zbMATfUg9NNPeBL>{h>kG=}G1lIP@%SvVwBpd+v+aI1_WYVs*kbK28EGHl6ZK%+C~v z#f*rpRS5SKagKy-x+#uOI0~)+d+{JA_v`8|;dUw=4UmvxENKvUv-lqj!Rc2(Ifusi~-|tFvRBz0j}{@(+;r5bc}bs|4M50T-K$jQk;`I&Mk5|bd2NKkjFp6;KmQeo4k%?=2$ryTK;t+QIG z{vlhDd8z>u`VpKv_$H65UASpQ+ za`|42>Gi0stwq?2FCpW-3>^3%3$MlRf>NnM%G)UzA0Ou=H2ZF4Dck1AWER)M)onE- ze$U~3O$$7p@)kr!zE=(pk2UzRx(d$*Y{27b14G6P-F+R#M)e2`48ol|cM%o29a5PL zF)=Y192!Ju=tkt`9)>s z!^hhjg~dg<+I@9lAcR1BL5mwd-oQnz79qjG(B0EvR6oi=j4Vz${qPVj6{|q8Y{Cpv z6R0W3;v^%JN|EwbDn37X(yINFBZtxWRU=|!V-dAu2a1Xc@%V4UqW(ud&Bf%@6fQSi zMoUu@5)u+nRaK41h;0x8rpn#y=|s(m45S^c1QClFG8G@o@nDE6{J^0@htb#DhraK7 znYIA`092f-fILx-`uch%5^Fuz;*rJrNR;oxwulHQk`#C+Jsr)>&8RqEiC3a`LZMKg z=h}D9?G$eIbfKo;03E4$G9x_5_^tOtd|W(AH6>Q!X5fZE96RZG#YtmS`%9G)`u_5 zWn2jOk@+8NPDLwvMEOrZS-fMZxs+Qt!LEouE3A~CIV`LpY8h^2_<-#S!``(9C16Z* zL2<4qEO(j`3!6^ZrY!jJD+<&~k+Hb!5CURfB(|CzJ_eR`4G`z-Qnr2OVnmq<@tGjo zqOlw|p~T5TLfPv(E0~RtP&gYUzWp5OaoG45=KiOC20U_N00000NkvXXu0mjfdh=En literal 0 HcmV?d00001 diff --git a/plugins/goxlr/bin/mic-mute-toggle b/plugins/goxlr/bin/mic-mute-toggle new file mode 100755 index 00000000..2fa8b697 --- /dev/null +++ b/plugins/goxlr/bin/mic-mute-toggle @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Toggles the GoXLR's mic mute (the cough button) directly against the +# goxlr-daemon HTTP API, independent of the Quickshell plugin process. Meant +# to be bound to a key, e.g. in Hyprland: +# bind = , XF86AudioMicMute, exec, ~/.local/share/ryoku/plugins/goxlr/bin/mic-mute-toggle +# +# Reads GOXLR_HOST / GOXLR_PORT from the environment, defaulting to the +# daemon's own defaults (localhost:14564). Requires curl and jq. +set -euo pipefail + +host="${GOXLR_HOST:-localhost}" +port="${GOXLR_PORT:-14564}" +url="http://${host}:${port}/api/command" + +status=$(curl -fs --max-time 3 -X POST "$url" -H 'Content-Type: application/json' --data-binary '"GetStatus"') +serial=$(printf '%s' "$status" | jq -r '.Status.mixers | keys[0] // empty') +if [ -z "$serial" ]; then + echo "goxlr: no device connected" >&2 + exit 1 +fi + +state=$(printf '%s' "$status" | jq -r --arg s "$serial" '.Status.mixers[$s].cough_button.state // "Unmuted"') +if [ "$state" = "Unmuted" ]; then + target="MutedToAll" +else + target="Unmuted" +fi + +body=$(jq -nc --arg s "$serial" --arg t "$target" '{"Command":[$s,{"SetCoughMuteState":$t}]}') +curl -fs --max-time 3 -X POST "$url" -H 'Content-Type: application/json' --data-binary "$body" >/dev/null +echo "goxlr: mic ${target}" diff --git a/plugins/goxlr/bin/volume-step b/plugins/goxlr/bin/volume-step new file mode 100755 index 00000000..d8792aa3 --- /dev/null +++ b/plugins/goxlr/bin/volume-step @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Nudges one channel's volume directly against the goxlr-daemon HTTP API, +# independent of the Quickshell plugin process. Meant to be bound to a key, +# e.g. in Hyprland: +# bind = , XF86AudioRaiseVolume, exec, ~/.local/share/ryoku/plugins/goxlr/bin/volume-step Mic 5 +# bind = , XF86AudioLowerVolume, exec, ~/.local/share/ryoku/plugins/goxlr/bin/volume-step Mic -5 +# +# Args: , both optional (defaults: Mic, 2). is +# the signed change in percent, e.g. "5" raises, "-5" lowers. is a +# daemon channel name: Mic, LineIn, Console, System, Game, Chat, Sample, +# Music, Headphones, MicMonitor, LineOut. +# +# Reads GOXLR_HOST / GOXLR_PORT from the environment, defaulting to the +# daemon's own defaults (localhost:14564). Requires curl and jq. +set -euo pipefail + +channel="${1:-Mic}" +percent="${2:-2}" +host="${GOXLR_HOST:-localhost}" +port="${GOXLR_PORT:-14564}" +url="http://${host}:${port}/api/command" + +status=$(curl -fs --max-time 3 -X POST "$url" -H 'Content-Type: application/json' --data-binary '"GetStatus"') +serial=$(printf '%s' "$status" | jq -r '.Status.mixers | keys[0] // empty') +if [ -z "$serial" ]; then + echo "goxlr: no device connected" >&2 + exit 1 +fi + +current=$(printf '%s' "$status" | jq -r --arg s "$serial" --arg c "$channel" '.Status.mixers[$s].levels.volumes[$c] // 0') +delta=$(( percent * 255 / 100 )) +target=$(( current + delta )) +if [ "$target" -lt 0 ]; then target=0; fi +if [ "$target" -gt 255 ]; then target=255; fi + +body=$(jq -nc --arg s "$serial" --arg c "$channel" --argjson v "$target" '{"Command":[$s,{"SetVolume":[$c,$v]}]}') +curl -fs --max-time 3 -X POST "$url" -H 'Content-Type: application/json' --data-binary "$body" >/dev/null +echo "goxlr: ${channel} -> ${target}" diff --git a/plugins/goxlr/content/Panel.qml b/plugins/goxlr/content/Panel.qml new file mode 100644 index 00000000..c7a2f558 --- /dev/null +++ b/plugins/goxlr/content/Panel.qml @@ -0,0 +1,238 @@ +import QtQuick +import Ryoku.PluginKit.Singletons + +// content/Panel.qml: the bar panel. A compact per-channel volume mixer plus +// mic mute, scoped to what fits a 360px-wide dropdown. Routing, effects, the +// sampler, lighting and profile switching stay in the GoXLR Utility window; +// this plugin only ever sends SetVolume, SetFaderMuteState and +// SetCoughMuteState, the same requests its own web UI makes. +Item { + id: root + + property var pluginApi + property string density: "full" + property real s: 1 + property real widthBudget: 360 + property bool active: false + + readonly property var service: pluginApi ? pluginApi.mainInstance : null + readonly property var channels: service ? service.channelList : [] + readonly property bool connected: service ? service.connected : false + + function channelLabel(name) { + const labels = { + "Mic": "Mic", + "LineIn": "Line In", + "Console": "Console", + "System": "System", + "Game": "Game", + "Chat": "Chat", + "Sample": "Sample", + "Music": "Music", + "Headphones": "Headphones", + "MicMonitor": "Mic Monitor", + "LineOut": "Line Out" + }; + return labels[name] || name; + } + + width: root.widthBudget + implicitWidth: root.widthBudget + implicitHeight: col.implicitHeight + 24 * root.s + + Column { + id: col + x: 12 * root.s + y: 12 * root.s + width: root.width - 24 * root.s + spacing: 10 * root.s + + Text { + text: "GoXLR" + color: Theme.bright + font.family: Theme.display + font.pixelSize: 16 * root.s + } + + Text { + visible: !root.connected + width: parent.width + wrapMode: Text.WordWrap + text: (root.service && root.service.lastError === "unreachable") ? "Daemon unreachable \u2014 is goxlr-daemon running?" : "No GoXLR connected." + color: Theme.dim + font.family: Theme.font + font.pixelSize: 12 * root.s + } + + Text { + visible: root.connected + width: parent.width + elide: Text.ElideRight + text: [root.service ? root.service.deviceType : "", root.service ? root.service.profileName : ""].filter(t => t && t.length > 0).join(" \u00b7 ") + color: Theme.dim + font.family: Theme.font + font.pixelSize: 11 * root.s + } + + // Mic mute gets its own large target: the one action worth reaching + // without scrolling to the Mic row below. + Rectangle { + id: micButton + visible: root.connected + width: parent.width + height: micLabel.implicitHeight + 16 * root.s + radius: Theme.radius + readonly property bool muted: root.service ? root.service.channelMuted("Mic") : false + color: micArea.pressed ? Theme.vermDeep : (muted ? Theme.vermDeep : Theme.tileBg) + + Text { + id: micLabel + anchors.centerIn: parent + text: micButton.muted ? "Mic muted \u2014 click to unmute" : "Mute mic" + color: Theme.bright + font.family: Theme.font + font.pixelSize: 13 * root.s + } + + MouseArea { + id: micArea + anchors.fill: parent + onClicked: if (root.service) + root.service.toggleMicMute() + } + } + + Flickable { + id: flick + visible: root.connected + width: parent.width + height: Math.min(channelColumn.implicitHeight, 360 * root.s) + contentWidth: width + contentHeight: channelColumn.implicitHeight + clip: true + boundsBehavior: Flickable.StopAtBounds + + Column { + id: channelColumn + width: flick.width + spacing: 10 * root.s + + Repeater { + model: root.channels + + delegate: Item { + id: chRow + required property string modelData + readonly property string channelName: modelData + readonly property var raw: (root.service && root.service.volumes) ? root.service.volumes[channelName] : undefined + readonly property bool muted: root.service ? root.service.channelMuted(channelName) : false + readonly property bool muteable: channelName === "Mic" || channelName === "MicMonitor" || (root.service ? root.service.faderFor(channelName) !== null : false) + + width: channelColumn.width + height: 26 * root.s + + Text { + id: nameLabel + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + width: 72 * root.s + elide: Text.ElideRight + text: root.channelLabel(chRow.channelName) + color: chRow.muted ? Theme.vermDeep : Theme.bright + font.family: Theme.font + font.pixelSize: 12 * root.s + } + + Item { + id: track + anchors.left: nameLabel.right + anchors.leftMargin: 8 * root.s + anchors.right: valueLabel.left + anchors.rightMargin: 8 * root.s + anchors.verticalCenter: parent.verticalCenter + height: 6 * root.s + + Rectangle { + anchors.fill: parent + radius: height / 2 + color: Theme.hair + } + + Rectangle { + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + height: parent.height + radius: height / 2 + width: parent.width * Math.max(0, Math.min(1, (chRow.raw || 0) / 255)) + color: chRow.muted ? Theme.vermDeep : Theme.accent + } + + MouseArea { + anchors.fill: parent + anchors.margins: -8 * root.s + onPressed: mouse => trackSlide(mouse.x) + onPositionChanged: mouse => { + if (pressed) + trackSlide(mouse.x); + } + function trackSlide(x) { + var ratio = Math.max(0, Math.min(1, (x + 8 * root.s) / track.width)); + if (root.service) + root.service.setVolume(chRow.channelName, Math.round(ratio * 255)); + } + } + } + + Text { + id: valueLabel + anchors.right: muteBtn.visible ? muteBtn.left : parent.right + anchors.rightMargin: muteBtn.visible ? 8 * root.s : 0 + anchors.verticalCenter: parent.verticalCenter + width: 40 * root.s + horizontalAlignment: Text.AlignRight + text: (root.service && chRow.raw !== undefined) ? root.service.volumeText(chRow.raw) : "--" + color: Theme.dim + font.family: Theme.font + font.pixelSize: 12 * root.s + } + + Rectangle { + id: muteBtn + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + width: 22 * root.s + height: 22 * root.s + radius: Theme.radius + visible: chRow.muteable + color: muteArea.pressed ? Theme.vermDeep : (chRow.muted ? Theme.vermDeep : Theme.tileBg) + + Text { + anchors.centerIn: parent + text: "\u2716" + color: Theme.bright + font.family: Theme.mono + font.pixelSize: 10 * root.s + } + + MouseArea { + id: muteArea + anchors.fill: parent + onClicked: if (root.service) + root.service.toggleChannelMute(chRow.channelName) + } + } + } + } + } + } + + Text { + width: parent.width + wrapMode: Text.WordWrap + text: "Routing, effects, the sampler, lighting and profiles aren't covered here \u2014 open the GoXLR Utility for those." + color: Theme.faint + font.family: Theme.font + font.pixelSize: 10 * root.s + } + } +} diff --git a/plugins/goxlr/content/Widget.qml b/plugins/goxlr/content/Widget.qml new file mode 100644 index 00000000..df08ef5b --- /dev/null +++ b/plugins/goxlr/content/Widget.qml @@ -0,0 +1,120 @@ +import QtQuick +import Ryoku.PluginKit.Singletons + +// content/Widget.qml: the bar capsule. Shows the configured channel's volume +// and scrolls it; a left click opens the panel, a right click mutes the mic. +// A channel that changes elsewhere (the device itself, another monitor's +// copy of this plugin) flashes its name and new level here briefly, since a +// bar plugin owns one panel and it is reserved for the user's own click. +Item { + id: root + + property var pluginApi + property var screen + property bool active: false + property string density: "glyph" + property real s: 1 + property real widthBudget: 0 + + readonly property var service: pluginApi ? pluginApi.mainInstance : null + readonly property var settings: pluginApi ? pluginApi.pluginSettings : null + + readonly property string channel: (settings && settings.channel) ? settings.channel : "Mic" + readonly property string displayMode: (settings && settings.display) ? settings.display : "glyph_value" + readonly property string glyph: (settings && settings.glyph) ? settings.glyph : "\u25C6" + readonly property string glyphStyle: (settings && settings.glyphStyle) ? settings.glyphStyle : "text" + readonly property string glyphFont: root.glyphStyle === "icon" ? "Material Symbols Rounded" : Theme.mono + readonly property bool showChannelName: settings ? settings.showChannelName === true : false + readonly property bool muteIndicatorOn: settings ? settings.muteIndicator !== false : true + readonly property bool hideWhenAbsent: settings ? settings.hideWhenAbsent === true : false + readonly property int scrollStep: (settings && settings.scrollStep) ? settings.scrollStep : 2 + + readonly property bool connected: service ? service.connected : false + readonly property bool showingFlash: service ? (service.flashVisible && service.flashChannel !== "") : false + readonly property string effectiveChannel: showingFlash ? service.flashChannel : root.channel + readonly property var rawVolume: (service && service.volumes) ? service.volumes[root.effectiveChannel] : undefined + readonly property bool muted: service ? service.channelMuted(root.effectiveChannel) : false + + function channelLabel(name) { + const labels = { + "Mic": "Mic", + "LineIn": "Line In", + "Console": "Console", + "System": "System", + "Game": "Game", + "Chat": "Chat", + "Sample": "Sample", + "Music": "Music", + "Headphones": "Headphones", + "MicMonitor": "Mic Monitor", + "LineOut": "Line Out" + }; + return labels[name] || name; + } + + function valueText() { + if (!root.connected || root.rawVolume === undefined) + return "--"; + var text = root.service.volumeText(root.rawVolume); + if (root.showChannelName || root.showingFlash) + text = root.channelLabel(root.effectiveChannel) + " " + text; + return text; + } + + visible: !(root.hideWhenAbsent && !root.connected) + implicitWidth: root.visible ? row.implicitWidth : 0 + implicitHeight: Math.max(row.implicitHeight, 18 * root.s) + + Row { + id: row + anchors.verticalCenter: parent.verticalCenter + spacing: 6 * root.s + + Text { + anchors.verticalCenter: parent.verticalCenter + visible: root.displayMode !== "value" + text: root.muted && root.muteIndicatorOn ? "\u2716" : root.glyph + color: { + if (!root.connected) + return Theme.dim; + if (root.showingFlash) + return Theme.accent; + if (root.muted && root.muteIndicatorOn) + return Theme.vermDeep; + return root.active ? Theme.accent : Theme.dim; + } + font.family: root.glyphFont + font.pixelSize: 13 * root.s + } + + Text { + anchors.verticalCenter: parent.verticalCenter + visible: root.displayMode !== "glyph" + text: root.valueText() + color: root.showingFlash ? Theme.accent : (root.muted && root.muteIndicatorOn ? Theme.vermDeep : Theme.bright) + font.family: Theme.font + font.pixelSize: 13 * root.s + elide: Text.ElideRight + width: root.widthBudget > 0 ? Math.min(implicitWidth, root.widthBudget) : implicitWidth + } + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: mouse => { + if (mouse.button === Qt.RightButton) { + if (root.service) + root.service.toggleMicMute(); + } else if (root.pluginApi) { + root.pluginApi.togglePanel(); + } + } + onWheel: wheel => { + if (!root.service) + return; + var delta = wheel.angleDelta.y > 0 ? root.scrollStep : -root.scrollStep; + root.service.adjustVolume(root.channel, delta); + } + } +} diff --git a/plugins/goxlr/manifest.json b/plugins/goxlr/manifest.json new file mode 100644 index 00000000..6a521aab --- /dev/null +++ b/plugins/goxlr/manifest.json @@ -0,0 +1,192 @@ +{ + "id": "goxlr", + "name": "GoXLR", + "version": "1.0.0", + "author": "dajax", + "description": "Core GoXLR / GoXLR Mini control from the bar: a volume capsule with a quick flash on change, mic mute, and per-channel volumes in the panel. Backed by the goxlr-utility daemon.", + "license": "MIT", + "official": false, + "hosts": [ + "topbarGlyph" + ], + "entryPoints": { + "main": "service/Main.qml", + "content": "content/Widget.qml", + "panel": "content/Panel.qml" + }, + "panel": { + "width": 360 + }, + "files": [ + "bin/mic-mute-toggle", + "bin/volume-step", + "assets/preview-widget.png" + ], + "capabilities": { + "densities": [ + "glyph", + "compact" + ], + "network": [ + "localhost", + "127.0.0.1" + ] + }, + "defaults": { + "host": "topbarGlyph", + "label": "GoXLR" + }, + "dependencies": { + "commands": [ + "curl", + "jq" + ] + }, + "metadata": { + "settings": [ + { + "key": "host", + "type": "text", + "label": "Daemon host", + "group": "Connection", + "default": "localhost", + "placeholder": "localhost" + }, + { + "key": "port", + "type": "int", + "label": "Daemon port", + "group": "Connection", + "default": 14564, + "min": 1, + "max": 65535 + }, + { + "key": "refreshMs", + "type": "int", + "label": "Poll interval while the panel is closed (ms)", + "group": "Connection", + "default": 1000, + "min": 250, + "max": 10000 + }, + { + "key": "volumeDisplay", + "type": "choice", + "label": "Show volumes as", + "group": "Connection", + "default": "percent", + "options": [ + { "value": "percent", "label": "Percent" }, + { "value": "raw", "label": "Raw (0-255)" } + ] + }, + { + "key": "channel", + "type": "choice", + "label": "Channel shown on the bar", + "group": "Widget", + "default": "Mic", + "options": [ + { "value": "Mic", "label": "Mic" }, + { "value": "LineIn", "label": "Line In" }, + { "value": "Console", "label": "Console" }, + { "value": "System", "label": "System" }, + { "value": "Game", "label": "Game" }, + { "value": "Chat", "label": "Chat" }, + { "value": "Sample", "label": "Sample" }, + { "value": "Music", "label": "Music" }, + { "value": "Headphones", "label": "Headphones" }, + { "value": "MicMonitor", "label": "Mic Monitor" }, + { "value": "LineOut", "label": "Line Out" } + ] + }, + { + "key": "display", + "type": "choice", + "label": "Bar display", + "group": "Widget", + "default": "glyph_value", + "options": [ + { "value": "glyph", "label": "Icon only" }, + { "value": "glyph_value", "label": "Icon and volume" }, + { "value": "value", "label": "Volume only" } + ] + }, + { + "key": "glyphStyle", + "type": "choice", + "label": "Bar icon style", + "group": "Widget", + "default": "text", + "options": [ + { "value": "text", "label": "Text / emoji character" }, + { "value": "icon", "label": "Material Symbols icon name" } + ] + }, + { + "key": "glyph", + "type": "text", + "label": "Bar icon", + "group": "Widget", + "default": "\u25C6", + "placeholder": "\u25C6 or, in icon style, a Material Symbols name like mic" + }, + { + "key": "showChannelName", + "type": "toggle", + "label": "Prefix the volume with the channel name", + "group": "Widget", + "default": false + }, + { + "key": "scrollStep", + "type": "int", + "label": "Volume change per scroll notch (%)", + "group": "Widget", + "default": 2, + "min": 1, + "max": 25 + }, + { + "key": "muteIndicator", + "type": "toggle", + "label": "Change colour while the channel is muted", + "group": "Widget", + "default": true + }, + { + "key": "hideWhenAbsent", + "type": "toggle", + "label": "Hide the capsule when no GoXLR is connected", + "group": "Widget", + "default": false + }, + { + "key": "flashEnabled", + "type": "toggle", + "label": "Flash the bar capsule when any channel's volume or mute changes", + "group": "Flash", + "default": true + }, + { + "key": "flashTimeoutMs", + "type": "int", + "label": "How long the flash stays up (ms)", + "group": "Flash", + "default": 1500, + "min": 500, + "max": 5000 + }, + { + "key": "flashPollMs", + "type": "int", + "label": "Poll interval while watching for changes to flash (ms)", + "group": "Flash", + "default": 200, + "min": 100, + "max": 1000 + } + ] + } +} diff --git a/plugins/goxlr/product-manifest.json b/plugins/goxlr/product-manifest.json new file mode 100644 index 00000000..fa898480 --- /dev/null +++ b/plugins/goxlr/product-manifest.json @@ -0,0 +1,113 @@ +{ + "schema": 1, + "id": "goxlr", + "category": "plugins", + "version": "1.0.0", + "destination": "ryoku/plugins/goxlr", + "files": [ + { + "source": ".gitignore", + "destination": ".gitignore", + "sha256": "379dfa9273952c08fa44042de676ed4addc26a7c4d4c90235d6ff2c73dffb810", + "mode": "0644", + "size": 22, + "install": true + }, + { + "source": "AGENTS.md", + "destination": "AGENTS.md", + "sha256": "069ca9810e1f7ab3d4053db9e9cfad2af6ef457874f8390e968471858e5e203a", + "mode": "0644", + "size": 3954, + "install": true + }, + { + "source": "CLAUDE.md", + "destination": "CLAUDE.md", + "sha256": "09ffb8ebdb8adf50bf4bde26dfe2109b4af3a4a8cc3f30cc536be42bb912c033", + "mode": "0644", + "size": 152, + "install": true + }, + { + "source": "LICENSE", + "destination": "LICENSE", + "sha256": "ed31c58623a08b80bf05d3575e03c1c957547da68ba2ade41c6cf81338e50a56", + "mode": "0644", + "size": 1061, + "install": false + }, + { + "source": "README.md", + "destination": "README.md", + "sha256": "83d27b9d36c281a62e501c8c03e21b79f28a57a96d03a5acb33528068716e25c", + "mode": "0644", + "size": 5270, + "install": false + }, + { + "source": "assets/preview-panel.png", + "destination": "assets/preview-panel.png", + "sha256": "45541f977411c5f1237dfaf010ad1983afcbc0ed38e7246dc24a44bc6770917c", + "mode": "0644", + "size": 108273, + "install": false + }, + { + "source": "assets/preview-widget.png", + "destination": "assets/preview-widget.png", + "sha256": "c65ca853699b3443f9efa1d24e797feae0fa36f398182a040e91c421a0018969", + "mode": "0644", + "size": 1289, + "install": false + }, + { + "source": "bin/mic-mute-toggle", + "destination": "bin/mic-mute-toggle", + "sha256": "2cd11be84be8b7a25f81c0efce0e4f8008c55691b698d0f397e476c3e4f390e9", + "mode": "0755", + "size": 1251, + "install": true + }, + { + "source": "bin/volume-step", + "destination": "bin/volume-step", + "sha256": "821dc027597264fd46d6793841007776b40b5e5a64d3bec383ba1ab6a3d10886", + "mode": "0755", + "size": 1755, + "install": true + }, + { + "source": "content/Panel.qml", + "destination": "content/Panel.qml", + "sha256": "260a2cdf171eb451bd2db517fd236194fbaa9c8c9ece012acfed902e6231bf9a", + "mode": "0644", + "size": 9734, + "install": true + }, + { + "source": "content/Widget.qml", + "destination": "content/Widget.qml", + "sha256": "fa847ea6ad44a117218c0e325c82bdd99abc7fe1bf9551087fb807d3b022c682", + "mode": "0644", + "size": 5046, + "install": true + }, + { + "source": "manifest.json", + "destination": "manifest.json", + "sha256": "6d4969c1040578ed0f7d99ba11c3623676ca73e7fdb1430e70dfa81a7ce4c3ce", + "mode": "0644", + "size": 5013, + "install": true + }, + { + "source": "service/Main.qml", + "destination": "service/Main.qml", + "sha256": "969d2d955f2cc5c5e5e2fe9ad75aa0151a7c66959779f6b6f58640c513ebb7cf", + "mode": "0644", + "size": 17474, + "install": true + } + ] +} diff --git a/plugins/goxlr/service/Main.qml b/plugins/goxlr/service/Main.qml new file mode 100644 index 00000000..7a75ab4e --- /dev/null +++ b/plugins/goxlr/service/Main.qml @@ -0,0 +1,487 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell.Io + +// service/Main.qml: the plugin's logic, no UI. One instance per bar copy of +// this plugin polls the goxlr-utility daemon's HTTP API (the same interface +// its own web UI uses) over loopback with curl, and every view +// (content/Widget.qml, content/Panel.qml) reads the live state published +// here through pluginApi.mainInstance. The daemon stays the only owner of the +// hardware; this never touches the device directly. +Item { + id: svc + + // Set by the host after this loads. Settings are declared in + // manifest.json metadata.settings and read behind a default (R5); they + // are written only through pluginApi.saveSetting, which this plugin never + // calls since it has no editable panel state of its own to persist. + property var pluginApi + readonly property var settings: pluginApi ? pluginApi.pluginSettings : null + + readonly property string host: (settings && settings.host && String(settings.host).trim() !== "") ? String(settings.host).trim() : "localhost" + readonly property int port: (settings && settings.port) ? Math.floor(settings.port) : 14564 + readonly property string baseUrl: "http://" + svc.host + ":" + svc.port + + readonly property var channelList: ["Mic", "LineIn", "Console", "System", "Game", "Chat", "Sample", "Music", "Headphones", "MicMonitor", "LineOut"] + readonly property var faderList: ["A", "B", "C", "D"] + + // ── Live state, published for the widget and the panel ───────────────── + property bool connected: false + property string serial: "" + property string deviceType: "" + property var volumes: ({}) + property var faders: ({}) + property var cough: ({}) + property string profileName: "" + property string micProfileName: "" + property string lastError: "" + + // A change worth flashing on the bar: the channel that moved, its new + // level, and whether it is muted. Mirrors the original plugin's OSD, but + // rendered inside the bar capsule itself since a bar plugin only owns one + // panel and it is reserved for the user's own click. + property string flashChannel: "" + property int flashVolume: 0 + property bool flashMuted: false + property bool flashVisible: false + property double flashUntil: 0 + + readonly property bool panelOpen: pluginApi ? pluginApi.panelOpen : false + + property bool _inFlight: false + property bool _pendingRefresh: false + property var _lastVolumes: null + property var _lastMutes: null + property string _lastSerial: "" + property double _lastStart: 0 + + // A burst wider than this is a profile load rewriting every level at + // once, not a deliberate change worth flashing. + readonly property int _flashBurstLimit: 3 + readonly property int _minGapMs: 120 + + onPanelOpenChanged: { + pollTimer.interval = svc.pollInterval(); + svc.poll(); + } + onSettingsChanged: { + pollTimer.interval = svc.pollInterval(); + svc.poll(); + } + + Component.onCompleted: { + pollTimer.interval = svc.pollInterval(); + svc.poll(); + } + + // ── Presentation helpers ──────────────────────────────────────────────── + + function volumeIsRaw() { + return settings && settings.volumeDisplay === "raw"; + } + + function volumePercent(raw) { + var clamped = Math.max(0, Math.min(255, Number(raw) || 0)); + return Math.round(clamped / 255 * 100); + } + + function percentToVolume(pct) { + var clamped = Math.max(0, Math.min(100, Number(pct) || 0)); + return Math.round(clamped / 100 * 255); + } + + function volumeText(raw) { + if (svc.volumeIsRaw()) + return String(Math.round(Number(raw) || 0)); + return svc.volumePercent(raw) + "%"; + } + + // Mic mute lives on the cough button; every other channel is muted + // through the fader it is assigned to, and a channel on no fader cannot + // be muted at all. + function channelMuted(channel) { + if (!svc.connected) + return false; + if (channel === "Mic" || channel === "MicMonitor") + return svc.cough && svc.cough.state !== undefined && svc.cough.state !== "Unmuted"; + var fader = svc.faderFor(channel); + if (fader === null) + return false; + var entry = svc.faders[fader]; + return entry ? entry.mute_state !== "Unmuted" : false; + } + + function faderFor(channel) { + for (var i = 0; i < svc.faderList.length; i++) { + var f = svc.faderList[i]; + var entry = svc.faders[f]; + if (entry && entry.channel === channel) + return f; + } + return null; + } + + // ── Transport ──────────────────────────────────────────────────────────── + // One throwaway curl process per request, run through an argv array (R9: + // never a shell string built from settings or daemon output). + + Component { + id: curlFactory + Process { + id: proc + property var onDone: null + stdout: StdioCollector { + id: outCollector + waitForEnd: true + } + onExited: (code, status) => { + var text = outCollector.text; + var cb = proc.onDone; + proc.destroy(); + if (cb) + cb(code === 0 ? text : null); + } + } + } + + function runCurl(body, onDone) { + var obj = curlFactory.createObject(svc, { + "command": ["curl", "-s", "-S", "--max-time", "3", "-X", "POST", svc.baseUrl + "/api/command", "-H", "Content-Type: application/json", "--data-binary", body], + "onDone": onDone + }); + if (!obj) { + if (onDone) + onDone(null); + return; + } + obj.running = true; + } + + // Every reply is JSON; a transport failure and a non-zero curl exit both + // arrive here as a null value plus a code the callers translate. + function post(body, onResult) { + svc.runCurl(body, function (text) { + if (!onResult) + return; + if (text === null || text === undefined || text === "") { + onResult(null, "unreachable"); + return; + } + var decoded = null; + try { + decoded = JSON.parse(text); + } catch (e) { + onResult(null, "bad_response"); + return; + } + onResult(decoded, null); + }); + } + + function errorText(decoded) { + if (decoded && typeof decoded === "object" && typeof decoded.Error === "string") + return decoded.Error; + return null; + } + + function status(onResult) { + svc.post(JSON.stringify("GetStatus"), function (decoded, err) { + if (decoded === null) { + onResult(null, err); + return; + } + if (decoded && decoded.Status !== undefined) { + onResult(decoded.Status, null); + return; + } + onResult(null, svc.errorText(decoded) || "bad_response"); + }); + } + + // A GoXLRCommand variant, encoded by arity the daemon expects: no args is + // an empty array, one arg is the bare value, two or more is an array. + function encodeCommand(name, args) { + var o = {}; + if (args.length === 0) + o[name] = []; + else if (args.length === 1) + o[name] = args[0]; + else + o[name] = args; + return o; + } + + // A device command: svc.send(serial, "SetVolume", "Music", 200). + function send(serial, name) { + if (!serial) + return; + var args = Array.prototype.slice.call(arguments, 2); + var body = JSON.stringify({ + "Command": [serial, svc.encodeCommand(name, args)] + }); + svc.post(body, null); + } + + // ── Polling ────────────────────────────────────────────────────────────── + // The daemon is local and answers in single-digit milliseconds, so a slow + // poll is about not spinning the CPU rather than about cost. The cadence + // tightens while the panel is open, and again while watching for a flash. + + function pollInterval() { + if (svc.panelOpen) + return 300; + var ms = Math.max(250, Math.min(10000, Number(svc.settings ? svc.settings.refreshMs : 1000) || 1000)); + if (svc.flashEnabled()) { + var detect = Math.max(100, Math.min(1000, Number(svc.settings ? svc.settings.flashPollMs : 200) || 200)); + ms = Math.min(ms, detect); + } + return ms; + } + + function flashEnabled() { + return !(svc.settings && svc.settings.flashEnabled === false); + } + + function flashTimeoutMs() { + return Math.max(500, Math.min(5000, Number(svc.settings ? svc.settings.flashTimeoutMs : 1500) || 1500)); + } + + function serials(status) { + var list = []; + if (!status || !status.mixers) + return list; + for (var key in status.mixers) + list.push(key); + list.sort(); + return list; + } + + function applyStatus(status) { + var list = svc.serials(status); + if (list.length === 0) { + svc.connected = false; + svc.serial = ""; + return; + } + var serial = list[0]; + var mixer = status.mixers[serial]; + var levels = mixer.levels || {}; + var faders = {}; + for (var i = 0; i < svc.faderList.length; i++) { + var f = svc.faderList[i]; + var entry = (mixer.fader_status || {})[f]; + if (entry) + faders[f] = { + "channel": entry.channel, + "mute_state": entry.mute_state, + "mute_type": entry.mute_type + }; + } + svc.connected = true; + svc.serial = serial; + svc.deviceType = (mixer.hardware || {}).device_type || ""; + svc.volumes = levels.volumes || {}; + svc.faders = faders; + svc.cough = mixer.cough_button || {}; + svc.profileName = mixer.profile_name || ""; + svc.micProfileName = mixer.mic_profile_name || ""; + } + + function muteSnapshot() { + var m = {}; + for (var i = 0; i < svc.channelList.length; i++) { + var c = svc.channelList[i]; + m[c] = svc.channelMuted(c); + } + return m; + } + + // Which single change to flash. A volume that moved wins over a mute + // that flipped; among several volumes the largest move wins. Ties fall + // back to channel order, which puts Mic ahead of MicMonitor when the + // cough button mutes both at once. + function changedChannel(volumes, mutes) { + if (!svc._lastVolumes || !svc._lastMutes) + return null; + var moved = null, movedDelta = -1, muteFlipped = null, count = 0; + for (var i = 0; i < svc.channelList.length; i++) { + var c = svc.channelList[i]; + var value = volumes[c], previous = svc._lastVolumes[c]; + var changed = false; + if (typeof previous === "number" && typeof value === "number" && previous !== value) { + changed = true; + var delta = Math.abs(value - previous); + if (delta > movedDelta) { + moved = c; + movedDelta = delta; + } + } + if (mutes[c] !== svc._lastMutes[c]) { + changed = true; + if (muteFlipped === null) + muteFlipped = c; + } + if (changed) + count += 1; + } + if (count === 0 || count > svc._flashBurstLimit) + return null; + return moved || muteFlipped; + } + + function showFlash(channel) { + svc.flashChannel = channel; + svc.flashVolume = (svc.volumes || {})[channel] || 0; + svc.flashMuted = svc.channelMuted(channel); + svc.flashUntil = Date.now() + svc.flashTimeoutMs(); + svc.flashVisible = true; + } + + function trackChanges() { + var volumes = svc.volumes || {}; + var mutes = svc.muteSnapshot(); + + // A different device, or one that just came back, has no history + // worth diffing against: everything would read as a change. + if (svc.serial !== svc._lastSerial) { + svc._lastSerial = svc.serial; + svc._lastVolumes = Object.assign({}, volumes); + svc._lastMutes = mutes; + return; + } + + // Nothing to flash while the panel is open: the control that + // changed is already on screen. + if (svc.flashEnabled() && !svc.panelOpen) { + var channel = svc.changedChannel(volumes, mutes); + if (channel !== null) + svc.showFlash(channel); + } + + svc._lastVolumes = Object.assign({}, volumes); + svc._lastMutes = mutes; + } + + function clearTracking() { + svc._lastVolumes = null; + svc._lastMutes = null; + svc._lastSerial = ""; + svc.flashVisible = false; + } + + function queueRefresh() { + svc._pendingRefresh = true; + } + + function poll() { + if (svc._inFlight) { + svc.queueRefresh(); + return; + } + var now = Date.now(); + if (svc._minGapMs - (now - svc._lastStart) > 0) { + svc.queueRefresh(); + return; + } + + svc._lastStart = now; + svc._pendingRefresh = false; + svc._inFlight = true; + pollTimer.interval = svc.pollInterval(); + + svc.status(function (status, err) { + svc._inFlight = false; + if (status === null) { + svc.connected = false; + svc.lastError = err === "unreachable" ? "unreachable" : (err || "failed"); + svc.clearTracking(); + } else { + svc.applyStatus(status); + svc.lastError = ""; + if (svc.connected) + svc.trackChanges(); + else + svc.clearTracking(); + } + if (svc._pendingRefresh) + svc.poll(); + }); + } + + Timer { + id: pollTimer + interval: 1000 + running: true + repeat: true + onTriggered: if (!svc._inFlight) + svc.poll() + } + + // The flash's lifetime rides on a plain timer rather than the poll tick, + // so it clears promptly even if the daemon is slow to answer. + Timer { + interval: 150 + running: svc.flashVisible + repeat: true + onTriggered: if (svc.flashVisible && Date.now() >= svc.flashUntil) + svc.flashVisible = false + } + + // ── Actions ────────────────────────────────────────────────────────────── + + // Mic mute is the cough button on both device families. Toggling asks + // for the opposite of the state the last poll saw, so a hold-to-talk + // profile still ends up where the user expects. + function toggleMicMute() { + if (!svc.connected) + return; + var muted = svc.cough && svc.cough.state !== "Unmuted"; + svc.send(svc.serial, "SetCoughMuteState", muted ? "Unmuted" : "MutedToAll"); + svc.poll(); + } + + // Mutes any other channel through the fader it is currently assigned to. + // A channel on no fader cannot be muted, matching the device itself. + function toggleChannelMute(channel) { + if (!svc.connected) + return; + if (channel === "Mic" || channel === "MicMonitor") { + svc.toggleMicMute(); + return; + } + var fader = svc.faderFor(channel); + if (fader === null) + return; + var entry = svc.faders[fader]; + var muted = entry ? entry.mute_state !== "Unmuted" : false; + svc.send(svc.serial, "SetFaderMuteState", fader, muted ? "Unmuted" : "MutedToX"); + svc.poll(); + } + + function adjustVolume(channel, deltaPercent) { + var current = (svc.volumes || {})[channel]; + if (typeof current !== "number") + return; + var target = Math.max(0, Math.min(255, Math.round(current + deltaPercent / 100 * 255))); + svc.setVolume(channel, target); + } + + function setVolume(channel, rawTarget) { + if (!svc.connected) + return; + var current = (svc.volumes || {})[channel]; + var target = Math.max(0, Math.min(255, Math.round(rawTarget))); + if (target === current) + return; + svc.send(svc.serial, "SetVolume", channel, target); + + // Publish the new level immediately so the UI tracks the wheel or + // slider instead of waiting a poll; the next poll confirms or + // corrects it. + var volumes = Object.assign({}, svc.volumes || {}); + volumes[channel] = target; + svc.volumes = volumes; + svc.poll(); + } +} diff --git a/plugins/registry.json b/plugins/registry.json index 15382ab7..ee1011fb 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -1621,6 +1621,36 @@ "topbarGlyph" ], "lastUpdated": "2026-10-01" + }, + { + "id": "goxlr", + "name": "GoXLR", + "version": "1.0.0", + "path": "plugins/goxlr", + "author": "dajax", + "upstream": "https://github.com/millerjryan/ryoku-goxlr", + "summary": "Core GoXLR / GoXLR Mini control from the bar: a volume capsule with a quick flash on change, mic mute, and per-channel volumes in the panel.", + "description": "Core GoXLR / GoXLR Mini control from the bar: a volume capsule with a quick flash on change, mic mute, and per-channel volumes in the panel. Backed by the goxlr-utility daemon over its local HTTP API; routing, effects, sampler, lighting, and profiles stay in the GoXLR app.", + "tags": [ + "bar-widget", + "audio" + ], + "accent": "#8f8378", + "surface": "#101010", + "preview": "assets/preview-panel.png", + "screenshots": [ + "assets/preview-panel.png", + "assets/preview-widget.png" + ], + "manifest": "product-manifest.json", + "manifestSha256": "c50fb4fd2ac01fb6d8db7edefe28d29c2392623a73181c66863b2614be81c114", + "official": false, + "tagline": "Core GoXLR / GoXLR Mini control from the bar: a volume capsule with a quick flash on change, mic mute, and per-channel volumes in the panel.", + "icon": "", + "hosts": [ + "topbarGlyph" + ], + "lastUpdated": "2026-10-07" } ] }