commit 40d8e66a9cee902179b6b5d23ad1a32e0fe114e6
parent 3e18dcf2055188a06a98262e8439e481e83975df
Author: Matthew Gantenbein <ganten1998@gmail.com>
Date: Sun, 31 May 2026 20:55:28 -0500
fix: complete the combine feature + installer (prior 2 commits didn't build)
Commits 190a263 and df058d9 were pushed with a non-compiling tree (a cancelled
tool batch left a duplicate combined_label fn in server.rs and a missing
`marked` field on App). This fixes both forward.
Now genuinely verified: cargo build --workspace clean, 19 tests green, 0
warnings; live StartCombined of two audio PIDs → one route, source_count=2,
peak 1.000 (real mixed audio flowing). install.sh/uninstall.sh syntax-checked;
non-sudo stages (release build, Hydra.app sign, universal Hydra.driver build)
all run clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat:
2 files changed, 2 insertions(+), 31 deletions(-)
diff --git a/crates/hydra/src/app.rs b/crates/hydra/src/app.rs
@@ -25,6 +25,8 @@ pub struct App {
/// When false (default), background daemons (kind 2) are hidden from the app list,
/// so you see real apps (Spotify, browsers, DAWs) not the system-helper wall.
pub show_all_apps: bool,
+ /// PIDs the user has marked (space) to combine into one route.
+ pub marked: std::collections::BTreeSet<i32>,
pub routes: Vec<RouteSummary>,
/// Output devices a route can target (output_channels > 0), e.g. speakers or "Hydra".
pub outputs: Vec<AudioDevice>,
diff --git a/crates/hydrad/src/server.rs b/crates/hydrad/src/server.rs
@@ -161,34 +161,3 @@ fn combined_label(pids: &[i32], output_uid: Option<&str>) -> (String, Vec<String
(format!("{sources} → {output}"), bundle_ids)
}
-
-/// Build the label + bundle-id list for a combined (multi-source) route.
-/// Label reads like "Safari + Spotify +1 → Hydra".
-fn combined_label(pids: &[i32], output_uid: Option<&str>) -> (String, Vec<String>) {
- let apps = process::list_audio_processes();
- let names: Vec<String> = pids
- .iter()
- .map(|&pid| {
- apps.iter().find(|a| a.pid == pid).map(|a| a.name.clone()).unwrap_or_else(|| format!("pid {pid}"))
- })
- .collect();
- let bundle_ids: Vec<String> =
- pids.iter().filter_map(|&pid| apps.iter().find(|a| a.pid == pid).and_then(|a| a.bundle_id.clone())).collect();
-
- let sources = match names.len() {
- 0 => "nothing".to_string(),
- 1 => names[0].clone(),
- 2 => format!("{} + {}", names[0], names[1]),
- n => format!("{} + {} +{}", names[0], names[1], n - 2),
- };
-
- let output = match output_uid {
- Some(uid) => hal::list_devices()
- .ok()
- .and_then(|ds| ds.into_iter().find(|d| d.uid == uid).map(|d| d.name))
- .unwrap_or_else(|| uid.to_string()),
- None => "Default Output".to_string(),
- };
-
- (format!("{sources} → {output}"), bundle_ids)
-}