summaryrefslogtreecommitdiff
path: root/TODO
diff options
context:
space:
mode:
authorCalvin Morrison <calvin@pobox.com>2026-05-15 10:10:04 -0400
committerCalvin Morrison <calvin@pobox.com>2026-05-15 10:10:04 -0400
commite776bc768cf9afca1867200e25d64d315cd72a3e (patch)
tree6745527b939c9d37147d7dc98e8664437ee433f6 /TODO
parent4e602e78cdfc210ab7781668df2a88afb923258b (diff)
Full mixer implementation — tray, popup, prefs, devices tab with port indicators
Adds the complete tmix feature set built since the initial skeleton: balance knob, level meters, KLed mute button, system tray with scroll-wheel volume and recording indicator, tray popup, preferences dialog, right-click context menus, single-instance enforcement, scroll area, window geometry persistence, and Devices tab with PA card profile switcher and live port availability indicators (2-column layout, in-place updates on plug/unplug). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'TODO')
-rw-r--r--TODO221
1 files changed, 221 insertions, 0 deletions
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..9834c25
--- /dev/null
+++ b/TODO
@@ -0,0 +1,221 @@
+tmix — todo list
+================
+
+## UAT checklist
+Run through this before any release / major refactor.
+
+### Startup
+- [ ] App launches without crash when PA is running
+- [ ] App launches without crash when PA is NOT running (graceful fail)
+- [ ] Window title shows "TMix - Volume Control" (not "TMix - Volume Control - TMix")
+- [ ] Tray icon appears when DockInTray=true
+- [ ] Window hidden on launch when DockInTray=true
+- [ ] Window visible on launch when DockInTray=false
+
+### Tabs / device population
+- [ ] Output tab shows all PA sinks (hardware outputs)
+- [ ] Input tab shows all PA sources (mics etc.) but NOT monitor sources
+- [ ] Playback tab shows per-app sink inputs; tmix-peak streams NOT shown
+- [ ] Recording tab shows per-app source outputs; tmix-peak streams NOT shown
+- [ ] Devices added/removed live without restart (plug/unplug USB audio, start/stop app)
+- [ ] Correct icon shown per device (headphone, microphone, digital, fallback)
+- [ ] Correct app icon shown for Playback streams (Amarok, Firefox, etc.)
+- [ ] Vertical label shows device/stream name
+
+### Volume
+- [ ] Dragging volume slider changes PA volume in real time
+- [ ] Volume % label updates live while dragging
+- [ ] Scrolling on tray icon changes default output volume
+- [ ] Volume change from another app (pavucontrol) reflects in tmix slider + label
+- [ ] Volume clamped 0–100%, no overflow
+
+### Mute
+- [ ] Green LED = unmuted, off = muted
+- [ ] Clicking LED toggles mute state in PA
+- [ ] Mute change from another app reflects in LED
+- [ ] Right-click "Mute" mutes; item shows "Muted" with checkmark when muted; "Unmute" when muted
+
+### Balance knob (Output + Playback only)
+- [ ] Knob renders cleanly (antialiased, no flicker)
+- [ ] Dragging up increases right balance, dragging down increases left
+- [ ] Scroll wheel adjusts ±5
+- [ ] Double-click resets to centre
+- [ ] PA channel volumes update correctly (left attenuated when right-heavy)
+- [ ] Balance change from pavucontrol reflects in knob
+- [ ] Input tab has NO balance knob
+
+### Level meter
+- [ ] Output: meter responds to audio playback through that sink
+- [ ] Input: meter responds to microphone input
+- [ ] Playback: meter shows per-stream level (only that app's audio, not the whole sink)
+- [ ] Recording: no meter (acceptable; source output monitoring not implemented)
+- [ ] Meter decays smoothly; attack is fast, decay is slower
+- [ ] Meter shows 0 when muted or silent
+
+### Default device
+- [ ] Radio button filled on the current PA default output
+- [ ] Radio button filled on the current PA default input
+- [ ] Clicking empty radio button sets that device as PA default
+- [ ] Default change from pavucontrol updates radio buttons in tmix
+- [ ] Only one radio button filled at a time per tab
+- [ ] Tray icon reflects default output volume/mute state
+
+### Recording indicator
+- [ ] Red LED on Input widget is OFF when no app is recording from that source
+- [ ] Red LED turns ON when an app starts recording from that source
+- [ ] Red LED turns OFF when recording app stops
+- [ ] Second tray icon (microphone) appears when any input is active
+- [ ] Second tray icon disappears when all recording stops
+
+### Right-click context menu
+- [ ] Right-click on any device widget shows context menu
+- [ ] Menu title shows device name
+- [ ] "Mute"/"Muted" item works (see Mute section)
+- [ ] Output: "Set as Default Output" present and functional
+- [ ] Input: "Set as Default Input" present and functional
+- [ ] Playback: "Move to Sink" section lists all available sinks
+- [ ] Current sink shown with checkmark in "Move to Sink" list
+- [ ] Selecting a different sink moves the stream
+- [ ] Output/Input: no "Move to Sink" section
+- [ ] Playback/Recording: no "Set as Default" item
+
+### System tray
+- [ ] Volume icon shows muted/low/medium/high based on default output
+- [ ] Icon updates when volume changes (slider, scroll wheel, external)
+- [ ] Icon updates when mute state changes
+- [ ] Scroll wheel on tray raises/lowers default output volume
+- [ ] Left-click tray shows/hides main window
+- [ ] Right-click tray shows context menu with Quit (only one Quit entry)
+
+### Window behaviour
+- [ ] Closing window hides to tray (DockInTray=true), does not quit
+- [ ] Closing window quits (DockInTray=false)
+- [ ] Session logout closes app cleanly (sessionSaving check)
+- [ ] File → Quit exits cleanly, no crash or double-free
+
+### Stress / edge cases
+- [ ] Rapidly toggle mute — no crash, no stuck state
+- [ ] Rapidly drag slider — no crash, PA not flooded beyond responsiveness
+- [ ] Kill and restart PulseAudio while tmix is open — tmix recovers or fails gracefully
+- [ ] Open tmix with 0 devices on each tab — no crash, empty tabs look OK
+- [ ] Open tmix with 10+ playback streams — layout scrolls, no overlap
+
+## Bugs / Polish
+- [x] Taskbar / dock icon missing
+- [x] Recording tray icon red dot not appearing
+- [x] Icons: app-specific icons for Firefox etc.
+- [x] Input devices always show microphone icon regardless of PA device name hint
+- [x] Right-click "Move to Sink": show checkmark on the sink the stream is currently on
+- [x] Right-click mute item: fixed label "Mute" with checkmark when muted
+- [x] Scroll area for 10+ devices — TQScrollView wrapping tab pages and flat strip;
+ scroll bars appear only when content exceeds window width
+- [x] Window does not resize on card profile change (removed adjustSize())
+- [x] Window position persists across restarts
+- [x] Single-instance enforcement — second launch raises/shows the existing window (KUniqueApplication)
+- [x] Settings dialog is non-blocking (modeless show(), reloads config on each open)
+- [ ] Devices tab — sex it up vs pavucontrol-qt:
+ - Port availability indicators (plugged/unplugged) with port-type icons
+ (headphones, mic, HDMI, speaker, S/PDIF) from pa_card_port_info.type
+ - availability_group handling: when a combo jack is detected (multiple ports
+ share an availability_group), show a "What did you plug in?" prompt so the
+ user can disambiguate headphones vs headset vs mic
+ - Hide unavailable profiles by default (toggle to show all)
+
+## Features
+
+### Implemented
+- [x] Volume % label (live, updates on drag)
+- [x] Pan / balance slider per stereo device (reads + writes PA per-channel cvolume)
+- [x] Level meter — Output/Input via sink/source monitor; Playback via pa_stream_set_monitor_stream (per-stream)
+- [x] Slider tick marks every 5%
+- [x] Separator between devices
+- [x] Playback slider fix (was broken due to hardcoded 2-channel cvolume)
+- [x] Mute button: 3D toggle style
+- [x] App icons with multimedia fallback; amarok/TDE apps resolve via binary name
+- [x] tmix-peak streams hidden from Recording tab and pavucontrol (media.role=abstract)
+- [x] Menu bar — File: Quit, Settings: Configure TMix, Help: About TMix
+- [x] Per-device right-click context menu — mute (checkmark), set default, move to sink (checkmark on current)
+- [x] System tray (KSystemTray) — scroll wheel adjusts default sink volume, left-click popup/window toggle
+- [x] Tray icon — SmallIcon("kmix")/("audio-volume-medium") fallback; muted/low/medium/high states
+- [x] Tray popup (TmixPopup) — left-click, shows default output DeviceWidget + "Mixer" button,
+ auto-dismiss on outside click, positions above/below tray, stays on top
+- [x] Recording tray icon — second KSystemTray icon when any input is active;
+ tooltip lists names of active recording streams
+- [x] "Show all in one view" (no-tabs mode) — TQWidgetStack, rebuilds on toggle,
+ live device add/remove works in both modes
+- [x] Show/hide individual tabs (Output, Input, Playback, Recording) via preferences
+- [x] Preferences dialog — modeless (non-blocking), OK+Apply+Cancel,
+ General: dock in tray, popup on click, rec tray icon, confirm quit, scroll step
+ View: no-tabs toggle, show/hide per tab
+- [x] Window auto-sizes to content (adjustSize on device add/remove), minimum 300×200
+- [x] Bottom row fixed 30px height — all device widgets align regardless of content
+
+### To do
+- [x] Devices tab — PA card profile switcher (dropdown per card, set active profile)
+- [ ] Switches tab (like KMix "Switches" view)
+ Enumerate PA card profiles + ports (pa_context_get_card_info_list).
+ Show as checkboxes/comboboxes: active profile, port retasking, IEC958 enable,
+ Auto-Mute Mode, etc. May need ALSA fallback for raw HDA switches not
+ surfaced by PulseAudio (snd-hda-intel ctl elements via alsa-lib).
+- [ ] Profiles / sources management tab
+ List all PA sources and sinks with their active profile (e.g. "analog-stereo",
+ "hdmi-stereo-extra1"). Allow switching profiles via dropdown.
+ Show default sink/source with a star; click to set new default
+ (pa_context_set_default_sink / pa_context_set_default_source).
+ Subscribe to PA_SUBSCRIPTION_MASK_SERVER + CARD for live updates.
+- [x] Tray right-click: Configure, About, Quit (standard TDE style — no functional items)
+- [x] Remember window geometry across restarts
+
+## Big Refactor — Backend Abstraction
+Goal: replace KMix entirely across all Trinity platforms (Linux PA/PW/ALSA, FreeBSD OSS,
+legacy systems). Each backend is self-contained end-to-end: its own model, its own widgets.
+The main window is a dumb shell.
+
+Architecture:
+ AbstractBackend (minimal interface)
+ - name() / open() / close()
+ - createMixerWidget(parent) → TQWidget*
+ - createDevicesWidget(parent)→ TQWidget* (null if not supported)
+
+ PulseAudioBackend : AbstractBackend — current code, reorganised
+ OSSBackend : AbstractBackend — flat sliders, no streams
+ AlsaBackend : AbstractBackend — HDA controls, switches
+ PipeWireBackend : AbstractBackend — routing graph if ever needed
+
+ MixerWindow shrinks to: tray, menu, prefs, geometry, "host what backend gives me."
+ Shared UI widgets (DeviceWidget, LevelMeter, BalanceKnob) become a toolkit
+ backends may use or ignore — not a framework they're forced into.
+
+ Backend selected at startup via config key "Backend" (default: pulseaudio).
+ Build system conditionally compiles backends per platform.
+
+Why: the OSS→ALSA→PA retrofit history was painful. No backend should ever know
+about another; no generic UI code should check backend capabilities via flags.
+- [ ] L/R channel lock/unlock button — when unlocked, show two independent sliders
+ for left and right channels; when locked, they move together (current behavior)
+- [ ] DCOP interface (get/set volume, mute, list devices)
+- [ ] Dark/light theme awareness (follow TDE palette)
+- [ ] Horizontal layout mode — device strips laid out left-to-right instead of
+ top-to-bottom; label above slider, level meter beside it. Toggle in View menu.
+- [ ] Current mixer selector — dropdown or sub-menu to switch between PulseAudio
+ and raw ALSA hardware cards (like KMix "Current Mixer"). Each card gets its
+ own tab set; PA is the default. Enumerate via pa_context_get_card_info_list
+ for PA cards; snd_ctl_open for ALSA HDA cards.
+- [ ] Popup config options (Settings → General):
+ Popup content: default output only (default) | all outputs | active playback streams
+ Show level meter in popup: yes/no (saves vertical space)
+
+## Settings / Polish (do later)
+- [ ] Settings dialog: switch from KDialogBase Tabbed to IconList style (like KMix) —
+ big sidebar icons (General, View, etc.) with page content on the right.
+- [ ] Settings dialog: Defaults button, Help button
+- [ ] Settings dialog: grey out Apply until a change is actually made
+- [ ] Show/hide toggles for tickmarks, labels, level meters (View tab)
+- [ ] KMix-style classic tray widget — large tray area showing default sink volume slider
+ directly in the panel (not a popup), like KMix's docked mixer strip.
+
+## Distribution / Integration
+- [ ] .desktop file + icon
+- [ ] CMake install rules (bin, desktop, icon)
+- [ ] PipeWire-native backend (currently works via PW's PA compatibility layer)
+- [ ] Package as trinity-mixer