From aaffebed4c0c7f3940e206319d7fc0ef8ca9f6b8 Mon Sep 17 00:00:00 2001 From: Marc Bornand Date: Fri, 24 Jan 2025 14:46:25 +0100 Subject: [PATCH 1/2] wireplumber: add more volume formats - Add the possibility to show the volume in linear, cubic, db, and cubic percent (default for backward compatibility). - Add the ability to change the scale for the scrolling action. - Make the minimal step flexible to fit any scale. --- man/waybar-wireplumber.5.scd | 25 ++++++++++- src/modules/wireplumber.cpp | 81 +++++++++++++++++++++++++++++------- 2 files changed, 88 insertions(+), 18 deletions(-) diff --git a/man/waybar-wireplumber.5.scd b/man/waybar-wireplumber.5.scd index ae78f184..45f1b92a 100644 --- a/man/waybar-wireplumber.5.scd +++ b/man/waybar-wireplumber.5.scd @@ -63,6 +63,11 @@ The *wireplumber* module displays the current volume reported by WirePlumber. default: 1.0 ++ The speed at which to change the volume when scrolling. +*scroll-scale*: ++ + typeof: string ++ + default: cubic_percent + The scale to use for the scrolling volume change. Options are 'linear', 'db', 'cubic', and 'cubic_percent'. + *on-click*: ++ typeof: string ++ Command to execute when clicked on the module. @@ -107,7 +112,13 @@ The *wireplumber* module displays the current volume reported by WirePlumber. # FORMAT REPLACEMENTS -*{volume}*: Volume in percentage. +*{volume}*: Volume in percentage, cubic scale as integer. + +*{volume_linear}*: Volume in linear scale as float. + +*{volume_cubic}*: Volume in cubic scale as float. + +*{volume_db}*: Volume in decibel scale as float. *{node_name}*: The node's nickname as reported by WirePlumber (*node.nick* property) @@ -123,7 +134,7 @@ The *wireplumber* module displays the current volume reported by WirePlumber. } ``` -## Separate Sink and Source Widgets +## Separate Sink and Source Widgets ``` "wireplumber#sink": { @@ -143,6 +154,16 @@ The *wireplumber* module displays the current volume reported by WirePlumber. } ``` +## Use a Different Scale + +``` +"wireplumber": { + "format": "{volume_db:.2f}dB", + "scroll-scale": "db", + "scroll-step": 2.5 +} +``` + # STYLE - *#wireplumber* diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index a43ad29b..f37445c7 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -1,6 +1,8 @@ #include "modules/wireplumber.hpp" #include +#include +#include bool isValidNodeId(uint32_t id) { return id > 0 && id < G_MAXUINT32; } @@ -396,7 +398,7 @@ void waybar::modules::Wireplumber::onMixerApiLoaded(WpObject* p, GAsyncResult* r spdlog::debug("[{}]: loaded mixer API", self->name_); g_ptr_array_add(self->apis_, ({ WpPlugin* p = wp_plugin_find(self->wp_core_, "mixer-api"); - g_object_set(G_OBJECT(p), "scale", 1 /* cubic */, nullptr); + g_object_set(G_OBJECT(p), "scale", 0 /* linear */, nullptr); p; })); @@ -436,8 +438,16 @@ auto waybar::modules::Wireplumber::update() -> void { label_.get_style_context()->remove_class("source-muted"); } - int vol = round(volume_ * 100.0); - int source_vol = round(source_volume_ * 100.0); + + double vol_cube = pow(volume_, 3); + double source_vol_cube = pow(source_volume_, 3); + + int vol = round(vol_cube * 100.0); + int source_vol = round(source_vol_cube * 100.0); + + double vol_db = 20.0 * log10(volume_); + double source_vol_db = 20.0 * log10(source_volume_); + // Get the state and apply state-specific format if available auto state = getState(vol); @@ -468,7 +478,10 @@ auto waybar::modules::Wireplumber::update() -> void { std::string markup = fmt::format(fmt::runtime(format), fmt::arg("node_name", node_name_), fmt::arg("volume", vol), fmt::arg("icon", getIcon(vol)), fmt::arg("format_source", formatted_source), - fmt::arg("source_volume", source_vol), fmt::arg("source_desc", source_name_)); + fmt::arg("source_volume", source_vol), fmt::arg("source_desc", source_name_), + fmt::arg("volume_linear", volume_), fmt::arg("volume_cubic", vol_cube), + fmt::arg("volume_db", vol_db),fmt::arg("source_volume_linear", source_volume_), + fmt::arg("source_volume_cubic", source_vol_cube), fmt::arg("source_volume_db", source_vol_db)); label_.set_markup(markup); if (tooltipEnabled()) { @@ -480,7 +493,10 @@ auto waybar::modules::Wireplumber::update() -> void { label_.set_tooltip_text(fmt::format( fmt::runtime(tooltipFormat), fmt::arg("node_name", node_name_), fmt::arg("volume", vol), fmt::arg("icon", getIcon(vol)), fmt::arg("format_source", formatted_source), - fmt::arg("source_volume", source_vol), fmt::arg("source_desc", source_name_))); + fmt::arg("source_volume", source_vol), fmt::arg("source_desc", source_name_), + fmt::arg("volume_linear", volume_), fmt::arg("volume_cubic", vol_cube), + fmt::arg("volume_db", vol_db), fmt::arg("source_volume_linear", source_volume_), + fmt::arg("source_volume_cubic", source_vol_cube), fmt::arg("source_volume_db", source_vol_db))); } else { label_.set_tooltip_text(node_name_); } @@ -499,28 +515,61 @@ bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll* e) { return true; } double maxVolume = 1; - double step = 1.0 / 100.0; + double step = 1.0; if (config_["scroll-step"].isDouble()) { - step = config_["scroll-step"].asDouble() / 100.0; + step = config_["scroll-step"].asDouble(); } if (config_["max-volume"].isDouble()) { - maxVolume = config_["max-volume"].asDouble() / 100.0; + maxVolume = config_["max-volume"].asDouble(); } - if (step < min_step_) step = min_step_; + double vol = volume_; + std::string scale = "cubic_percent"; + if (config_["scroll-scale"].isString()) { + scale = config_["scroll-scale"].asString(); + } - double newVol = volume_; + if (scale == "cubic") { + vol = pow(vol, 3); + } + else if (scale == "db") { + vol = log10(vol) * 20.0; + } + else if (scale == "cubic_percent") { + vol = pow(vol, 3) * 100.0; + } + + + double newVol = vol; if (dir == SCROLL_DIR::UP) { - if (volume_ < maxVolume) { - newVol = volume_ + step; - if (newVol > maxVolume) newVol = maxVolume; + newVol = vol + step; + } else if (dir == SCROLL_DIR::DOWN) { + newVol = vol - step; + } + + if (scale == "cubic") { + newVol = cbrt(newVol); + } + else if (scale == "db") { + newVol = exp10(newVol / 20.0); + } + else if (scale == "cubic_percent") { + newVol = cbrt(newVol / 100.0); + } + + if (dir == SCROLL_DIR::UP) { + if (volume_ + min_step_ > newVol) { + newVol = volume_ + min_step_; } } else if (dir == SCROLL_DIR::DOWN) { - if (volume_ > 0) { - newVol = volume_ - step; - if (newVol < 0) newVol = 0; + if (volume_ - min_step_ < newVol) { + newVol = volume_ - min_step_; } } + + if (newVol < 0) newVol = 0; + else if (newVol > maxVolume) newVol = maxVolume; + if (newVol != volume_) { GVariant* variant = g_variant_new_double(newVol); gboolean ret; From cd2b1802cbcb9d49803b5742a1b7d11455b6e43b Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 3 Jul 2026 22:21:07 +0200 Subject: [PATCH 2/2] Apply clang-format to wireplumber module --- src/modules/wireplumber.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index 2607d22d..751e885c 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -1,6 +1,7 @@ #include "modules/wireplumber.hpp" #include + #include #include @@ -450,7 +451,6 @@ auto waybar::modules::Wireplumber::update() -> void { label_.get_style_context()->remove_class("source-muted"); } - double vol_cube = pow(volume_, 3); double source_vol_cube = pow(source_volume_, 3); @@ -460,7 +460,6 @@ auto waybar::modules::Wireplumber::update() -> void { double vol_db = 20.0 * log10(volume_); double source_vol_db = 20.0 * log10(source_volume_); - // Get the state and apply state-specific format if available auto state = getState(vol); if (!state.empty()) { @@ -492,8 +491,9 @@ auto waybar::modules::Wireplumber::update() -> void { fmt::arg("icon", getIcon(vol)), fmt::arg("format_source", formatted_source), fmt::arg("source_volume", source_vol), fmt::arg("source_desc", source_name_), fmt::arg("volume_linear", volume_), fmt::arg("volume_cubic", vol_cube), - fmt::arg("volume_db", vol_db),fmt::arg("source_volume_linear", source_volume_), - fmt::arg("source_volume_cubic", source_vol_cube), fmt::arg("source_volume_db", source_vol_db)); + fmt::arg("volume_db", vol_db), fmt::arg("source_volume_linear", source_volume_), + fmt::arg("source_volume_cubic", source_vol_cube), + fmt::arg("source_volume_db", source_vol_db)); label_.set_markup(markup); if (tooltipEnabled()) { @@ -508,7 +508,8 @@ auto waybar::modules::Wireplumber::update() -> void { fmt::arg("source_volume", source_vol), fmt::arg("source_desc", source_name_), fmt::arg("volume_linear", volume_), fmt::arg("volume_cubic", vol_cube), fmt::arg("volume_db", vol_db), fmt::arg("source_volume_linear", source_volume_), - fmt::arg("source_volume_cubic", source_vol_cube), fmt::arg("source_volume_db", source_vol_db))); + fmt::arg("source_volume_cubic", source_vol_cube), + fmt::arg("source_volume_db", source_vol_db))); } else { label_.set_tooltip_markup(node_name_); } @@ -543,15 +544,12 @@ bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll* e) { if (scale == "cubic") { vol = pow(vol, 3); - } - else if (scale == "db") { + } else if (scale == "db") { vol = log10(vol) * 20.0; - } - else if (scale == "cubic_percent") { + } else if (scale == "cubic_percent") { vol = pow(vol, 3) * 100.0; } - double newVol = vol; if (dir == SCROLL_DIR::UP) { newVol = vol + step; @@ -561,11 +559,9 @@ bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll* e) { if (scale == "cubic") { newVol = cbrt(newVol); - } - else if (scale == "db") { + } else if (scale == "db") { newVol = exp10(newVol / 20.0); - } - else if (scale == "cubic_percent") { + } else if (scale == "cubic_percent") { newVol = cbrt(newVol / 100.0); } @@ -579,8 +575,10 @@ bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll* e) { } } - if (newVol < 0) newVol = 0; - else if (newVol > maxVolume) newVol = maxVolume; + if (newVol < 0) + newVol = 0; + else if (newVol > maxVolume) + newVol = maxVolume; if (newVol != volume_) { if (mixer_api_ == nullptr) return true;