Changing audio from an external source works now!

This commit is contained in:
Lucy 2022-03-23 13:36:09 -04:00
parent 84364936b7
commit 660c19624b
No known key found for this signature in database
GPG key ID: EBC517FAD666BBF1
4 changed files with 42 additions and 27 deletions

12
Cargo.lock generated
View file

@ -237,8 +237,8 @@ dependencies = [
name = "cosmic-applet-audio" name = "cosmic-applet-audio"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-io",
"futures-util", "futures-util",
"gtk4",
"libcosmic-widgets", "libcosmic-widgets",
"libpulse-binding", "libpulse-binding",
"pulsectl-rs", "pulsectl-rs",
@ -251,7 +251,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"gtk4", "gtk4",
"once_cell", "once_cell",
"relm4-macros 0.4.2", "relm4-macros 0.4.3",
"tokio", "tokio",
"zbus", "zbus",
] ]
@ -266,7 +266,7 @@ dependencies = [
"itertools", "itertools",
"libcosmic-widgets", "libcosmic-widgets",
"once_cell", "once_cell",
"relm4-macros 0.4.2", "relm4-macros 0.4.3",
"slotmap", "slotmap",
"tokio", "tokio",
"zbus", "zbus",
@ -281,7 +281,7 @@ dependencies = [
"logind-zbus", "logind-zbus",
"nix 0.23.1", "nix 0.23.1",
"once_cell", "once_cell",
"relm4-macros 0.4.2", "relm4-macros 0.4.3",
"tokio", "tokio",
"zbus", "zbus",
] ]
@ -1519,9 +1519,9 @@ dependencies = [
[[package]] [[package]]
name = "relm4-macros" name = "relm4-macros"
version = "0.4.2" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d70f60fbeae94001a45d0a2f7ff66b4c18535cc00ebd746d2ced0be1916cf83f" checksum = "b0df3a77e22dee74ce668daa437252e02a19252ae0eda49ebebb20b365afc52a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View file

@ -5,9 +5,11 @@ edition = "2021"
license = "LGPL-3.0-or-later" license = "LGPL-3.0-or-later"
[dependencies] [dependencies]
async-io = "1.6.0"
futures-util = "0.3.21" futures-util = "0.3.21"
gtk4 = "0.4.6"
libcosmic-widgets = { git = "https://github.com/pop-os/libcosmic", branch = "lucy/widgets" } libcosmic-widgets = { git = "https://github.com/pop-os/libcosmic", branch = "lucy/widgets" }
libpulse-binding = "2.26.0" libpulse-binding = "2.26.0"
pulsectl-rs = "0.3.2" pulsectl-rs = "0.3.2"
relm4 = { git = "https://github.com/AaronErhardt/relm4", branch = "new-approach", features = ["macros"] } relm4 = { git = "https://github.com/AaronErhardt/relm4", branch = "new-approach", features = ["macros"] }
[features]

View file

@ -1,7 +1,4 @@
use gtk4::{ use futures_util::StreamExt;
prelude::*, Box as GtkBox, Button, Image, Label, ListBox, Orientation, PositionType, Revealer,
RevealerTransitionType, Scale, Separator, Window,
};
use libcosmic_widgets::LabeledItem; use libcosmic_widgets::LabeledItem;
use libpulse_binding::{ use libpulse_binding::{
context::subscribe::{Facility, InterestMaskSet, Operation}, context::subscribe::{Facility, InterestMaskSet, Operation},
@ -11,7 +8,17 @@ use pulsectl::{
controllers::{types::DeviceInfo, DeviceControl, SinkController, SourceController}, controllers::{types::DeviceInfo, DeviceControl, SinkController, SourceController},
Handler, Handler,
}; };
use relm4::{component, view, ComponentParts, RelmContainerExt, Sender, SimpleComponent}; use relm4::{
component,
gtk::{
self,
glib::{self, clone},
prelude::*,
Box as GtkBox, Button, Image, Label, ListBox, Orientation, PositionType, Revealer,
RevealerTransitionType, Scale, Separator, Window,
},
view, ComponentParts, RelmContainerExt, Sender, SimpleComponent,
};
use std::rc::Rc; use std::rc::Rc;
pub enum AppInput { pub enum AppInput {
@ -41,6 +48,13 @@ impl Default for App {
let outputs = output_controller.list_devices().unwrap_or_default(); let outputs = output_controller.list_devices().unwrap_or_default();
let handler = Handler::connect("com.system76.cosmic.applets.audio") let handler = Handler::connect("com.system76.cosmic.applets.audio")
.expect("failed to connect to pulse"); .expect("failed to connect to pulse");
relm4::spawn_local(clone!(@weak handler.mainloop as main_loop => async move {
let mut timer = async_io::Timer::interval(std::time::Duration::from_millis(100));
loop {
main_loop.borrow_mut().iterate(false);
timer.next().await;
}
}));
Self { Self {
default_input, default_input,
inputs, inputs,
@ -100,11 +114,10 @@ impl App {
let mut context = self.handler.context.borrow_mut(); let mut context = self.handler.context.borrow_mut();
let input = input.clone(); let input = input.clone();
context.set_subscribe_callback(Some(Box::new(move |facility, operation, _idx| { context.set_subscribe_callback(Some(Box::new(move |facility, operation, _idx| {
match dbg!(operation) { if !matches!(operation, Some(Operation::Changed)) {
Some(Operation::Changed) => {} return;
_ => return,
} }
match dbg!(facility) { match facility {
Some(Facility::Sink | Facility::SinkInput) => { Some(Facility::Sink | Facility::SinkInput) => {
send!(input, AppInput::OutputVolume); send!(input, AppInput::OutputVolume);
} }
@ -114,9 +127,7 @@ impl App {
_ => {} _ => {}
} }
}))); })));
context.subscribe(InterestMaskSet::all(), |success| { context.subscribe(InterestMaskSet::all(), |_| {});
println!("success: {}", success);
});
} }
fn update_inputs(&self, widgets: &AppWidgets) { fn update_inputs(&self, widgets: &AppWidgets) {
@ -213,7 +224,7 @@ impl SimpleComponent for App {
set_format_value_func: |_, value| { set_format_value_func: |_, value| {
format!("{:.0}%", value) format!("{:.0}%", value)
}, },
set_value: model.default_output.as_ref().map(|info| (info.volume.avg().0 as f64 / Volume::NORMAL.0 as f64) * 100.).unwrap_or(0.), set_value: watch! { model.default_output.as_ref().map(|info| (info.volume.avg().0 as f64 / Volume::NORMAL.0 as f64) * 100.).unwrap_or(0.) },
set_value_pos: PositionType::Right, set_value_pos: PositionType::Right,
set_hexpand: true set_hexpand: true
} }
@ -228,10 +239,12 @@ impl SimpleComponent for App {
set_format_value_func: |_, value| { set_format_value_func: |_, value| {
format!("{:.0}%", value) format!("{:.0}%", value)
}, },
set_value: model.default_input set_value: watch! {
.as_ref() model.default_input
.map(|info| (info.volume.avg().0 as f64 / Volume::NORMAL.0 as f64) * 100.) .as_ref()
.unwrap_or(0.), .map(|info| (info.volume.avg().0 as f64 / Volume::NORMAL.0 as f64) * 100.)
.unwrap_or(0.)
},
set_value_pos: PositionType::Right, set_value_pos: PositionType::Right,
set_hexpand: true set_hexpand: true
} }
@ -253,7 +266,7 @@ impl SimpleComponent for App {
append: outputs_revealer = &Revealer { append: outputs_revealer = &Revealer {
set_transition_type: RevealerTransitionType::SlideDown, set_transition_type: RevealerTransitionType::SlideDown,
set_child: outputs = Some(&ListBox) { set_child: outputs = Some(&ListBox) {
set_selection_mode: gtk4::SelectionMode::None, set_selection_mode: gtk::SelectionMode::None,
set_activate_on_single_click: true set_activate_on_single_click: true
} }
} }
@ -275,7 +288,7 @@ impl SimpleComponent for App {
append: inputs_revealer = &Revealer { append: inputs_revealer = &Revealer {
set_transition_type: RevealerTransitionType::SlideDown, set_transition_type: RevealerTransitionType::SlideDown,
set_child: inputs = Some(&ListBox) { set_child: inputs = Some(&ListBox) {
set_selection_mode: gtk4::SelectionMode::None, set_selection_mode: gtk::SelectionMode::None,
set_activate_on_single_click: true set_activate_on_single_click: true
} }
} }

View file

@ -10,7 +10,7 @@ futures-util = "0.3.21"
gtk4 = "0.4.6" gtk4 = "0.4.6"
itertools = "0.10.3" itertools = "0.10.3"
once_cell = "1.9.0" once_cell = "1.9.0"
relm4-macros = "0.4.1" relm4-macros = "0.4.3"
slotmap = "1.0.6" slotmap = "1.0.6"
tokio = { version = "1.15.0", features = ["full"] } tokio = { version = "1.15.0", features = ["full"] }
zbus = "2.0.1" zbus = "2.0.1"