Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 62 additions & 31 deletions cosmic-applet-audio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,15 @@ use cosmic::{
};
use cosmic_settings_audio_client::{self as audio_client, CosmicAudioProxy};
use futures::SinkExt;
use iced::platform_specific::shell::wayland::commands::popup::{destroy_popup, get_popup};
use mpris_subscription::{MprisRequest, MprisUpdate};
use mpris2_zbus::player::PlaybackStatus;
use std::{cell::RefCell, rc::Rc, sync::Arc};
use std::{
sync::{
Arc,
atomic::{self, AtomicU32},
},
time::Duration,
};

mod config;
mod mpris_subscription;
Expand All @@ -58,11 +63,15 @@ pub struct Audio {
/// Track the applet's popup window.
popup: Option<window::Id>,
/// Varlink connection to `com.system76.CosmicSettings.Audio`.
audio_client: Option<Rc<RefCell<audio_client::Client>>>,
audio_client: Option<audio_client::Client>,
/// Known audio device state
model: model::Model,
/// Whether to expand the revealer of a source or sink device.
is_open: IsOpen,
/// Used to debounce sink volume updates.
applied_sink_volume: Arc<AtomicU32>,
/// Used to deboune source volume updates.
applied_source_volume: Arc<AtomicU32>,
/// Max slider volume for the sink device, as determined by the amplification property.
max_sink_volume: u32,
/// Max slider volume for the source device, as determined by the amplification property.
Expand Down Expand Up @@ -125,26 +134,27 @@ enum IsOpen {
pub enum Message {
/// Connection to `com.system76.CosmicSettings`.
Client(Arc<audio_client::Client>),
Ignore,
SetSinkVolume(u32),
SetSourceVolume(u32),
ToggleSinkMute,
ToggleSourceMute,
SetDefaultSink(usize),
SetDefaultSource(usize),
OutputToggle,
InputToggle,
TogglePopup,
CloseRequested(window::Id),
ToggleMediaControlsInTopPanel(bool),
ConfigChanged(AudioAppletConfig),
Ignore,
InputToggle,
Mpris(mpris_subscription::MprisUpdate),
MprisRequest(MprisRequest),
Token(TokenUpdate),
OpenSettings,
OutputToggle,
ReattachClient(Arc<audio_client::Client>),
Rectangle(RectangleUpdate<u32>),
SetDefaultSink(usize),
SetDefaultSource(usize),
SetSinkVolume(u32),
SetSourceVolume(u32),
Subscription(audio_client::Event),
Surface(surface::Action),
Rectangle(RectangleUpdate<u32>),
ToggleMediaControlsInTopPanel(bool),
TogglePopup,
ToggleSinkMute,
ToggleSourceMute,
Token(TokenUpdate),
}

// TODO
Expand Down Expand Up @@ -287,6 +297,11 @@ impl cosmic::Application for Audio {
self.rectangle_tracker.replace(tracker);
}
},
Message::ReattachClient(client) => {
if let Some(client) = Arc::into_inner(client) {
self.audio_client = Some(client);
}
}
Message::Ignore => {}
Message::TogglePopup => {
if let Some(p) = self.popup.take() {
Expand Down Expand Up @@ -359,7 +374,7 @@ impl cosmic::Application for Audio {
&& let Some(client) = self.audio_client.as_mut()
{
futures::executor::block_on(async {
_ = client.borrow_mut().conn.set_default(node_id, true).await;
_ = client.conn.set_default(node_id, true).await;
});
}
}
Expand All @@ -370,43 +385,59 @@ impl cosmic::Application for Audio {
&& let Some(client) = self.audio_client.as_mut()
{
futures::executor::block_on(async {
_ = client.borrow_mut().conn.set_default(node_id, true).await;
_ = client.conn.set_default(node_id, true).await;
});
}
}

Message::ToggleSinkMute => {
if let Some(ref mut client) = self.audio_client {
futures::executor::block_on(async {
_ = client.borrow_mut().conn.sink_mute_toggle().await;
_ = client.conn.sink_mute_toggle().await;
});
}
}

Message::ToggleSourceMute => {
if let Some(ref mut client) = self.audio_client {
futures::executor::block_on(async {
_ = client.borrow_mut().conn.source_mute_toggle().await;
_ = client.conn.source_mute_toggle().await;
});
}
}

Message::SetSinkVolume(volume) => {
if let Some(ref mut client) = self.audio_client {
self.model.active_sink.volume = volume;
self.model.active_sink.volume_text = volume.to_string();
futures::executor::block_on(async {
_ = client.borrow_mut().conn.set_sink_volume(volume).await;
self.applied_sink_volume
.store(volume, atomic::Ordering::Relaxed);
self.model.active_sink.volume = volume;
self.model.active_sink.volume_text = volume.to_string();
if let Some(mut client) = self.audio_client.take() {
let volume = Arc::clone(&self.applied_sink_volume);
return cosmic::Task::future(async move {
tokio::time::sleep(Duration::from_millis(128)).await;
_ = client
.conn
.set_sink_volume(volume.load(atomic::Ordering::Relaxed))
.await;
Message::ReattachClient(Arc::new(client)).into()
});
}
}

Message::SetSourceVolume(volume) => {
if let Some(ref mut client) = self.audio_client {
self.model.active_source.volume = volume;
self.model.active_source.volume_text = volume.to_string();
futures::executor::block_on(async {
_ = client.borrow_mut().conn.set_source_volume(volume).await;
self.applied_source_volume
.store(volume, atomic::Ordering::Relaxed);
self.model.active_source.volume = volume;
self.model.active_source.volume_text = volume.to_string();
if let Some(mut client) = self.audio_client.take() {
let volume = Arc::clone(&self.applied_source_volume);
return cosmic::Task::future(async move {
tokio::time::sleep(Duration::from_millis(128)).await;
_ = client
.conn
.set_sink_volume(volume.load(atomic::Ordering::Relaxed))
.await;
Message::ReattachClient(Arc::new(client)).into()
});
}
}
Expand Down Expand Up @@ -517,7 +548,7 @@ impl cosmic::Application for Audio {
}
Message::Client(client) => {
if let Some(client) = Arc::into_inner(client) {
self.audio_client = Some(Rc::new(RefCell::new(client)));
self.audio_client = Some(client);
self.model = model::Model::default();
}
}
Expand Down
Loading