audio: Mpris media control fixes

The panel buttons for next/previous didn't do anything since `on_press`
wasn't set. Now they work.

Fixed `autosize` which I had accidentally committed after using it for
testing. (It would be good to figure out why the applets don't work
properly with autosize when run outside of the panel, since that's handy
for testing.)

I noticed with VLC, skipping a track makes the media controls disappear
very briefly, and sometimes the pause button didn't return. I guess
`can_play` (etc.) are temporarily set to false, probably expecting the
controls to be greyed out and not hidden from a panel. Anyway,
monitoring for changes to these properties as well will hopefully fix
the part where it could remain missing. Though I can't reproduce that
consistently.
This commit is contained in:
Ian Douglas Scott 2024-04-05 09:22:14 -07:00 committed by Jeremy Soller
parent 32b7012b79
commit 216d88e977
3 changed files with 31 additions and 13 deletions

View file

@ -50,7 +50,7 @@ const PLAY: &str = "media-playback-start-symbolic";
pub fn run() -> cosmic::iced::Result {
localize();
cosmic::applet::run::<Audio>(false, ())
cosmic::applet::run::<Audio>(true, ())
}
#[derive(Default)]
@ -160,7 +160,13 @@ impl Audio {
.map(|s| s.can_go_previous)
.unwrap_or_default()
{
elements.push(self.core.applet.icon_button(GO_BACK).into())
elements.push(
self.core
.applet
.icon_button(GO_BACK)
.on_press(Message::MprisRequest(MprisRequest::Previous))
.into(),
)
}
if let Some(play) = self.is_play() {
elements.push(
@ -181,7 +187,13 @@ impl Audio {
.map(|s| s.can_go_next)
.unwrap_or_default()
{
elements.push(self.core.applet.icon_button(GO_NEXT).into())
elements.push(
self.core
.applet
.icon_button(GO_NEXT)
.on_press(Message::MprisRequest(MprisRequest::Next))
.into(),
)
}
Some(match self.core.applet.anchor {

View file

@ -1,8 +1,8 @@
use std::{borrow::Cow, collections::HashMap, fmt::Debug, hash::Hash, path::PathBuf};
use std::{borrow::Cow, fmt::Debug, hash::Hash, path::PathBuf};
use cosmic::{
iced::{self, subscription},
iced_futures::futures::{self, future::OptionFuture, FutureExt, SinkExt, StreamExt},
iced_futures::futures::{self, future::OptionFuture, SinkExt, StreamExt},
};
use mpris2_zbus::{
enumerator,
@ -13,7 +13,6 @@ use tokio::join;
use urlencoding::decode;
use zbus::{
names::{BusName, OwnedBusName},
zvariant::OwnedValue,
Connection,
};
@ -129,8 +128,7 @@ struct State {
Box<dyn futures::Stream<Item = zbus::Result<enumerator::Event>> + Unpin + Send>,
players: Vec<MprisPlayer>,
active_player: Option<MprisPlayer>,
active_player_metadata_stream:
Option<zbus::PropertyStream<'static, HashMap<String, OwnedValue>>>,
active_player_metadata_stream: Option<Box<dyn futures::Stream<Item = ()> + Unpin + Send>>,
any_player_state_stream: futures::stream::SelectAll<zbus::PropertyStream<'static, String>>,
}
@ -195,8 +193,18 @@ impl State {
if self.active_player.as_ref().map(|p| p.name()) != new_active_player.map(|p| p.name()) {
self.active_player = new_active_player.cloned();
if let Some(player) = new_active_player {
self.active_player_metadata_stream =
Some(player.player.receive_metadata_changed().await);
let controls_changed = futures::stream::select_all([
player.player.receive_can_pause_changed().await,
player.player.receive_can_play_changed().await,
player.player.receive_can_go_previous_changed().await,
player.player.receive_can_go_next_changed().await,
]);
let metadata_changed = player.player.receive_metadata_changed().await;
let stream = futures::stream::select(
controls_changed.map(|_| ()),
metadata_changed.map(|_| ()),
);
self.active_player_metadata_stream = Some(Box::new(stream));
} else {
self.active_player_metadata_stream = None;
}
@ -242,7 +250,7 @@ async fn run(output: &mut futures::channel::mpsc::Sender<MprisUpdate>) {
_ = metadata_changed_next, if state.active_player.is_some() => {
},
event = state.enumerator_stream.next() => {
match dbg!(event) {
match event {
Some(Ok(enumerator::Event::Add(name))) => state.add_player(name).await,
Some(Ok(enumerator::Event::Remove(name))) => state.remove_player(name).await,
Some(Err(err)) => {

View file

@ -19,8 +19,6 @@ use libpulse_binding::{
volume::ChannelVolumes,
};
use std::time::{Duration, Instant};
use tokio::sync::{mpsc, Mutex};
pub static FROM_PULSE: Lazy<Mutex<Option<(mpsc::Receiver<Message>, mpsc::Sender<Message>)>>> =