1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-09-15 19:26:58 +02:00

Remove unused parts of pulseaudio module

This commit is contained in:
Reinout Meliesie 2025-08-20 20:51:36 +02:00
commit 54e91facd3
Signed by: zedfrigg
GPG key ID: 3AFCC06481308BC6
4 changed files with 27 additions and 190 deletions

View file

@ -3,7 +3,7 @@ mod sink_input;
use crate::{APP_ID, arc_mut, lock, register_client, spawn_blocking}; use crate::{APP_ID, arc_mut, lock, register_client, spawn_blocking};
use libpulse_binding::callbacks::ListResult; use libpulse_binding::callbacks::ListResult;
use libpulse_binding::context::introspect::{Introspector, ServerInfo}; use libpulse_binding::context::introspect::ServerInfo;
use libpulse_binding::context::subscribe::{Facility, InterestMaskSet, Operation}; use libpulse_binding::context::subscribe::{Facility, InterestMaskSet, Operation};
use libpulse_binding::context::{Context, FlagSet, State}; use libpulse_binding::context::{Context, FlagSet, State};
use libpulse_binding::mainloop::standard::{IterateResult, Mainloop}; use libpulse_binding::mainloop::standard::{IterateResult, Mainloop};
@ -24,11 +24,11 @@ type ArcMutVec<T> = Arc<Mutex<Vec<T>>>;
pub enum Event { pub enum Event {
AddSink(Sink), AddSink(Sink),
UpdateSink(Sink), UpdateSink(Sink),
RemoveSink(String), RemoveSink,
AddInput(SinkInput), AddInput,
UpdateInput(SinkInput), UpdateInput,
RemoveInput(u32), RemoveInput,
} }
#[derive(Debug)] #[derive(Debug)]
@ -51,10 +51,7 @@ struct Data {
pub enum ConnectionState { pub enum ConnectionState {
Disconnected, Disconnected,
Connected { Connected,
context: Arc<Mutex<Context>>,
introspector: Introspector,
},
} }
impl Debug for ConnectionState { impl Debug for ConnectionState {
@ -64,7 +61,7 @@ impl Debug for ConnectionState {
"{}", "{}",
match self { match self {
Self::Disconnected => "Disconnected", Self::Disconnected => "Disconnected",
Self::Connected { .. } => "Connected", Self::Connected => "Connected",
} }
) )
} }
@ -120,14 +117,9 @@ impl Client {
error!("{err:?}"); error!("{err:?}");
} }
let introspector = lock!(context).introspect();
{ {
let mut inner = lock!(self.connection); let mut inner = lock!(self.connection);
*inner = ConnectionState::Connected { *inner = ConnectionState::Connected;
context,
introspector,
};
} }
loop { loop {
@ -291,22 +283,4 @@ fn volume_to_percent(volume: ChannelVolumes) -> f64 {
((avg - Volume::MUTED.0) as f64 / base_delta).round() ((avg - Volume::MUTED.0) as f64 / base_delta).round()
} }
/// Converts a percentage volume into a Pulse volume value,
/// which can be used for setting channel volumes.
pub fn percent_to_volume(target_percent: f64) -> u32 {
let base_delta = (Volume::NORMAL.0 as f32 - Volume::MUTED.0 as f32) / 100.0;
if target_percent < 0.0 {
Volume::MUTED.0
} else if target_percent == 100.0 {
Volume::NORMAL.0
} else if target_percent >= 150.0 {
(Volume::NORMAL.0 as f32 * 1.5) as u32
} else if target_percent < 100.0 {
Volume::MUTED.0 + target_percent as u32 * base_delta as u32
} else {
Volume::NORMAL.0 + (target_percent - 100.0) as u32 * base_delta as u32
}
}
register_client!(Client, volume); register_client!(Client, volume);

View file

@ -1,4 +1,4 @@
use super::{ArcMutVec, Client, ConnectionState, Event, percent_to_volume, volume_to_percent}; use super::{ArcMutVec, Client, Event, volume_to_percent};
use crate::channels::SyncSenderExt; use crate::channels::SyncSenderExt;
use crate::lock; use crate::lock;
use libpulse_binding::callbacks::ListResult; use libpulse_binding::callbacks::ListResult;
@ -6,7 +6,7 @@ use libpulse_binding::context::Context;
use libpulse_binding::context::introspect::SinkInfo; use libpulse_binding::context::introspect::SinkInfo;
use libpulse_binding::context::subscribe::Operation; use libpulse_binding::context::subscribe::Operation;
use libpulse_binding::def::SinkState; use libpulse_binding::def::SinkState;
use std::sync::{Arc, Mutex, mpsc}; use std::sync::{Arc, Mutex};
use tokio::sync::broadcast; use tokio::sync::broadcast;
use tracing::{debug, error, instrument, trace}; use tracing::{debug, error, instrument, trace};
@ -14,7 +14,6 @@ use tracing::{debug, error, instrument, trace};
pub struct Sink { pub struct Sink {
index: u32, index: u32,
pub name: String, pub name: String,
pub description: String,
pub volume: f64, pub volume: f64,
pub muted: bool, pub muted: bool,
pub active: bool, pub active: bool,
@ -29,11 +28,6 @@ impl From<&SinkInfo<'_>> for Sink {
.as_ref() .as_ref()
.map(ToString::to_string) .map(ToString::to_string)
.unwrap_or_default(), .unwrap_or_default(),
description: value
.description
.as_ref()
.map(ToString::to_string)
.unwrap_or_default(),
muted: value.mute, muted: value.mute,
volume: volume_to_percent(value.volume), volume: volume_to_percent(value.volume),
active: value.state == SinkState::Running, active: value.state == SinkState::Running,
@ -46,43 +40,6 @@ impl Client {
pub fn sinks(&self) -> Arc<Mutex<Vec<Sink>>> { pub fn sinks(&self) -> Arc<Mutex<Vec<Sink>>> {
self.data.sinks.clone() self.data.sinks.clone()
} }
#[instrument(level = "trace")]
pub fn set_default_sink(&self, name: &str) {
if let ConnectionState::Connected { context, .. } = &*lock!(self.connection) {
lock!(context).set_default_sink(name, |_| {});
}
}
#[instrument(level = "trace")]
pub fn set_sink_volume(&self, name: &str, volume_percent: f64) {
if let ConnectionState::Connected { introspector, .. } = &mut *lock!(self.connection) {
let (tx, rx) = mpsc::channel();
introspector.get_sink_info_by_name(name, move |info| {
let ListResult::Item(info) = info else {
return;
};
tx.send_expect(info.volume);
});
let new_volume = percent_to_volume(volume_percent);
let mut volume = rx.recv().expect("to receive info");
for v in volume.get_mut() {
v.0 = new_volume;
}
introspector.set_sink_volume_by_name(name, &volume, None);
}
}
#[instrument(level = "trace")]
pub fn set_sink_muted(&self, name: &str, muted: bool) {
if let ConnectionState::Connected { introspector, .. } = &mut *lock!(self.connection) {
introspector.set_sink_mute_by_name(name, muted, None);
}
}
} }
pub fn on_event( pub fn on_event(
@ -177,10 +134,9 @@ fn update(
fn remove(index: u32, sinks: &ArcMutVec<Sink>, tx: &broadcast::Sender<Event>) { fn remove(index: u32, sinks: &ArcMutVec<Sink>, tx: &broadcast::Sender<Event>) {
trace!("removing {index}"); trace!("removing {index}");
let mut sinks = lock!(sinks); let sinks = lock!(sinks);
if let Some(pos) = sinks.iter().position(|s| s.index == index) { if let Some(_pos) = sinks.iter().position(|s| s.index == index) {
let info = sinks.remove(pos); tx.send_expect(Event::RemoveSink);
tx.send_expect(Event::RemoveSink(info.name));
} }
} }

View file

@ -1,37 +1,22 @@
use super::{ArcMutVec, Client, ConnectionState, Event, percent_to_volume, volume_to_percent}; use super::{ArcMutVec, Client, Event};
use crate::channels::SyncSenderExt; use crate::channels::SyncSenderExt;
use crate::lock; use crate::lock;
use libpulse_binding::callbacks::ListResult; use libpulse_binding::callbacks::ListResult;
use libpulse_binding::context::Context; use libpulse_binding::context::Context;
use libpulse_binding::context::introspect::SinkInputInfo; use libpulse_binding::context::introspect::SinkInputInfo;
use libpulse_binding::context::subscribe::Operation; use libpulse_binding::context::subscribe::Operation;
use std::sync::{Arc, Mutex, mpsc}; use std::sync::{Arc, Mutex};
use tokio::sync::broadcast; use tokio::sync::broadcast;
use tracing::{debug, error, instrument, trace}; use tracing::{debug, error, instrument, trace};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SinkInput { pub struct SinkInput {
pub index: u32, pub index: u32,
pub name: String,
pub volume: f64,
pub muted: bool,
pub can_set_volume: bool,
} }
impl From<&SinkInputInfo<'_>> for SinkInput { impl From<&SinkInputInfo<'_>> for SinkInput {
fn from(value: &SinkInputInfo) -> Self { fn from(value: &SinkInputInfo) -> Self {
Self { Self { index: value.index }
index: value.index,
name: value
.name
.as_ref()
.map(ToString::to_string)
.unwrap_or_default(),
muted: value.mute,
volume: volume_to_percent(value.volume),
can_set_volume: value.has_volume && value.volume_writable,
}
} }
} }
@ -40,36 +25,6 @@ impl Client {
pub fn sink_inputs(&self) -> Arc<Mutex<Vec<SinkInput>>> { pub fn sink_inputs(&self) -> Arc<Mutex<Vec<SinkInput>>> {
self.data.sink_inputs.clone() self.data.sink_inputs.clone()
} }
#[instrument(level = "trace")]
pub fn set_input_volume(&self, index: u32, volume_percent: f64) {
if let ConnectionState::Connected { introspector, .. } = &mut *lock!(self.connection) {
let (tx, rx) = mpsc::channel();
introspector.get_sink_input_info(index, move |info| {
let ListResult::Item(info) = info else {
return;
};
tx.send_expect(info.volume);
});
let new_volume = percent_to_volume(volume_percent);
let mut volume = rx.recv().expect("to receive info");
for v in volume.get_mut() {
v.0 = new_volume;
}
introspector.set_sink_input_volume(index, &volume, None);
}
}
#[instrument(level = "trace")]
pub fn set_input_muted(&self, index: u32, muted: bool) {
if let ConnectionState::Connected { introspector, .. } = &mut *lock!(self.connection) {
introspector.set_sink_input_mute(index, muted, None);
}
}
} }
pub fn on_event( pub fn on_event(
@ -119,7 +74,7 @@ pub fn add(
trace!("adding {info:?}"); trace!("adding {info:?}");
lock!(inputs).push(info.into()); lock!(inputs).push(info.into());
tx.send_expect(Event::AddInput(info.into())); tx.send_expect(Event::AddInput);
} }
fn update( fn update(
@ -143,16 +98,15 @@ fn update(
inputs[pos] = info.into(); inputs[pos] = info.into();
} }
tx.send_expect(Event::UpdateInput(info.into())); tx.send_expect(Event::UpdateInput);
} }
fn remove(index: u32, inputs: &ArcMutVec<SinkInput>, tx: &broadcast::Sender<Event>) { fn remove(index: u32, inputs: &ArcMutVec<SinkInput>, tx: &broadcast::Sender<Event>) {
let mut inputs = lock!(inputs); let inputs = lock!(inputs);
trace!("removing {index}"); trace!("removing {index}");
if let Some(pos) = inputs.iter().position(|s| s.index == index) { if let Some(_pos) = inputs.iter().position(|s| s.index == index) {
let info = inputs.remove(pos); tx.send_expect(Event::RemoveInput);
tx.send_expect(Event::RemoveInput(info.index));
} }
} }

View file

@ -1,13 +1,13 @@
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt}; use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
use crate::clients::volume::{self, Event}; use crate::clients::volume::{self, Event};
use crate::config::{CommonConfig, LayoutConfig, TruncateMode}; use crate::config::CommonConfig;
use crate::gtk_helpers::IronbarGtkExt; use crate::gtk_helpers::IronbarGtkExt;
use crate::modules::{ use crate::modules::{
Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, PopupButton, WidgetContext, Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, PopupButton, WidgetContext,
}; };
use crate::{lock, module_impl, spawn}; use crate::{lock, module_impl, spawn};
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{Button, Image, Label, Scale, ToggleButton}; use gtk::{Button, Image};
use serde::Deserialize; use serde::Deserialize;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tracing::trace; use tracing::trace;
@ -15,48 +15,21 @@ use tracing::trace;
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct VolumeModule { pub struct VolumeModule {
/// Maximum value to allow volume sliders to reach.
/// Pulse supports values > 100 but this may result in distortion.
///
/// **Default**: `100`
#[serde(default = "default_max_volume")]
max_volume: f64,
#[serde(default = "default_icon_size")] #[serde(default = "default_icon_size")]
icon_size: i32, icon_size: i32,
// -- Common -- // -- Common --
/// See [truncate options](module-level-options#truncate-mode).
///
/// **Default**: `null`
pub(crate) truncate: Option<TruncateMode>,
/// See [layout options](module-level-options#layout)
#[serde(default, flatten)]
layout: LayoutConfig,
/// See [common options](module-level-options#common-options). /// See [common options](module-level-options#common-options).
#[serde(flatten)] #[serde(flatten)]
pub common: Option<CommonConfig>, pub common: Option<CommonConfig>,
} }
const fn default_max_volume() -> f64 {
100.0
}
const fn default_icon_size() -> i32 { const fn default_icon_size() -> i32 {
24 24
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Update { pub enum Update {}
SinkChange(String),
SinkVolume(String, f64),
SinkMute(String, bool),
InputVolume(u32, f64),
InputMute(u32, bool),
}
impl Module<Button> for VolumeModule { impl Module<Button> for VolumeModule {
type SendMessage = Event; type SendMessage = Event;
@ -68,7 +41,7 @@ impl Module<Button> for VolumeModule {
&self, &self,
_info: &ModuleInfo, _info: &ModuleInfo,
context: &WidgetContext<Self::SendMessage, Self::ReceiveMessage>, context: &WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
mut rx: mpsc::Receiver<Self::ReceiveMessage>, _rx: mpsc::Receiver<Self::ReceiveMessage>,
) -> color_eyre::Result<()> ) -> color_eyre::Result<()>
where where
<Self as Module<Button>>::SendMessage: Clone, <Self as Module<Button>>::SendMessage: Clone,
@ -102,8 +75,8 @@ impl Module<Button> for VolumeModule {
tx.send_update(Event::AddSink(sink)).await; tx.send_update(Event::AddSink(sink)).await;
} }
for input in inputs { for _input in inputs {
tx.send_update(Event::AddInput(input)).await; tx.send_update(Event::AddInput).await;
} }
// recv loop // recv loop
@ -114,19 +87,6 @@ impl Module<Button> for VolumeModule {
}); });
} }
// ui events
spawn(async move {
while let Some(update) = rx.recv().await {
match update {
Update::SinkChange(name) => client.set_default_sink(&name),
Update::SinkVolume(name, volume) => client.set_sink_volume(&name, volume),
Update::SinkMute(name, muted) => client.set_sink_muted(&name, muted),
Update::InputVolume(index, volume) => client.set_input_volume(index, volume),
Update::InputMute(index, muted) => client.set_input_muted(index, muted),
}
}
});
Ok(()) Ok(())
} }
@ -179,13 +139,6 @@ impl Module<Button> for VolumeModule {
} }
} }
struct InputUi {
container: gtk::Box,
label: Label,
slider: Scale,
btn_mute: ToggleButton,
}
fn determine_volume_icon(muted: bool, volume: f64) -> String { fn determine_volume_icon(muted: bool, volume: f64) -> String {
let icon_variant = if muted { let icon_variant = if muted {
"muted" "muted"