Commit Graph

10 Commits

Author SHA1 Message Date
joren
db48781221 fix: optimistically update nodes store when loading profile volumes
setNodeVolume/setNodeMute only send API requests; the nodes store
wasn't updated until the backend broadcast a graph change, so sliders
showed stale values. Now the store is updated immediately before
firing the API calls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 19:16:55 +02:00
joren
a58df9cdaa fix: store volumes/mutes in profiles + fix hide rule matching
- Snapshot node volumes and mutes when saving a profile; restore
  them on load via setNodeVolume/setNodeMute for each matching node
- Fix hide rules to do exact case-insensitive match on display name
  (alias/nick) instead of regex substring match on PW name, so
  "Speaker" no longer accidentally hides "Gaming Speaker"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 18:39:28 +02:00
joren
cb87cd34ba feat: custom node display names (aliases)
Right-click any node → Rename to set a custom label. The alias is shown
in the node header and Properties dialog instead of the raw PipeWire name.
Leave the input blank (or press Reset) to revert to the PW name.

Aliases are stored in aliases: Record<string,string> inside the patchbay
state (keyed by PW node name, which is stable for hardware devices) and
persisted automatically with the rest of the patchbay config. Old save
files without an aliases key are handled gracefully via the ?? {} fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 20:08:16 +02:00
joren
b3c81623f1 fix: mute race condition + profile loading + add Update button
Bug 1 - Mute unmute not sticking (G560 and others):
- Root cause: on_node_info was reading volume/mute from info->props which
  contains static initial values only — NOT updated at runtime. When any
  node info event fired, it overwrote the correct runtime state with stale
  initial data, causing the unmute to revert on the next graph event.
- Fix: Subscribe nodes to SPA_PARAM_Props in addition to SPA_PARAM_Format.
  Handle SPA_PARAM_Props in on_node_param to track volume (both SPA_PROP_volume
  and SPA_PROP_channelVolumes averaged) and mute from the authoritative live
  parameter stream. Remove stale volume/mute reads from on_node_info.
- Also fix mute detection in /api/mute: check "mute":true precisely instead
  of searching for bare "true" anywhere in the body.

Bug 2 - Loading profiles does not work:
- loadProfile was only applying connections when already in "activated" mode.
  Load now always applies the profile connections immediately.

Bug 3 - No option to update an existing profile:
- Add "Update" button in profile list that overwrites the profile with current
  connections (calls saveProfile with the existing name).
- Clear the profile name input after "Save Current" succeeds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 12:20:22 +02:00
joren
f76583a33e feat: buffer/latency control + non-selectable node text
Buffer Control:
- GET /api/quantum - reads current graph quantum via pw-metadata
- POST /api/quantum {quantum:N} - sets quantum via pw-metadata
- Toolbar dropdown with presets: 32, 64, 128, 256, 512, 1024, 2048, 4096
- Loads current quantum on startup

Text Selection Fix:
- Added user-select: none to wrap and canvas CSS
- Node text no longer gets selected when dragging
2026-03-30 01:10:46 +02:00
joren
9dc685acda feat: pactl-based module loading, more device types
Backend:
- Switched null-sink and loopback to use pactl (works on all systems)
- Generic POST /api/load-module {module, args} for any pactl module
- Fixed SVG toolbar click issue (z-index layering)

Frontend:
- + Add Device dropdown now includes:
  - Null Sink (virtual audio output)
  - Loopback Device (paired input+output)
  - TCP Network Server (module-native-protocol-tcp)
  - TCP Tunnel Sink
  - TCP Tunnel Source
- Dropdown header and section separators
- Fixed canvas z-index so toolbar is clickable
2026-03-29 23:55:19 +02:00
joren
2879469d13 feat: create virtual devices (+ Add Device dropdown)
Backend:
- POST /api/create-null-sink {name} - loads null-sink module
- POST /api/create-loopback {name} - loads loopback module
- POST /api/unload-module {module_id} - unloads a module
- Fixed double-proxy-destroy crash in GraphEngine
- Graceful failure when module not available (no crash)

Frontend:
- + Add Device button in toolbar with dropdown menu
- Null Sink option (creates virtual audio output)
- Loopback Device option (creates paired input+output)
- Dropdown closes on outside click

Note: null-sink requires libpipewire-module-null-sink to be installed.
Loopback works on all PipeWire installations.
2026-03-29 23:50:01 +02:00
joren
65db5daa7c feat: built-in volume management
- Volume slider on every node (green bar, draggable)
- Mute toggle button (M/m) on every node
- Backend: read volume/mute from PipeWire node props
- Backend: POST /api/volume {node_id, volume} to set volume
- Backend: POST /api/mute {node_id, mute} to toggle mute
- Graph JSON includes volume and mute fields per node
- Slider supports drag-to-adjust with mouse
2026-03-29 23:21:39 +02:00
joren
0acfa6ea73 feat: complete qpwgraph feature parity
Core Visual Routing:
- Dashed lines for inactive connections (unpinned shown dimmer)
- Color-coded streams (audio=green, midi=red, video=blue)
- Pin indicator (yellow dot) on pinned connections

Patchbay - Session Management:
- Save & Restore: named profiles stored on server (~/.config/pwweb/patchbay.json)
- Activated Mode: toggle to auto-restore connections when apps appear
- Exclusive Mode: enforce profile-only links, disconnect everything else
- Pin & Unpin: right-click wire -> Pin/Unpin, yellow dot on pinned wires
- Auto-Pin: automatically pin all new manual connections
- Auto-Disconnect: auto-sever pinned connections when patchbay deactivated
- Rule Management: dialog showing all profile rules with type badges

Graph Customization:
- Node Hiding: add regex patterns to hide nodes (e.g. Dummy|Freewheel)
- Node Merging: merge nodes sharing a common prefix into one block
- All rules persisted to server with the patchbay state

Dialogs: Hide Nodes, Merge Nodes, Profiles, Rules
2026-03-29 22:55:28 +02:00
joren
f8c57fbdd3 Initial commit: pwweb - PipeWire WebUI
C++ backend with SSE streaming (reuses qpwgraph PipeWire callbacks).
Svelte frontend with custom SVG canvas for port-level connections.

Features:
- Live PipeWire graph via SSE
- Drag output->input port to connect
- Double-click or select+Delete to disconnect
- Node positions saved to localStorage
- Pan (drag bg) and zoom (scroll)
- Port type coloring (audio=green, midi=red, video=blue)
2026-03-29 22:40:07 +02:00