WIP: listening for volume changes
This commit is contained in:
parent
27c1db7625
commit
3b8996a24c
1 changed files with 76 additions and 12 deletions
|
|
@ -3,16 +3,30 @@ use gtk4::{
|
||||||
RevealerTransitionType, Scale, Separator, Window,
|
RevealerTransitionType, Scale, Separator, Window,
|
||||||
};
|
};
|
||||||
use libcosmic_widgets::LabeledItem;
|
use libcosmic_widgets::LabeledItem;
|
||||||
use libpulse_binding::volume::Volume;
|
use libpulse_binding::{
|
||||||
use pulsectl::controllers::{types::DeviceInfo, DeviceControl, SinkController, SourceController};
|
context::subscribe::{Facility, InterestMaskSet, Operation},
|
||||||
|
volume::Volume,
|
||||||
|
};
|
||||||
|
use pulsectl::{
|
||||||
|
controllers::{types::DeviceInfo, DeviceControl, SinkController, SourceController},
|
||||||
|
Handler,
|
||||||
|
};
|
||||||
use relm4::{component, view, ComponentParts, RelmContainerExt, Sender, SimpleComponent};
|
use relm4::{component, view, ComponentParts, RelmContainerExt, Sender, SimpleComponent};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub enum Input {
|
||||||
|
UpdateInputs,
|
||||||
|
UpdateOutputs,
|
||||||
|
UpdateInputVolume,
|
||||||
|
UpdateOutputVolume,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
default_input: Option<DeviceInfo>,
|
default_input: Option<DeviceInfo>,
|
||||||
inputs: Vec<DeviceInfo>,
|
inputs: Vec<DeviceInfo>,
|
||||||
default_output: Option<DeviceInfo>,
|
default_output: Option<DeviceInfo>,
|
||||||
outputs: Vec<DeviceInfo>,
|
outputs: Vec<DeviceInfo>,
|
||||||
|
handler: Handler,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for App {
|
impl Default for App {
|
||||||
|
|
@ -25,17 +39,20 @@ impl Default for App {
|
||||||
SinkController::create().expect("failed to create output controller");
|
SinkController::create().expect("failed to create output controller");
|
||||||
let default_output = output_controller.get_default_device().ok();
|
let default_output = output_controller.get_default_device().ok();
|
||||||
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")
|
||||||
|
.expect("failed to connect to pulse");
|
||||||
Self {
|
Self {
|
||||||
default_input,
|
default_input,
|
||||||
inputs,
|
inputs,
|
||||||
default_output,
|
default_output,
|
||||||
outputs,
|
outputs,
|
||||||
|
handler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn get_default_input_name(&self) -> &str {
|
fn get_default_input_name(&self) -> &str {
|
||||||
match &self.default_input {
|
match &self.default_input {
|
||||||
Some(input) => match &input.description {
|
Some(input) => match &input.description {
|
||||||
Some(name) => name.as_str(),
|
Some(name) => name.as_str(),
|
||||||
|
|
@ -45,7 +62,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_default_output_name(&self) -> &str {
|
fn get_default_output_name(&self) -> &str {
|
||||||
match &self.default_output {
|
match &self.default_output {
|
||||||
Some(output) => match &output.description {
|
Some(output) => match &output.description {
|
||||||
Some(name) => name.as_str(),
|
Some(name) => name.as_str(),
|
||||||
|
|
@ -54,15 +71,55 @@ impl App {
|
||||||
None => "No Output Device",
|
None => "No Output Device",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Input {
|
fn update_default_input(&mut self) {
|
||||||
UpdateInputs,
|
let mut input_controller =
|
||||||
UpdateOutputs,
|
SourceController::create().expect("failed to create input controller");
|
||||||
}
|
self.default_input = match self.default_input.as_ref() {
|
||||||
|
Some(input) => match &input.name {
|
||||||
|
Some(name) => input_controller.get_device_by_name(name.as_str()).ok(),
|
||||||
|
None => input_controller.get_device_by_index(input.index).ok(),
|
||||||
|
},
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl App {
|
fn update_default_output(&mut self) {
|
||||||
pub fn update_inputs(&self, widgets: &AppWidgets) {
|
let mut output_controller =
|
||||||
|
SinkController::create().expect("failed to create output controller");
|
||||||
|
self.default_output = match self.default_output.as_ref() {
|
||||||
|
Some(output) => match &output.name {
|
||||||
|
Some(name) => output_controller.get_device_by_name(name.as_str()).ok(),
|
||||||
|
None => output_controller.get_device_by_index(output.index).ok(),
|
||||||
|
},
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subscribe_for_updates(&self, input: &Sender<Input>) {
|
||||||
|
let mut context = self.handler.context.borrow_mut();
|
||||||
|
let input = input.clone();
|
||||||
|
context.set_subscribe_callback(Some(Box::new(move |facility, operation, _idx| {
|
||||||
|
match dbg!(operation) {
|
||||||
|
Some(Operation::Changed) => {}
|
||||||
|
_ => return,
|
||||||
|
}
|
||||||
|
match dbg!(facility) {
|
||||||
|
Some(Facility::Sink | Facility::SinkInput) => {
|
||||||
|
send!(input, Input::UpdateOutputVolume);
|
||||||
|
}
|
||||||
|
Some(Facility::Source | Facility::SourceOutput) => {
|
||||||
|
send!(input, Input::UpdateInputVolume);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
})));
|
||||||
|
context.subscribe(InterestMaskSet::all(), |success| {
|
||||||
|
println!("success: {}", success);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_inputs(&self, widgets: &AppWidgets) {
|
||||||
let mut input_controller =
|
let mut input_controller =
|
||||||
SourceController::create().expect("failed to create input controller");
|
SourceController::create().expect("failed to create input controller");
|
||||||
let inputs = input_controller.list_devices().unwrap_or_default();
|
let inputs = input_controller.list_devices().unwrap_or_default();
|
||||||
|
|
@ -95,7 +152,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_outputs(&self, widgets: &AppWidgets) {
|
fn update_outputs(&self, widgets: &AppWidgets) {
|
||||||
let mut output_controller =
|
let mut output_controller =
|
||||||
SinkController::create().expect("failed to create output controller");
|
SinkController::create().expect("failed to create output controller");
|
||||||
let outputs = output_controller.list_devices().unwrap_or_default();
|
let outputs = output_controller.list_devices().unwrap_or_default();
|
||||||
|
|
@ -235,6 +292,7 @@ impl SimpleComponent for App {
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let model = App::default();
|
let model = App::default();
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
model.subscribe_for_updates(input);
|
||||||
|
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
|
|
@ -252,6 +310,12 @@ impl SimpleComponent for App {
|
||||||
Input::UpdateInputs => {
|
Input::UpdateInputs => {
|
||||||
self.inputs.clear();
|
self.inputs.clear();
|
||||||
}
|
}
|
||||||
|
Input::UpdateInputVolume => {
|
||||||
|
self.update_default_input();
|
||||||
|
}
|
||||||
|
Input::UpdateOutputVolume => {
|
||||||
|
self.update_default_output();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue