From 88a1a702b4598669bc6807c4f4454283f23ef27d Mon Sep 17 00:00:00 2001 From: Evyatar Stalinsky Date: Mon, 5 Jun 2023 22:03:46 +0300 Subject: [PATCH 1/6] wireplumber: Support for scrolling --- include/modules/wireplumber.hpp | 3 ++ src/modules/wireplumber.cpp | 63 +++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/include/modules/wireplumber.hpp b/include/modules/wireplumber.hpp index 5cf462e9..81b2e68d 100644 --- a/include/modules/wireplumber.hpp +++ b/include/modules/wireplumber.hpp @@ -27,6 +27,8 @@ class Wireplumber : public ALabel { static void onMixerChanged(waybar::modules::Wireplumber* self, uint32_t id); static void onDefaultNodesApiChanged(waybar::modules::Wireplumber* self); + bool handleScroll(GdkEventScroll* e) override; + WpCore* wp_core_; GPtrArray* apis_; WpObjectManager* om_; @@ -36,6 +38,7 @@ class Wireplumber : public ALabel { uint32_t pending_plugins_; bool muted_; double volume_; + double step_; uint32_t node_id_{0}; std::string node_name_; }; diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index 0c4848ac..cfdbccc5 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -15,6 +15,7 @@ waybar::modules::Wireplumber::Wireplumber(const std::string& id, const Json::Val pending_plugins_(0), muted_(false), volume_(0.0), + step_(0.0), node_id_(0) { wp_init(WP_INIT_PIPEWIRE); wp_core_ = wp_core_new(NULL, NULL); @@ -39,6 +40,9 @@ waybar::modules::Wireplumber::Wireplumber(const std::string& id, const Json::Val activatePlugins(); dp.emit(); + + event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); + event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Wireplumber::handleScroll)); } waybar::modules::Wireplumber::~Wireplumber() { @@ -83,7 +87,6 @@ void waybar::modules::Wireplumber::updateNodeName(waybar::modules::Wireplumber* void waybar::modules::Wireplumber::updateVolume(waybar::modules::Wireplumber* self, uint32_t id) { spdlog::debug("[{}]: updating volume", self->name_); - double vol; GVariant* variant = NULL; if (!isValidNodeId(id)) { @@ -99,11 +102,11 @@ void waybar::modules::Wireplumber::updateVolume(waybar::modules::Wireplumber* se throw std::runtime_error(err); } - g_variant_lookup(variant, "volume", "d", &vol); + g_variant_lookup(variant, "volume", "d", &self->volume_); + g_variant_lookup(variant, "step", "d", &self->step_); g_variant_lookup(variant, "mute", "b", &self->muted_); g_clear_pointer(&variant, g_variant_unref); - self->volume_ = std::round(vol * 100.0F); self->dp.emit(); } @@ -280,11 +283,12 @@ auto waybar::modules::Wireplumber::update() -> void { label_.get_style_context()->remove_class("muted"); } + int vol = volume_ * 100.0; std::string markup = fmt::format(fmt::runtime(format), fmt::arg("node_name", node_name_), - fmt::arg("volume", volume_), fmt::arg("icon", getIcon(volume_))); + fmt::arg("volume", vol), fmt::arg("icon", getIcon(vol))); label_.set_markup(markup); - getState(volume_); + getState(vol); if (tooltipEnabled()) { if (tooltip_format.empty() && config_["tooltip-format"].isString()) { @@ -294,7 +298,7 @@ auto waybar::modules::Wireplumber::update() -> void { if (!tooltip_format.empty()) { label_.set_tooltip_text( fmt::format(fmt::runtime(tooltip_format), fmt::arg("node_name", node_name_), - fmt::arg("volume", volume_), fmt::arg("icon", getIcon(volume_)))); + fmt::arg("volume", vol), fmt::arg("icon", getIcon(vol)))); } else { label_.set_tooltip_text(node_name_); } @@ -303,3 +307,50 @@ auto waybar::modules::Wireplumber::update() -> void { // Call parent update ALabel::update(); } + +bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll *e) { + if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { + return AModule::handleScroll(e); + } + auto dir = AModule::getScrollDir(e); + if (dir == SCROLL_DIR::NONE) { + return true; + } + if (config_["reverse-scrolling"].asInt() == 1) { + if (dir == SCROLL_DIR::UP) { + dir = SCROLL_DIR::DOWN; + } else if (dir == SCROLL_DIR::DOWN) { + dir = SCROLL_DIR::UP; + } + } + double max_volume = 1; + double step = step_; + // isDouble returns true for integers as well, just in case + if (config_["scroll-step"].isDouble()) { + step = config_["scroll-step"].asDouble() / 100.0; + } + if (config_["max-volume"].isInt()) { + max_volume = config_["max-volume"].asInt() / 100.0; + } + + double new_vol = volume_; + if (dir == SCROLL_DIR::UP) { + if (volume_ < max_volume) { + new_vol = volume_ + step; + if (new_vol > max_volume) + new_vol = max_volume; + } + } else if (dir == SCROLL_DIR::DOWN) { + if (volume_ > 0) { + new_vol = volume_ - step; + if (new_vol < 0) + new_vol = 0; + } + } + if (new_vol != volume_) { + GVariant* variant = g_variant_new_double(new_vol); + gboolean ret; + g_signal_emit_by_name(mixer_api_, "set-volume", node_id_, variant, &ret); + } + return true; +} From 75990c2867717b5d734cb348152c5cef53fc99bd Mon Sep 17 00:00:00 2001 From: Evyatar Stalinsky Date: Mon, 5 Jun 2023 22:22:35 +0300 Subject: [PATCH 2/6] Fix linting --- src/modules/wireplumber.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index cfdbccc5..1d8d1f8d 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -296,9 +296,9 @@ auto waybar::modules::Wireplumber::update() -> void { } if (!tooltip_format.empty()) { - label_.set_tooltip_text( - fmt::format(fmt::runtime(tooltip_format), fmt::arg("node_name", node_name_), - fmt::arg("volume", vol), fmt::arg("icon", getIcon(vol)))); + label_.set_tooltip_text(fmt::format(fmt::runtime(tooltip_format), + fmt::arg("node_name", node_name_), + fmt::arg("volume", vol), fmt::arg("icon", getIcon(vol)))); } else { label_.set_tooltip_text(node_name_); } @@ -308,7 +308,7 @@ auto waybar::modules::Wireplumber::update() -> void { ALabel::update(); } -bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll *e) { +bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll* e) { if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { return AModule::handleScroll(e); } @@ -337,14 +337,12 @@ bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll *e) { if (dir == SCROLL_DIR::UP) { if (volume_ < max_volume) { new_vol = volume_ + step; - if (new_vol > max_volume) - new_vol = max_volume; + if (new_vol > max_volume) new_vol = max_volume; } } else if (dir == SCROLL_DIR::DOWN) { if (volume_ > 0) { new_vol = volume_ - step; - if (new_vol < 0) - new_vol = 0; + if (new_vol < 0) new_vol = 0; } } if (new_vol != volume_) { From d22fd3bbd1b09809cc025ca6b5b50015fba8acbd Mon Sep 17 00:00:00 2001 From: Evyatar Stalinsky Date: Tue, 6 Jun 2023 11:42:02 +0300 Subject: [PATCH 3/6] Use a minimum step as provided by wireplubmer; Default step to 1 --- include/modules/wireplumber.hpp | 2 +- src/modules/wireplumber.cpp | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/modules/wireplumber.hpp b/include/modules/wireplumber.hpp index 81b2e68d..9bbf4d46 100644 --- a/include/modules/wireplumber.hpp +++ b/include/modules/wireplumber.hpp @@ -38,7 +38,7 @@ class Wireplumber : public ALabel { uint32_t pending_plugins_; bool muted_; double volume_; - double step_; + double min_step_; uint32_t node_id_{0}; std::string node_name_; }; diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index 1d8d1f8d..cd02d42e 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -15,7 +15,7 @@ waybar::modules::Wireplumber::Wireplumber(const std::string& id, const Json::Val pending_plugins_(0), muted_(false), volume_(0.0), - step_(0.0), + min_step_(0.0), node_id_(0) { wp_init(WP_INIT_PIPEWIRE); wp_core_ = wp_core_new(NULL, NULL); @@ -103,7 +103,7 @@ void waybar::modules::Wireplumber::updateVolume(waybar::modules::Wireplumber* se } g_variant_lookup(variant, "volume", "d", &self->volume_); - g_variant_lookup(variant, "step", "d", &self->step_); + g_variant_lookup(variant, "step", "d", &self->min_step_); g_variant_lookup(variant, "mute", "b", &self->muted_); g_clear_pointer(&variant, g_variant_unref); @@ -324,15 +324,16 @@ bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll* e) { } } double max_volume = 1; - double step = step_; - // isDouble returns true for integers as well, just in case + double step = 1.0 / 100.0; if (config_["scroll-step"].isDouble()) { step = config_["scroll-step"].asDouble() / 100.0; } - if (config_["max-volume"].isInt()) { - max_volume = config_["max-volume"].asInt() / 100.0; + if (config_["max-volume"].isDouble()) { + max_volume = config_["max-volume"].asDouble() / 100.0; } + if (step < min_step_) step = min_step_; + double new_vol = volume_; if (dir == SCROLL_DIR::UP) { if (volume_ < max_volume) { From e397f568b736d169eefda3913224dfe42f148f61 Mon Sep 17 00:00:00 2001 From: Evyatar Stalinsky Date: Tue, 6 Jun 2023 11:42:31 +0300 Subject: [PATCH 4/6] Round volume instead of truncating it --- src/modules/wireplumber.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index cd02d42e..b2d9b39d 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -283,7 +283,7 @@ auto waybar::modules::Wireplumber::update() -> void { label_.get_style_context()->remove_class("muted"); } - int vol = volume_ * 100.0; + int vol = round(volume_ * 100.0); std::string markup = fmt::format(fmt::runtime(format), fmt::arg("node_name", node_name_), fmt::arg("volume", vol), fmt::arg("icon", getIcon(vol))); label_.set_markup(markup); From d61b1d54de65293033f975aa4ecd08efe870f391 Mon Sep 17 00:00:00 2001 From: Evyatar Stalinsky Date: Tue, 6 Jun 2023 11:44:17 +0300 Subject: [PATCH 5/6] Document new wireplumber module functionality --- man/waybar-wireplumber.5.scd | 76 ++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/man/waybar-wireplumber.5.scd b/man/waybar-wireplumber.5.scd index 60883774..473df926 100644 --- a/man/waybar-wireplumber.5.scd +++ b/man/waybar-wireplumber.5.scd @@ -11,59 +11,77 @@ The *wireplumber* module displays the current volume reported by WirePlumber. # CONFIGURATION *format*: ++ - typeof: string ++ - default: *{volume}%* ++ - The format, how information should be displayed. This format is used when other formats aren't specified. + typeof: string ++ + default: *{volume}%* ++ + The format, how information should be displayed. This format is used when other formats aren't specified. *format-muted*: ++ - typeof: string ++ - This format is used when the sound is muted. + typeof: string ++ + This format is used when the sound is muted. *tooltip*: ++ - typeof: bool ++ - default: *true* ++ - Option to disable tooltip on hover. + typeof: bool ++ + default: *true* ++ + Option to disable tooltip on hover. *tooltip-format*: ++ - typeof: string ++ - default: *{node_name}* ++ - The format of information displayed in the tooltip. + typeof: string ++ + default: *{node_name}* ++ + The format of information displayed in the tooltip. *rotate*: ++ - typeof: integer ++ - Positive value to rotate the text label. + typeof: integer ++ + Positive value to rotate the text label. *states*: ++ - typeof: object ++ - A number of volume states which get activated on certain volume levels. See *waybar-states(5)*. + typeof: object ++ + A number of volume states which get activated on certain volume levels. See *waybar-states(5)*. *max-length*: ++ - typeof: integer ++ - The maximum length in character the module should display. + typeof: integer ++ + The maximum length in character the module should display. *min-length*: ++ - typeof: integer ++ - The minimum length in characters the module should take up. + typeof: integer ++ + The minimum length in characters the module should take up. *align*: ++ - typeof: float ++ - The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. + typeof: float ++ + The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. + +*scroll-step*: ++ + typeof: float ++ + default: 1.0 ++ + The speed in which to change the volume when scrolling. *on-click*: ++ - typeof: string ++ - Command to execute when clicked on the module. + typeof: string ++ + Command to execute when clicked on the module. *on-click-middle*: ++ - typeof: string ++ - Command to execute when middle-clicked on the module using mousewheel. + typeof: string ++ + Command to execute when middle-clicked on the module using mousewheel. *on-click-right*: ++ - typeof: string ++ - Command to execute when you right clicked on the module. + typeof: string ++ + Command to execute when you right clicked on the module. *on-update*: ++ - typeof: string ++ - Command to execute when the module is updated. + typeof: string ++ + Command to execute when the module is updated. + +*on-scroll-up*: ++ + typeof: string ++ + Command to execute when scrolling up on the module. This replaces the default behaviour of volume control. + +*on-scroll-down*: ++ + typeof: string ++ + Command to execute when scrolling down on the module. This replaces the default behaviour of volume control. + +*max-volume*: ++ + typeof: float ++ + default: 100 ++ + The maximum volume that can be set, in percentage. # FORMAT REPLACEMENTS From e96610e31a7f1b788740a32f61db1b184027db0e Mon Sep 17 00:00:00 2001 From: Evyatar Stalinsky Date: Tue, 6 Jun 2023 12:01:25 +0300 Subject: [PATCH 6/6] Use consistent tabbing --- man/waybar-pulseaudio.5.scd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/man/waybar-pulseaudio.5.scd b/man/waybar-pulseaudio.5.scd index b941c22c..655fbc4d 100644 --- a/man/waybar-pulseaudio.5.scd +++ b/man/waybar-pulseaudio.5.scd @@ -51,12 +51,12 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu The maximum length in character the module should display. *min-length*: ++ - typeof: integer ++ - The minimum length in characters the module should take up. + typeof: integer ++ + The minimum length in characters the module should take up. *align*: ++ - typeof: float ++ - The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. + typeof: float ++ + The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. *scroll-step*: ++ typeof: float ++