diff --git a/cosmic-applet-audio/src/main.rs b/cosmic-applet-audio/src/main.rs index 91dcc2ac..a91d4257 100644 --- a/cosmic-applet-audio/src/main.rs +++ b/cosmic-applet-audio/src/main.rs @@ -39,6 +39,7 @@ use mpris_subscription::MprisUpdate; mod config; mod mpris_subscription; +mod pipewire; mod pulse; const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/cosmic-applet-audio/src/pipewire.rs b/cosmic-applet-audio/src/pipewire.rs new file mode 100644 index 00000000..c7967be8 --- /dev/null +++ b/cosmic-applet-audio/src/pipewire.rs @@ -0,0 +1,21 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: MPL-2.0 + +use std::path::Path; +use std::process::Stdio; + +/// Plays an audio file. +pub fn play(path: &Path) { + let _result = tokio::process::Command::new("pw-play") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .arg(path) + .spawn(); +} + +pub fn play_audio_volume_change() { + play(Path::new( + "/usr/share/sounds/freedesktop/stereo/audio-volume-change.oga", + )); +} diff --git a/cosmic-applet-audio/src/pulse.rs b/cosmic-applet-audio/src/pulse.rs index 93e746f4..acc4d0d6 100644 --- a/cosmic-applet-audio/src/pulse.rs +++ b/cosmic-applet-audio/src/pulse.rs @@ -2,10 +2,11 @@ use std::cell::RefCell; use std::{rc::Rc, thread}; extern crate libpulse_binding as pulse; + use cosmic::iced::{self, subscription}; use cosmic::iced_futures::futures::{self, SinkExt}; use cosmic_time::once_cell::sync::Lazy; -//use futures::channel::mpsc; + use libpulse_binding::{ callbacks::ListResult, context::{ @@ -17,6 +18,9 @@ use libpulse_binding::{ proplist::Proplist, volume::ChannelVolumes, }; + +use std::time::{Duration, Instant}; + use tokio::sync::{mpsc, Mutex}; pub static FROM_PULSE: Lazy, mpsc::Sender)>>> = @@ -386,6 +390,7 @@ struct PulseServer { mainloop: Rc>, context: Rc>, introspector: Introspector, + last_playback: Instant, } #[derive(Clone, Debug)] @@ -432,6 +437,7 @@ impl PulseServer { mainloop, context, introspector, + last_playback: Instant::now(), }) } @@ -631,6 +637,12 @@ impl PulseServer { .introspector .set_sink_volume_by_name(name, volume, None); self.wait_for_result(op).ok(); + + let now = Instant::now(); + if now.duration_since(self.last_playback) > Duration::from_millis(250) { + self.last_playback = now; + crate::pipewire::play_audio_volume_change(); + } } fn set_source_volume_by_name(&mut self, name: &str, volume: &ChannelVolumes) {