From 580b24e55da13a0ea856c5a79c7c7362c5e1b679 Mon Sep 17 00:00:00 2001 From: Tglman Date: Thu, 1 May 2025 02:52:28 +0100 Subject: [PATCH] feat: add support to change the volume scrolling on the volume icon --- src/clients/volume/mod.rs | 16 ++++++++++ src/clients/volume/sink.rs | 40 ++++++++++++++++++++++++- src/modules/volume.rs | 61 +++++++++++++++++++++++++++++++++----- 3 files changed, 109 insertions(+), 8 deletions(-) diff --git a/src/clients/volume/mod.rs b/src/clients/volume/mod.rs index 29f3935d..cc560981 100644 --- a/src/clients/volume/mod.rs +++ b/src/clients/volume/mod.rs @@ -29,6 +29,8 @@ pub enum Event { AddInput(SinkInput), UpdateInput(SinkInput), RemoveInput(u32), + VolumeUp(f64), + VolumeDown(f64), } #[derive(Debug)] @@ -309,4 +311,18 @@ pub fn percent_to_volume(target_percent: f64) -> u32 { } } +pub fn scroll_to_volume(current_value: u32, scroll_value: f64) -> u32 { + let mut val: i32 = current_value as i32; + let scroll_delta = scroll_value * -1000.0; + trace!("base+delta: {val} + {scroll_delta} orig: scroll_value"); + val += scroll_delta as i32; + if val > Volume::NORMAL.0 as i32 { + Volume::NORMAL.0 as u32 + } else if val < Volume::MUTED.0 as i32 { + Volume::MUTED.0 as u32 + } else { + val as u32 + } +} + register_client!(Client, volume); diff --git a/src/clients/volume/sink.rs b/src/clients/volume/sink.rs index 723cc1d9..f1889143 100644 --- a/src/clients/volume/sink.rs +++ b/src/clients/volume/sink.rs @@ -1,4 +1,7 @@ -use super::{ArcMutVec, Client, ConnectionState, Event, percent_to_volume, volume_to_percent}; +use super::{ + ArcMutVec, Client, ConnectionState, Event, percent_to_volume, scroll_to_volume, + volume_to_percent, +}; use crate::channels::SyncSenderExt; use crate::lock; use libpulse_binding::callbacks::ListResult; @@ -54,6 +57,41 @@ impl Client { } } + #[instrument(level = "trace")] + pub fn set_default_volume(&self, value: f64) { + trace!("raceived volume change: {value:?}"); + let mut active = None; + for sync in &*lock!(self.data.sinks) { + if sync.active { + active = Some(sync.name.to_string()); + break; + } + } + if let Some(name) = active { + 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 mut volume = rx.recv().expect("to receive info"); + for v in volume.get_mut() { + let dval = v.0; + let val = scroll_to_volume(v.0, value); + trace!("changing value from: {dval:?} to: {val}"); + v.0 = val; + } + + introspector.set_sink_volume_by_name(&name, &volume, None); + } + } + } + #[instrument(level = "trace")] pub fn set_sink_volume(&self, name: &str, volume_percent: f64) { if let ConnectionState::Connected { introspector, .. } = &mut *lock!(self.connection) { diff --git a/src/modules/volume.rs b/src/modules/volume.rs index b6af7462..287a2bdd 100644 --- a/src/modules/volume.rs +++ b/src/modules/volume.rs @@ -7,9 +7,12 @@ use crate::modules::{ }; use crate::{lock, module_impl, spawn}; use glib::Propagation; +use gtk::gdk::{EventMask, ScrollDirection}; use gtk::pango::EllipsizeMode; use gtk::prelude::*; -use gtk::{Button, CellRendererText, ComboBoxText, Label, Orientation, Scale, ToggleButton}; +use gtk::{ + Button, CellRendererText, ComboBoxText, EventBox, Label, Orientation, Scale, ToggleButton, +}; use serde::Deserialize; use std::collections::HashMap; use tokio::sync::mpsc; @@ -134,9 +137,11 @@ pub enum Update { InputVolume(u32, f64), InputMute(u32, bool), + InputVolumeUp(f64), + InputVolumeDown(f64), } -impl Module