From 7e2d8ab2a37302d09727b29d600f7768d1a2efb4 Mon Sep 17 00:00:00 2001 From: "Lars-Ragnar A. Haugen" Date: Wed, 15 May 2024 20:07:28 +0200 Subject: [PATCH 01/35] fix(#3239): hide cursor type change behind config flag also, statically configure the cursor type --- man/waybar-styles.5.scd.in | 32 ++++++++++++++++++++++++++++++++ src/AModule.cpp | 37 +++++++++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/man/waybar-styles.5.scd.in b/man/waybar-styles.5.scd.in index 0af393ef..c1bc25e3 100644 --- a/man/waybar-styles.5.scd.in +++ b/man/waybar-styles.5.scd.in @@ -39,6 +39,38 @@ You can apply special styling to any module for when the cursor hovers it. } ``` +## Setting cursor style + +Most, if not all, module types support setting the `cursor` option. This is +configured in your `config.jsonc`. If set to `true`, when hovering the module a +"pointer"(as commonly known from web CSS styling `cursor: pointer`) style cursor +will be shown. +There are more cursor types to choose from by setting the `cursor` option to +a number, see Gdk3 official docs for all possible cursor types: +https://docs.gtk.org/gdk3/enum.CursorType.html. +However, note that not all cursor options listed may be available on +your system. If you attempt to use a cursor which is not available, the +application will crash. + +Example of enabling pointer(`Gdk::Hand2`) cursor type on a custom module: + +``` +"custom/my-custom-module": { + ... + "cursor": true, +} +``` + +Example of setting cursor type to `Gdk::Boat`(according to +https://docs.gtk.org/gdk3/enum.CursorType.html#boat): + +``` +"custom/my-custom-module": { + ... + "cursor": 8, +} +``` + # SEE ALSO - *waybar(5)* diff --git a/src/AModule.cpp b/src/AModule.cpp index c40e3a56..887b0de0 100644 --- a/src/AModule.cpp +++ b/src/AModule.cpp @@ -1,9 +1,13 @@ #include "AModule.hpp" #include +#include #include +#include "gdk/gdk.h" +#include "gdkmm/cursor.h" + namespace waybar { AModule::AModule(const Json::Value& config, const std::string& name, const std::string& id, @@ -64,6 +68,16 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std:: event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll)); } + + if (config_.isMember("cursor")) { + if (config_["cursor"].isBool() && config_["cursor"].asBool()) { + setCursor(Gdk::HAND2); + } else if (config_["cursor"].isInt()) { + setCursor(Gdk::CursorType(config_["cursor"].asInt())); + } else { + spdlog::warn("unknown cursor option configured on module {}", name_); + } + } } AModule::~AModule() { @@ -91,19 +105,26 @@ auto AModule::doAction(const std::string& name) -> void { } void AModule::setCursor(Gdk::CursorType const& c) { - auto cursor = Gdk::Cursor::create(c); auto gdk_window = event_box_.get_window(); - gdk_window->set_cursor(cursor); + if (gdk_window) { + auto cursor = Gdk::Cursor::create(c); + gdk_window->set_cursor(cursor); + } else { + // window may not be accessible yet, in this case, + // schedule another call for setting the cursor in 1 sec + Glib::signal_timeout().connect_seconds( + [this, c]() { + setCursor(c); + return false; + }, + 1); + } } bool AModule::handleMouseEnter(GdkEventCrossing* const& e) { if (auto* module = event_box_.get_child(); module != nullptr) { module->set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); } - - if (hasUserEvents_) { - setCursor(Gdk::HAND2); - } return false; } @@ -111,10 +132,6 @@ bool AModule::handleMouseLeave(GdkEventCrossing* const& e) { if (auto* module = event_box_.get_child(); module != nullptr) { module->unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); } - - if (hasUserEvents_) { - setCursor(Gdk::ARROW); - } return false; } From f78f29ee66f5d67579791380098759768e3682e8 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Tue, 2 Jul 2024 18:13:53 -0500 Subject: [PATCH 02/35] AModule: retain existing default behavior when unconfigured --- man/waybar-styles.5.scd.in | 10 ++++++---- src/AModule.cpp | 13 +++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/man/waybar-styles.5.scd.in b/man/waybar-styles.5.scd.in index c1bc25e3..b11e15bd 100644 --- a/man/waybar-styles.5.scd.in +++ b/man/waybar-styles.5.scd.in @@ -42,9 +42,11 @@ You can apply special styling to any module for when the cursor hovers it. ## Setting cursor style Most, if not all, module types support setting the `cursor` option. This is -configured in your `config.jsonc`. If set to `true`, when hovering the module a +configured in your `config.jsonc`. If set to `false`, when hovering the module a "pointer"(as commonly known from web CSS styling `cursor: pointer`) style cursor -will be shown. +will not be shown. Default behavior is to indicate an interaction event is +available. + There are more cursor types to choose from by setting the `cursor` option to a number, see Gdk3 official docs for all possible cursor types: https://docs.gtk.org/gdk3/enum.CursorType.html. @@ -52,12 +54,12 @@ However, note that not all cursor options listed may be available on your system. If you attempt to use a cursor which is not available, the application will crash. -Example of enabling pointer(`Gdk::Hand2`) cursor type on a custom module: +Example of disabling pointer(`Gdk::Hand2`) cursor type on a custom module: ``` "custom/my-custom-module": { ... - "cursor": true, + "cursor": false, } ``` diff --git a/src/AModule.cpp b/src/AModule.cpp index 887b0de0..c180b480 100644 --- a/src/AModule.cpp +++ b/src/AModule.cpp @@ -69,6 +69,7 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std:: event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll)); } + // Respect user configuration of cursor if (config_.isMember("cursor")) { if (config_["cursor"].isBool() && config_["cursor"].asBool()) { setCursor(Gdk::HAND2); @@ -125,6 +126,12 @@ bool AModule::handleMouseEnter(GdkEventCrossing* const& e) { if (auto* module = event_box_.get_child(); module != nullptr) { module->set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); } + + // Default behavior indicating event availability + if (hasUserEvents_ && !config_.isMember("cursor")) { + setCursor(Gdk::HAND2); + } + return false; } @@ -132,6 +139,12 @@ bool AModule::handleMouseLeave(GdkEventCrossing* const& e) { if (auto* module = event_box_.get_child(); module != nullptr) { module->unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); } + + // Default behavior indicating event availability + if (hasUserEvents_ && !config_.isMember("cursor")) { + setCursor(Gdk::ARROW); + } + return false; } From 23274a9d570f3821c20dcc004da5e6e0afa122bd Mon Sep 17 00:00:00 2001 From: Lauri Niskanen Date: Sat, 6 Jul 2024 01:15:16 +0300 Subject: [PATCH 03/35] pulseaudio: Consider ignored sinks never running If the current sink happens to be ignored it is never considered running so it will be replaced with another sink. --- src/util/audio_backend.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/audio_backend.cpp b/src/util/audio_backend.cpp index e634784b..3d90b6d5 100644 --- a/src/util/audio_backend.cpp +++ b/src/util/audio_backend.cpp @@ -144,6 +144,12 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i if (!backend->ignored_sinks_.empty()) { for (const auto &ignored_sink : backend->ignored_sinks_) { if (ignored_sink == i->description) { + if (i->name == backend->current_sink_name_) { + // If the current sink happens to be ignored it is never considered running + // so it will be replaced with another sink. + backend->current_sink_running_ = false; + } + return; } } From e2e5d4d447fceca6d3185ddd4b7171a751412920 Mon Sep 17 00:00:00 2001 From: "Rene D. Obermueller" Date: Sun, 7 Jul 2024 22:08:45 +0200 Subject: [PATCH 04/35] feat/issue 3256: Toggle drawer state --- include/group.hpp | 4 ++++ man/waybar.5.scd.in | 5 +++++ src/group.cpp | 31 ++++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/include/group.hpp b/include/group.hpp index 564d2eb5..b10402c6 100644 --- a/include/group.hpp +++ b/include/group.hpp @@ -25,9 +25,13 @@ class Group : public AModule { Gtk::Revealer revealer; bool is_first_widget = true; bool is_drawer = false; + bool click_to_reveal = false; std::string add_class_to_drawer_children; bool handleMouseEnter(GdkEventCrossing *const &ev) override; bool handleMouseLeave(GdkEventCrossing *const &ev) override; + bool handleToggle(GdkEventButton *const &ev) override; + void show_group(); + void hide_group(); }; } // namespace waybar diff --git a/man/waybar.5.scd.in b/man/waybar.5.scd.in index 53613e4a..db546e17 100644 --- a/man/waybar.5.scd.in +++ b/man/waybar.5.scd.in @@ -278,6 +278,11 @@ A group may hide all but one element, showing them only on mouse hover. In order default: "hidden" ++ Defines the CSS class to be applied to the hidden elements. +*click-to-reveal*: ++ + typeof: bool ++ + default: false ++ + Whether left click should reveal the content rather than mouse over. Note that grouped modules may still process their own on-click events. + *transition-left-to-right*: ++ typeof: bool ++ default: true ++ diff --git a/src/group.cpp b/src/group.cpp index c77f2d31..deeecc75 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -62,6 +62,7 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value& const bool left_to_right = (drawer_config["transition-left-to-right"].isBool() ? drawer_config["transition-left-to-right"].asBool() : true); + click_to_reveal = drawer_config["click-to-reveal"].asBool(); auto transition_type = getPreferredTransitionType(vertical); @@ -83,18 +84,42 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value& event_box_.add(box); } -bool Group::handleMouseEnter(GdkEventCrossing* const& e) { +void Group::show_group() { box.set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); revealer.set_reveal_child(true); +} + +void Group::hide_group() { + box.unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); + revealer.set_reveal_child(false); +} + +bool Group::handleMouseEnter(GdkEventCrossing* const& e) { + if (!click_to_reveal) { + show_group(); + } return false; } bool Group::handleMouseLeave(GdkEventCrossing* const& e) { - box.unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); - revealer.set_reveal_child(false); + if (!click_to_reveal) { + hide_group(); + } return false; } +bool Group::handleToggle(GdkEventButton* const& e) { + if (!click_to_reveal || e->button != 1) { + return false; + } + if (box.get_state_flags() & Gtk::StateFlags::STATE_FLAG_PRELIGHT) { + hide_group(); + } else { + show_group(); + } + return true; +} + auto Group::update() -> void { // noop } From e117bd7cb6da994fbe5bd3cb69ccecdd86664d09 Mon Sep 17 00:00:00 2001 From: Siddhant Kameswar <115331356+grimsteel@users.noreply.github.com> Date: Fri, 12 Jul 2024 20:46:26 -0500 Subject: [PATCH 05/35] network: add bssid format replacement --- include/modules/network.hpp | 2 ++ man/waybar-network.5.scd | 2 ++ src/modules/network.cpp | 23 ++++++++++++++++++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/modules/network.hpp b/include/modules/network.hpp index 47701b4e..4a84b02f 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -40,6 +40,7 @@ class Network : public ALabel { void parseEssid(struct nlattr**); void parseSignal(struct nlattr**); void parseFreq(struct nlattr**); + void parseBssid(struct nlattr**); bool associatedOrJoined(struct nlattr**); bool checkInterface(std::string name); auto getInfo() -> void; @@ -69,6 +70,7 @@ class Network : public ALabel { std::string state_; std::string essid_; + std::string bssid_; bool carrier_; std::string ifname_; std::string ipaddr_; diff --git a/man/waybar-network.5.scd b/man/waybar-network.5.scd index cc0b470b..bd546916 100644 --- a/man/waybar-network.5.scd +++ b/man/waybar-network.5.scd @@ -156,6 +156,8 @@ Addressed by *network* *{essid}*: Name (SSID) of the wireless network. +*{bssid}*: MAC address (BSSID) of the wireless access point. + *{signalStrength}*: Signal strength of the wireless network. *{signaldBm}*: Signal strength of the wireless network in dBm. diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 654afbe8..0e49177a 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -332,8 +332,8 @@ auto waybar::modules::Network::update() -> void { getState(signal_strength_); auto text = fmt::format( - fmt::runtime(format_), fmt::arg("essid", essid_), fmt::arg("signaldBm", signal_strength_dbm_), - fmt::arg("signalStrength", signal_strength_), + fmt::runtime(format_), fmt::arg("essid", essid_), fmt::arg("bssid", bssid_), + fmt::arg("signaldBm", signal_strength_dbm_), fmt::arg("signalStrength", signal_strength_), fmt::arg("signalStrengthApp", signal_strength_app_), fmt::arg("ifname", ifname_), fmt::arg("netmask", netmask_), fmt::arg("ipaddr", ipaddr_), fmt::arg("gwaddr", gwaddr_), fmt::arg("cidr", cidr_), fmt::arg("frequency", fmt::format("{:.1f}", frequency_)), @@ -364,7 +364,7 @@ auto waybar::modules::Network::update() -> void { } if (!tooltip_format.empty()) { auto tooltip_text = fmt::format( - fmt::runtime(tooltip_format), fmt::arg("essid", essid_), + fmt::runtime(tooltip_format), fmt::arg("essid", essid_), fmt::arg("bssid", bssid_), fmt::arg("signaldBm", signal_strength_dbm_), fmt::arg("signalStrength", signal_strength_), fmt::arg("signalStrengthApp", signal_strength_app_), fmt::arg("ifname", ifname_), fmt::arg("netmask", netmask_), fmt::arg("ipaddr", ipaddr_), fmt::arg("gwaddr", gwaddr_), @@ -407,6 +407,7 @@ void waybar::modules::Network::clearIface() { ifid_ = -1; ifname_.clear(); essid_.clear(); + bssid_.clear(); ipaddr_.clear(); gwaddr_.clear(); netmask_.clear(); @@ -481,6 +482,7 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { } else { // clear state related to WiFi connection net->essid_.clear(); + net->bssid_.clear(); net->signal_strength_dbm_ = 0; net->signal_strength_ = 0; net->signal_strength_app_.clear(); @@ -772,6 +774,7 @@ int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) { net->parseEssid(bss); net->parseSignal(bss); net->parseFreq(bss); + net->parseBssid(bss); return NL_OK; } @@ -837,6 +840,20 @@ void waybar::modules::Network::parseFreq(struct nlattr **bss) { } } +void waybar::modules::Network::parseBssid(struct nlattr **bss) { + if (bss[NL80211_BSS_BSSID] != nullptr) { + auto bssid = static_cast(nla_data(bss[NL80211_BSS_BSSID])); + auto bssid_len = nla_len(bss[NL80211_BSS_BSSID]); + if (bssid_len == 6) { + bssid_ = std::format( + "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", + bssid[0], bssid[1], bssid[2], + bssid[3], bssid[4], bssid[5] + ); + } + } +} + bool waybar::modules::Network::associatedOrJoined(struct nlattr **bss) { if (bss[NL80211_BSS_STATUS] == nullptr) { return false; From 0a78da0315a96e31365f49076021356cd278e5fa Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 15 Jul 2024 08:55:30 -0500 Subject: [PATCH 06/35] flake.lock: update --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 3f0deffe..0d945dbe 100644 --- a/flake.lock +++ b/flake.lock @@ -18,11 +18,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1719506693, - "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=", + "lastModified": 1720957393, + "narHash": "sha256-oedh2RwpjEa+TNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a", + "rev": "693bc46d169f5af9c992095736e82c3488bf7dbb", "type": "github" }, "original": { From b41fcdedff884f25e96011278dcdb38788a291fe Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 15 Jul 2024 08:44:26 -0500 Subject: [PATCH 07/35] hyprland/window: fix crash when no return from socket Gracefully handle lack of response from the IPC. If socket isn't available, we already log the IPC isn't running. We dont need to crash program just because we couldn't get responses. We can just return an empty object. --- src/modules/hyprland/window.cpp | 132 +++++++++++++++++--------------- 1 file changed, 71 insertions(+), 61 deletions(-) diff --git a/src/modules/hyprland/window.cpp b/src/modules/hyprland/window.cpp index ec151a7b..b5ed8f02 100644 --- a/src/modules/hyprland/window.cpp +++ b/src/modules/hyprland/window.cpp @@ -92,30 +92,39 @@ auto Window::update() -> void { auto Window::getActiveWorkspace() -> Workspace { const auto workspace = gIPC->getSocket1JsonReply("activeworkspace"); - assert(workspace.isObject()); - return Workspace::parse(workspace); + + if (workspace.isObject()) { + return Workspace::parse(workspace); + } + + return {}; } auto Window::getActiveWorkspace(const std::string& monitorName) -> Workspace { const auto monitors = gIPC->getSocket1JsonReply("monitors"); - assert(monitors.isArray()); - auto monitor = std::find_if(monitors.begin(), monitors.end(), - [&](Json::Value monitor) { return monitor["name"] == monitorName; }); - if (monitor == std::end(monitors)) { - spdlog::warn("Monitor not found: {}", monitorName); - return Workspace{-1, 0, "", ""}; - } - const int id = (*monitor)["activeWorkspace"]["id"].asInt(); + if (monitors.isArray()) { + auto monitor = std::find_if(monitors.begin(), monitors.end(), [&](Json::Value monitor) { + return monitor["name"] == monitorName; + }); + if (monitor == std::end(monitors)) { + spdlog::warn("Monitor not found: {}", monitorName); + return Workspace{-1, 0, "", ""}; + } + const int id = (*monitor)["activeWorkspace"]["id"].asInt(); - const auto workspaces = gIPC->getSocket1JsonReply("workspaces"); - assert(workspaces.isArray()); - auto workspace = std::find_if(workspaces.begin(), workspaces.end(), - [&](Json::Value workspace) { return workspace["id"] == id; }); - if (workspace == std::end(workspaces)) { - spdlog::warn("No workspace with id {}", id); - return Workspace{-1, 0, "", ""}; - } - return Workspace::parse(*workspace); + const auto workspaces = gIPC->getSocket1JsonReply("workspaces"); + if (workspaces.isArray()) { + auto workspace = std::find_if(workspaces.begin(), workspaces.end(), + [&](Json::Value workspace) { return workspace["id"] == id; }); + if (workspace == std::end(workspaces)) { + spdlog::warn("No workspace with id {}", id); + return Workspace{-1, 0, "", ""}; + } + return Workspace::parse(*workspace); + }; + }; + + return {}; } auto Window::Workspace::parse(const Json::Value& value) -> Window::Workspace { @@ -146,53 +155,54 @@ void Window::queryActiveWorkspace() { focused_ = true; if (workspace_.windows > 0) { const auto clients = gIPC->getSocket1JsonReply("clients"); - assert(clients.isArray()); - auto activeWindow = std::find_if(clients.begin(), clients.end(), [&](Json::Value window) { - return window["address"] == workspace_.last_window; - }); + if (clients.isArray()) { + auto activeWindow = std::find_if(clients.begin(), clients.end(), [&](Json::Value window) { + return window["address"] == workspace_.last_window; + }); - if (activeWindow == std::end(clients)) { - focused_ = false; - return; - } + if (activeWindow == std::end(clients)) { + focused_ = false; + return; + } - windowData_ = WindowData::parse(*activeWindow); - updateAppIconName(windowData_.class_name, windowData_.initial_class_name); - std::vector workspaceWindows; - std::copy_if(clients.begin(), clients.end(), std::back_inserter(workspaceWindows), - [&](Json::Value window) { - return window["workspace"]["id"] == workspace_.id && window["mapped"].asBool(); - }); - swallowing_ = - std::any_of(workspaceWindows.begin(), workspaceWindows.end(), [&](Json::Value window) { - return !window["swallowing"].isNull() && window["swallowing"].asString() != "0x0"; - }); - std::vector visibleWindows; - std::copy_if(workspaceWindows.begin(), workspaceWindows.end(), - std::back_inserter(visibleWindows), - [&](Json::Value window) { return !window["hidden"].asBool(); }); - solo_ = 1 == std::count_if(visibleWindows.begin(), visibleWindows.end(), - [&](Json::Value window) { return !window["floating"].asBool(); }); - allFloating_ = std::all_of(visibleWindows.begin(), visibleWindows.end(), - [&](Json::Value window) { return window["floating"].asBool(); }); - fullscreen_ = windowData_.fullscreen; + windowData_ = WindowData::parse(*activeWindow); + updateAppIconName(windowData_.class_name, windowData_.initial_class_name); + std::vector workspaceWindows; + std::copy_if(clients.begin(), clients.end(), std::back_inserter(workspaceWindows), + [&](Json::Value window) { + return window["workspace"]["id"] == workspace_.id && window["mapped"].asBool(); + }); + swallowing_ = + std::any_of(workspaceWindows.begin(), workspaceWindows.end(), [&](Json::Value window) { + return !window["swallowing"].isNull() && window["swallowing"].asString() != "0x0"; + }); + std::vector visibleWindows; + std::copy_if(workspaceWindows.begin(), workspaceWindows.end(), + std::back_inserter(visibleWindows), + [&](Json::Value window) { return !window["hidden"].asBool(); }); + solo_ = 1 == std::count_if(visibleWindows.begin(), visibleWindows.end(), + [&](Json::Value window) { return !window["floating"].asBool(); }); + allFloating_ = std::all_of(visibleWindows.begin(), visibleWindows.end(), + [&](Json::Value window) { return window["floating"].asBool(); }); + fullscreen_ = windowData_.fullscreen; - // Fullscreen windows look like they are solo - if (fullscreen_) { - solo_ = true; - } + // Fullscreen windows look like they are solo + if (fullscreen_) { + solo_ = true; + } - // Grouped windows have a tab bar and therefore don't look fullscreen or solo - if (windowData_.grouped) { - fullscreen_ = false; - solo_ = false; - } + // Grouped windows have a tab bar and therefore don't look fullscreen or solo + if (windowData_.grouped) { + fullscreen_ = false; + solo_ = false; + } - if (solo_) { - soloClass_ = windowData_.class_name; - } else { - soloClass_ = ""; - } + if (solo_) { + soloClass_ = windowData_.class_name; + } else { + soloClass_ = ""; + } + }; } else { focused_ = false; windowData_ = WindowData{}; From b19890c0b1e9de87bb5ada10e2d6fa3bf5ad518b Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 15 Jul 2024 08:48:01 -0500 Subject: [PATCH 08/35] network: clang-format --- src/modules/network.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 0e49177a..e84b0d90 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -845,11 +845,8 @@ void waybar::modules::Network::parseBssid(struct nlattr **bss) { auto bssid = static_cast(nla_data(bss[NL80211_BSS_BSSID])); auto bssid_len = nla_len(bss[NL80211_BSS_BSSID]); if (bssid_len == 6) { - bssid_ = std::format( - "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", - bssid[0], bssid[1], bssid[2], - bssid[3], bssid[4], bssid[5] - ); + bssid_ = std::format("{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", bssid[0], bssid[1], bssid[2], bssid[3], + bssid[4], bssid[5]); } } } From 47d7324a19647996dda96aaae1a7ee3956900440 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 15 Jul 2024 08:48:08 -0500 Subject: [PATCH 09/35] client: clang-format --- src/client.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client.cpp b/src/client.cpp index cac1ffe8..63a9276a 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -123,7 +123,8 @@ void waybar::Client::handleMonitorAdded(Glib::RefPtr monitor) { } void waybar::Client::handleMonitorRemoved(Glib::RefPtr monitor) { - spdlog::debug("Output removed: {} {}", monitor->get_manufacturer().c_str(), monitor->get_model().c_str()); + spdlog::debug("Output removed: {} {}", monitor->get_manufacturer().c_str(), + monitor->get_model().c_str()); /* This event can be triggered from wl_display_roundtrip called by GTK or our code. * Defer destruction of bars for the output to the next iteration of the event loop to avoid * deleting objects referenced by currently executed code. From 895c870d02758b8698cdce859fc4c359d255c5a9 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 15 Jul 2024 09:44:39 -0500 Subject: [PATCH 10/35] network: use fmt for format Fixes the gentoo build --- src/modules/network.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index e84b0d90..0bbea631 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -845,7 +845,7 @@ void waybar::modules::Network::parseBssid(struct nlattr **bss) { auto bssid = static_cast(nla_data(bss[NL80211_BSS_BSSID])); auto bssid_len = nla_len(bss[NL80211_BSS_BSSID]); if (bssid_len == 6) { - bssid_ = std::format("{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", bssid[0], bssid[1], bssid[2], bssid[3], + bssid_ = fmt::format("{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); } } From b71dfce1f7eefcd6c0dc99f162899b053d7fe082 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 16 Jul 2024 06:39:45 +0800 Subject: [PATCH 11/35] Fix build with fmt11 Since fmt 11.0.0, formatter:format() is required to be const. Mark all of the specializations as const to be compatible with fmt 11. This change is implemented in the same spirit of 7725f6ed5a. Signed-off-by: Kefu Chai --- include/util/format.hpp | 2 +- src/modules/sni/item.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/util/format.hpp b/include/util/format.hpp index a5630cf4..cf8d706b 100644 --- a/include/util/format.hpp +++ b/include/util/format.hpp @@ -92,7 +92,7 @@ struct formatter { template <> struct formatter : formatter { template - auto format(const Glib::ustring& value, FormatContext& ctx) { + auto format(const Glib::ustring& value, FormatContext& ctx) const { return formatter::format(static_cast(value), ctx); } }; diff --git a/src/modules/sni/item.cpp b/src/modules/sni/item.cpp index b5c0dd85..6c4ec8c0 100644 --- a/src/modules/sni/item.cpp +++ b/src/modules/sni/item.cpp @@ -14,14 +14,14 @@ template <> struct fmt::formatter : formatter { - bool is_printable(const Glib::VariantBase& value) { + bool is_printable(const Glib::VariantBase& value) const { auto type = value.get_type_string(); /* Print only primitive (single character excluding 'v') and short complex types */ return (type.length() == 1 && islower(type[0]) && type[0] != 'v') || value.get_size() <= 32; } template - auto format(const Glib::VariantBase& value, FormatContext& ctx) { + auto format(const Glib::VariantBase& value, FormatContext& ctx) const { if (is_printable(value)) { return formatter::format(static_cast(value.print()), ctx); } else { From b65ca334a8c9218a9ee1f42c411ef81be5014f38 Mon Sep 17 00:00:00 2001 From: yangyingchao Date: Tue, 16 Jul 2024 09:07:39 +0800 Subject: [PATCH 12/35] fix #3442 --- src/modules/sni/watcher.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/modules/sni/watcher.cpp b/src/modules/sni/watcher.cpp index 8c035ae1..324bd9f5 100644 --- a/src/modules/sni/watcher.cpp +++ b/src/modules/sni/watcher.cpp @@ -67,10 +67,9 @@ gboolean Watcher::handleRegisterHost(Watcher* obj, GDBusMethodInvocation* invoca } auto watch = gfWatchFind(obj->hosts_, bus_name, object_path); if (watch != nullptr) { - g_dbus_method_invocation_return_error( - invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, - "Status Notifier Host with bus name '%s' and object path '%s' is already registered", - bus_name, object_path); + g_warning("Status Notifier Host with bus name '%s' and object path '%s' is already registered", + bus_name, object_path); + sn_watcher_complete_register_item(obj->watcher_, invocation); return TRUE; } watch = gfWatchNew(GF_WATCH_TYPE_HOST, service, bus_name, object_path, obj); From 17132b250d4a61e0366742fb9d86210762d5a5a2 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Tue, 16 Jul 2024 18:24:40 -0500 Subject: [PATCH 13/35] sway/workspaces: remove deprecated field Was deprecated a long time ago, we removed the Hyprland version. Removing this, as well. --- src/modules/sway/workspaces.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 2adde69c..f5851737 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -125,18 +125,10 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { std::copy(output["floating_nodes"].begin(), output["floating_nodes"].end(), std::back_inserter(workspaces_)); } - if (config_["persistent_workspaces"].isObject()) { - spdlog::warn( - "persistent_workspaces is deprecated. Please change config to use " - "persistent-workspaces."); - } // adding persistent workspaces (as per the config file) - if (config_["persistent-workspaces"].isObject() || - config_["persistent_workspaces"].isObject()) { - const Json::Value &p_workspaces = config_["persistent-workspaces"].isObject() - ? config_["persistent-workspaces"] - : config_["persistent_workspaces"]; + if (config_["persistent-workspaces"].isObject()) { + const Json::Value &p_workspaces = config_["persistent-workspaces"]; const std::vector p_workspaces_names = p_workspaces.getMemberNames(); for (const std::string &p_w_name : p_workspaces_names) { From 9c40137d05cfac4f41a49e354dd77d008a96386e Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Tue, 16 Jul 2024 18:26:28 -0500 Subject: [PATCH 14/35] sway/workspaces: clang-tidy --- include/modules/sway/workspaces.hpp | 8 ++++---- src/modules/sway/workspaces.cpp | 16 +++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/include/modules/sway/workspaces.hpp b/include/modules/sway/workspaces.hpp index 4258252a..97f4e950 100644 --- a/include/modules/sway/workspaces.hpp +++ b/include/modules/sway/workspaces.hpp @@ -19,7 +19,7 @@ namespace waybar::modules::sway { class Workspaces : public AModule, public sigc::trackable { public: Workspaces(const std::string&, const waybar::Bar&, const Json::Value&); - virtual ~Workspaces() = default; + ~Workspaces() override = default; auto update() -> void override; private: @@ -38,10 +38,10 @@ class Workspaces : public AModule, public sigc::trackable { Gtk::Button& addButton(const Json::Value&); void onButtonReady(const Json::Value&, Gtk::Button&); std::string getIcon(const std::string&, const Json::Value&); - const std::string getCycleWorkspace(std::vector::iterator, bool prev) const; + std::string getCycleWorkspace(std::vector::iterator, bool prev) const; uint16_t getWorkspaceIndex(const std::string& name) const; - std::string trimWorkspaceName(std::string); - bool handleScroll(GdkEventScroll*) override; + static std::string trimWorkspaceName(std::string); + bool handleScroll(GdkEventScroll* /*unused*/) override; const Bar& bar_; std::vector workspaces_; diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index f5851737..0ca41d1c 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -11,15 +11,14 @@ namespace waybar::modules::sway { // Helper function to assign a number to a workspace, just like sway. In fact // this is taken quite verbatim from `sway/ipc-json.c`. int Workspaces::convertWorkspaceNameToNum(std::string name) { - if (isdigit(name[0])) { + if (isdigit(name[0]) != 0) { errno = 0; - char *endptr = NULL; + char *endptr = nullptr; long long parsed_num = strtoll(name.c_str(), &endptr, 10); if (errno != 0 || parsed_num > INT32_MAX || parsed_num < 0 || endptr == name.c_str()) { return -1; - } else { - return (int)parsed_num; } + return (int)parsed_num; } return -1; } @@ -47,7 +46,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value bar_(bar), box_(bar.orientation, 0) { if (config["format-icons"]["high-priority-named"].isArray()) { - for (auto &it : config["format-icons"]["high-priority-named"]) { + for (const auto &it : config["format-icons"]["high-priority-named"]) { high_priority_named_.push_back(it.asString()); } } @@ -70,7 +69,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value m_windowRewriteRules = waybar::util::RegexCollection( windowRewrite, m_windowRewriteDefault, - [this](std::string &window_rule) { return windowRewritePriorityFunction(window_rule); }); + [](std::string &window_rule) { return windowRewritePriorityFunction(window_rule); }); ipc_.subscribe(R"(["workspace"])"); ipc_.subscribe(R"(["window"])"); ipc_.signal_event.connect(sigc::mem_fun(*this, &Workspaces::onEvent)); @@ -414,7 +413,7 @@ std::string Workspaces::getIcon(const std::string &name, const Json::Value &node } bool Workspaces::handleScroll(GdkEventScroll *e) { - if (gdk_event_get_pointer_emulated((GdkEvent *)e)) { + if (gdk_event_get_pointer_emulated((GdkEvent *)e) != 0) { /** * Ignore emulated scroll events on window */ @@ -464,8 +463,7 @@ bool Workspaces::handleScroll(GdkEventScroll *e) { return true; } -const std::string Workspaces::getCycleWorkspace(std::vector::iterator it, - bool prev) const { +std::string Workspaces::getCycleWorkspace(std::vector::iterator it, bool prev) const { if (prev && it == workspaces_.begin() && !config_["disable-scroll-wraparound"].asBool()) { return (*(--workspaces_.end()))["name"].asString(); } From 4295faa7c4b23b7f6e86669d1fe8c93562e10241 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Tue, 16 Jul 2024 14:53:54 -0500 Subject: [PATCH 15/35] hyprland/backend: throw runtime_error instead of log Allows us to disable modules entirely when socket connection isn't working. This is similar to how sway handles their socket connections disabling modules. This supports a single waybar config for multiple IPCs. --- src/modules/hyprland/backend.cpp | 16 ++++++---------- test/hyprland/backend.cpp | 6 ++---- test/hyprland/fixtures/IPCTestFixture.hpp | 3 +++ 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/modules/hyprland/backend.cpp b/src/modules/hyprland/backend.cpp index 8ec6edda..60453dcb 100644 --- a/src/modules/hyprland/backend.cpp +++ b/src/modules/hyprland/backend.cpp @@ -153,8 +153,7 @@ std::string IPC::getSocket1Reply(const std::string& rq) { const auto serverSocket = socket(AF_UNIX, SOCK_STREAM, 0); if (serverSocket < 0) { - spdlog::error("Hyprland IPC: Couldn't open a socket (1)"); - return ""; + throw std::runtime_error("Hyprland IPC: Couldn't open a socket (1)"); } memset(&aiHints, 0, sizeof(struct addrinfo)); @@ -162,16 +161,15 @@ std::string IPC::getSocket1Reply(const std::string& rq) { aiHints.ai_socktype = SOCK_STREAM; if (getaddrinfo("localhost", nullptr, &aiHints, &aiRes) != 0) { - spdlog::error("Hyprland IPC: Couldn't get host (2)"); - return ""; + throw std::runtime_error("Hyprland IPC: Couldn't get host (2)"); } // get the instance signature auto* instanceSig = getenv("HYPRLAND_INSTANCE_SIGNATURE"); if (instanceSig == nullptr) { - spdlog::error("Hyprland IPC: HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)"); - return ""; + throw std::runtime_error( + "Hyprland IPC: HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)"); } sockaddr_un serverAddress = {0}; @@ -182,14 +180,12 @@ std::string IPC::getSocket1Reply(const std::string& rq) { // Use snprintf to copy the socketPath string into serverAddress.sun_path if (snprintf(serverAddress.sun_path, sizeof(serverAddress.sun_path), "%s", socketPath.c_str()) < 0) { - spdlog::error("Hyprland IPC: Couldn't copy socket path (6)"); - return ""; + throw std::runtime_error("Hyprland IPC: Couldn't copy socket path (6)"); } if (connect(serverSocket, reinterpret_cast(&serverAddress), sizeof(serverAddress)) < 0) { - spdlog::error("Hyprland IPC: Couldn't connect to " + socketPath + ". (3)"); - return ""; + throw std::runtime_error("Hyprland IPC: Couldn't connect to " + socketPath + ". (3)"); } auto sizeWritten = write(serverSocket, rq.c_str(), rq.length()); diff --git a/test/hyprland/backend.cpp b/test/hyprland/backend.cpp index dcae0509..b83b839c 100644 --- a/test/hyprland/backend.cpp +++ b/test/hyprland/backend.cpp @@ -52,10 +52,8 @@ TEST_CASE_METHOD(IPCTestFixture, "XDGRuntimeDirExistsNoHyprDir", "[getSocketFold REQUIRE(actualPath == expectedPath); } -TEST_CASE_METHOD(IPCMock, "getSocket1JsonReply handles empty response", "[getSocket1JsonReply]") { +TEST_CASE_METHOD(IPCTestFixture, "getSocket1Reply throws on no socket", "[getSocket1Reply]") { std::string request = "test_request"; - Json::Value jsonResponse = getSocket1JsonReply(request); - - REQUIRE(jsonResponse.isNull()); + CHECK_THROWS(getSocket1Reply(request)); } diff --git a/test/hyprland/fixtures/IPCTestFixture.hpp b/test/hyprland/fixtures/IPCTestFixture.hpp index f6fa335f..caa92975 100644 --- a/test/hyprland/fixtures/IPCTestFixture.hpp +++ b/test/hyprland/fixtures/IPCTestFixture.hpp @@ -19,4 +19,7 @@ class IPCMock : public IPCTestFixture { public: // Mock getSocket1Reply to return an empty string static std::string getSocket1Reply(const std::string& rq) { return ""; } + + protected: + const char* instanceSig = "instance_sig"; }; From 90ac7d5d2c0fd5728647dd63fe0069170bfabe16 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Tue, 16 Jul 2024 22:48:25 -0500 Subject: [PATCH 16/35] sway/workspaces: support ignore window-rewrite Similar to hyprland implementation to ignore "" empty rules --- man/waybar-sway-workspaces.5.scd | 1 + src/modules/sway/workspaces.cpp | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/man/waybar-sway-workspaces.5.scd b/man/waybar-sway-workspaces.5.scd index a65a999b..fc73a85a 100644 --- a/man/waybar-sway-workspaces.5.scd +++ b/man/waybar-sway-workspaces.5.scd @@ -87,6 +87,7 @@ warp-on-scroll: ++ Regex rules to map window class to an icon or preferred method of representation for a workspace's window. Keys are the rules, while the values are the methods of representation. Rules may specify `class<...>`, `title<...>`, or both in order to fine-tune the matching. + You may assign an empty value to a rule to have it ignored from generating any representation in workspaces. *window-rewrite-default*: typeof: string ++ diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 0ca41d1c..8f273300 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -261,13 +261,17 @@ void Workspaces::updateWindows(const Json::Value &node, std::string &windows) { node["name"].isString()) { std::string title = g_markup_escape_text(node["name"].asString().c_str(), -1); std::string windowClass = node["app_id"].asString(); - std::string windowReprKey = fmt::format("class<{}> title<{}>", windowClass, title); - std::string window = m_windowRewriteRules.get(windowReprKey); - // allow result to have formatting - window = - fmt::format(fmt::runtime(window), fmt::arg("name", title), fmt::arg("class", windowClass)); - windows.append(window); - windows.append(m_formatWindowSeperator); + + // Only add window rewrites that can be looked up + if (!windowClass.empty()) { + std::string windowReprKey = fmt::format("class<{}> title<{}>", windowClass, title); + std::string window = m_windowRewriteRules.get(windowReprKey); + // allow result to have formatting + window = fmt::format(fmt::runtime(window), fmt::arg("name", title), + fmt::arg("class", windowClass)); + windows.append(window); + windows.append(m_formatWindowSeperator); + } } for (const Json::Value &child : node["nodes"]) { updateWindows(child, windows); From ed0ed398b74cdd3bbf6bfcc751255507c56062e2 Mon Sep 17 00:00:00 2001 From: Alexis Rouillard Date: Wed, 17 Jul 2024 22:46:58 +0200 Subject: [PATCH 17/35] Update freebsd.yml --- .github/workflows/freebsd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index 7effb484..242633f5 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Test in FreeBSD VM - uses: cross-platform-actions/action@v0.23.0 + uses: cross-platform-actions/action@v0.25.0 timeout-minutes: 180 env: CPPFLAGS: '-isystem/usr/local/include' From dcbcf90aef9665b179cf8c021dfd1c008e06ee10 Mon Sep 17 00:00:00 2001 From: Alexis Rouillard Date: Wed, 17 Jul 2024 22:52:39 +0200 Subject: [PATCH 18/35] Update freebsd.yml --- .github/workflows/freebsd.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index 242633f5..bbb97198 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -21,11 +21,10 @@ jobs: LDFLAGS: '-L/usr/local/lib' with: operating_system: freebsd - version: "13.2" + version: "14.1" environment_variables: CPPFLAGS LDFLAGS sync_files: runner-to-vm run: | - sudo sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf sudo pkg install -y git # subprojects/date sudo pkg install -y catch evdev-proto gtk-layer-shell gtkmm30 jsoncpp \ libdbusmenu libevdev libfmt libmpdclient libudev-devd meson \ From 15e1547661bfc5fe9b3d45bb0d9cea11cf07db7f Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 17 Jul 2024 23:04:05 +0200 Subject: [PATCH 19/35] chore: 0.10.4 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index a154a51b..8daa6c9c 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project( 'waybar', 'cpp', 'c', - version: '0.10.3', + version: '0.10.4', license: 'MIT', meson_version: '>= 0.59.0', default_options : [ From ee0912a254326ecbc0686fdd6c571f63bac73d95 Mon Sep 17 00:00:00 2001 From: "Rene D. Obermueller" Date: Sat, 20 Jul 2024 09:00:59 +0200 Subject: [PATCH 20/35] Issue #3414/clock: Shift ONLY calendar Right now, for the tooltip, all times are shifted if shift-down/shift-up actions are used. But it really only makes sense for this to apply to the {calendar} replacement, so use shiftedNow there and now for all the rest. --- src/modules/clock.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/modules/clock.cpp b/src/modules/clock.cpp index fe2c4c8f..7a4cb9c2 100644 --- a/src/modules/clock.cpp +++ b/src/modules/clock.cpp @@ -163,15 +163,16 @@ auto waybar::modules::Clock::update() -> void { // std::vformat doesn't support named arguments. m_tlpText_ = std::regex_replace(m_tlpFmt_, std::regex("\\{" + kTZPlaceholder + "\\}"), tzText_); - m_tlpText_ = - std::regex_replace(m_tlpText_, std::regex("\\{" + kCldPlaceholder + "\\}"), cldText_); + m_tlpText_ = std::regex_replace( + m_tlpText_, std::regex("\\{" + kCldPlaceholder + "\\}"), + fmt_lib::vformat(m_locale_, cldText_, fmt_lib::make_format_args(shiftedNow))); m_tlpText_ = std::regex_replace(m_tlpText_, std::regex("\\{" + kOrdPlaceholder + "\\}"), ordText_); } else { m_tlpText_ = m_tlpFmt_; } - m_tlpText_ = fmt_lib::vformat(m_locale_, m_tlpText_, fmt_lib::make_format_args(shiftedNow)); + m_tlpText_ = fmt_lib::vformat(m_locale_, m_tlpText_, fmt_lib::make_format_args(now)); m_tooltip_->set_markup(m_tlpText_); label_.trigger_tooltip_query(); } From a544f4b2cdcf632f1a4424b89f6e3d85ef5aaa85 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Sat, 20 Jul 2024 09:33:13 -0500 Subject: [PATCH 21/35] bar: fix setVisible Accidentally removed updating the visible variable --- include/bar.hpp | 2 +- src/bar.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/bar.hpp b/include/bar.hpp index 6900da47..43756bfd 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -66,7 +66,7 @@ class Bar { ~Bar(); void setMode(const std::string &mode); - void setVisible(bool visible); + void setVisible(bool value); void toggle(); void handleSignal(int); diff --git a/src/bar.cpp b/src/bar.cpp index 8c75c2c2..8a245ad1 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -404,7 +404,8 @@ void waybar::Bar::onMap(GdkEventAny* /*unused*/) { setPassThrough(passthrough_); } -void waybar::Bar::setVisible(bool visible) { +void waybar::Bar::setVisible(bool value) { + visible = value; if (auto mode = config.get("mode", {}); mode.isString()) { setMode(visible ? config["mode"].asString() : MODE_INVISIBLE); } else { From 58e21e876e3b4184f197ed8c8f48a081130ab3a4 Mon Sep 17 00:00:00 2001 From: DomCristaldi Date: Sat, 20 Jul 2024 22:58:03 -0400 Subject: [PATCH 22/35] walk up symlink tree "reload_style_on_change" would check if the target file is a symlink, but only resolves the first link. If the symlink is acutally a chain of symlink, such as what happens with NixOS's mkOutOfStoreSymlink, we will not find the actual file style file. Update the symlink resolution logic to walk down the symlink chain until it finds a non-symlink. Also check against a the original filename (which may be a symlink) to guard against infinitely looping on a circular symlink chain. --- src/util/css_reload_helper.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/util/css_reload_helper.cpp b/src/util/css_reload_helper.cpp index 45fd801a..e440c3c1 100644 --- a/src/util/css_reload_helper.cpp +++ b/src/util/css_reload_helper.cpp @@ -43,8 +43,14 @@ std::string waybar::CssReloadHelper::findPath(const std::string& filename) { } // File monitor does not work with symlinks, so resolve them - if (std::filesystem::is_symlink(result)) { + std::string original = result; + while(std::filesystem::is_symlink(result)) { result = std::filesystem::read_symlink(result); + + // prevent infinite cycle + if (result == original) { + break; + } } return result; From 7e1fffc455cb9930982e65d29e1b8bfd7d2c90d9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Aug 2024 00:09:59 +0000 Subject: [PATCH 23/35] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/693bc46d169f5af9c992095736e82c3488bf7dbb?narHash=sha256-oedh2RwpjEa%2BTNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA%3D' (2024-07-14) → 'github:NixOS/nixpkgs/52ec9ac3b12395ad677e8b62106f0b98c1f8569d?narHash=sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k%3D' (2024-07-28) --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 0d945dbe..b8f68f4b 100644 --- a/flake.lock +++ b/flake.lock @@ -18,11 +18,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1720957393, - "narHash": "sha256-oedh2RwpjEa+TNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA=", + "lastModified": 1722185531, + "narHash": "sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "693bc46d169f5af9c992095736e82c3488bf7dbb", + "rev": "52ec9ac3b12395ad677e8b62106f0b98c1f8569d", "type": "github" }, "original": { From 7ec1343ad5012e5ada25e76aefc227d35e4ce7f7 Mon Sep 17 00:00:00 2001 From: yangyingchao Date: Thu, 1 Aug 2024 17:47:10 +0800 Subject: [PATCH 24/35] fix #3490: expand menu file before opening it --- include/config.hpp | 3 +++ src/ALabel.cpp | 12 +++++++++++- src/config.cpp | 3 ++- src/util/css_reload_helper.cpp | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 66945542..18a1daed 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -20,6 +20,9 @@ class Config { static std::optional findConfigPath( const std::vector &names, const std::vector &dirs = CONFIG_DIRS); + static std::optional tryExpandPath(const std::string &base, + const std::string &filename); + Config() = default; void load(const std::string &config); diff --git a/src/ALabel.cpp b/src/ALabel.cpp index da2991a3..ecb1b7ce 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -6,6 +6,8 @@ #include #include +#include "config.hpp" + namespace waybar { ALabel::ALabel(const Json::Value& config, const std::string& name, const std::string& id, @@ -61,6 +63,14 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st try { // Check that the file exists std::string menuFile = config_["menu-file"].asString(); + + // there might be "~" or "$HOME" in original path, try to expand it. + auto result = Config::tryExpandPath(menuFile, ""); + if (!result.has_value()) { + throw std::runtime_error("Failed to expand file: " + menuFile); + } + + menuFile = result.value(); // Read the menu descriptor file std::ifstream file(menuFile); if (!file.is_open()) { @@ -170,7 +180,7 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) { return AModule::handleToggle(e); } -void ALabel::handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data) { +void ALabel::handleGtkMenuEvent(GtkMenuItem* /*menuitem*/, gpointer data) { waybar::util::command::res res = waybar::util::command::exec((char*)data, "GtkMenu"); } diff --git a/src/config.cpp b/src/config.cpp index b78af56c..375dc4cb 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -21,7 +21,8 @@ const std::vector Config::CONFIG_DIRS = { const char *Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR"; -std::optional tryExpandPath(const std::string &base, const std::string &filename) { +std::optional Config::tryExpandPath(const std::string &base, + const std::string &filename) { fs::path path; if (!filename.empty()) { diff --git a/src/util/css_reload_helper.cpp b/src/util/css_reload_helper.cpp index e440c3c1..274bdeed 100644 --- a/src/util/css_reload_helper.cpp +++ b/src/util/css_reload_helper.cpp @@ -44,7 +44,7 @@ std::string waybar::CssReloadHelper::findPath(const std::string& filename) { // File monitor does not work with symlinks, so resolve them std::string original = result; - while(std::filesystem::is_symlink(result)) { + while (std::filesystem::is_symlink(result)) { result = std::filesystem::read_symlink(result); // prevent infinite cycle From 24a9886952297a3be27c26195b924c5bf975f260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20S=C3=A1lyi?= Date: Fri, 2 Aug 2024 15:21:01 +0200 Subject: [PATCH 25/35] Handle offline CPUs and CPU hotplug First of all in case when the number CPUs change prevent out-of-bound index access in waybar::modules::CpuUsage::getCpuUsage() Secondly on Linux when updating CPU usage read /sys/devices/system/cpu/present and use it to detect the offline CPUs missing from /proc/stat For offline CPUs report 0 usage and "offline" in the tooltip Fixes issue #3498 On Linux one can test this functionality with: echo 0 > /sys/devices/system/cpu/cpu1/online echo 1 > /sys/devices/system/cpu/cpu1/online On non-Linux OSes I'm not sure how to detect offline CPUs, so I didn't add the offline CPU detection there but at least CPU number change should not cause a crash there anymore or cause memory safety issues after this fix --- src/modules/cpu_usage/common.cpp | 27 +++++++++++++++++++++++ src/modules/cpu_usage/linux.cpp | 38 ++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/modules/cpu_usage/common.cpp b/src/modules/cpu_usage/common.cpp index 4e36f48e..e3947967 100644 --- a/src/modules/cpu_usage/common.cpp +++ b/src/modules/cpu_usage/common.cpp @@ -61,9 +61,36 @@ std::tuple, std::string> waybar::modules::CpuUsage::getCpu std::vector> curr_times = CpuUsage::parseCpuinfo(); std::string tooltip; std::vector usage; + + if (curr_times.size() != prev_times.size()) { + // The number of CPUs has changed, eg. due to CPU hotplug + // We don't know which CPU came up or went down + // so only give total usage (if we can) + if (!curr_times.empty() && !prev_times.empty()) { + auto [curr_idle, curr_total] = curr_times[0]; + auto [prev_idle, prev_total] = prev_times[0]; + const float delta_idle = curr_idle - prev_idle; + const float delta_total = curr_total - prev_total; + uint16_t tmp = 100 * (1 - delta_idle / delta_total); + tooltip = fmt::format("Total: {}%\nCores: (pending)", tmp); + usage.push_back(tmp); + } else { + tooltip = "(pending)"; + usage.push_back(0); + } + prev_times = curr_times; + return {usage, tooltip}; + } + for (size_t i = 0; i < curr_times.size(); ++i) { auto [curr_idle, curr_total] = curr_times[i]; auto [prev_idle, prev_total] = prev_times[i]; + if (i > 0 && (curr_total == 0 || prev_total == 0)) { + // This CPU is offline + tooltip = tooltip + fmt::format("\nCore{}: offline", i - 1); + usage.push_back(0); + continue; + } const float delta_idle = curr_idle - prev_idle; const float delta_total = curr_total - prev_total; uint16_t tmp = 100 * (1 - delta_idle / delta_total); diff --git a/src/modules/cpu_usage/linux.cpp b/src/modules/cpu_usage/linux.cpp index bcd9594e..6fbd659b 100644 --- a/src/modules/cpu_usage/linux.cpp +++ b/src/modules/cpu_usage/linux.cpp @@ -3,6 +3,23 @@ #include "modules/cpu_usage.hpp" std::vector> waybar::modules::CpuUsage::parseCpuinfo() { + // Get the "existing CPU count" from /sys/devices/system/cpu/present + // Probably this is what the user wants the offline CPUs accounted from + // For further details see: + // https://www.kernel.org/doc/html/latest/core-api/cpu_hotplug.html + const std::string sys_cpu_present_path = "/sys/devices/system/cpu/present"; + size_t cpu_present_last = 0; + std::ifstream cpu_present_file(sys_cpu_present_path); + std::string cpu_present_text; + if (cpu_present_file.is_open()) { + getline(cpu_present_file, cpu_present_text); + // This is a comma-separated list of ranges, eg. 0,2-4,7 + size_t last_separator = cpu_present_text.find_last_of("-,"); + if (last_separator < cpu_present_text.size()) { + std::stringstream(cpu_present_text.substr(last_separator + 1)) >> cpu_present_last; + } + } + const std::string data_dir_ = "/proc/stat"; std::ifstream info(data_dir_); if (!info.is_open()) { @@ -10,14 +27,23 @@ std::vector> waybar::modules::CpuUsage::parseCpuinfo( } std::vector> cpuinfo; std::string line; + size_t current_cpu_number = -1; // First line is total, second line is cpu 0 while (getline(info, line)) { if (line.substr(0, 3).compare("cpu") != 0) { break; } + size_t line_cpu_number; + if (current_cpu_number >= 0) { + std::stringstream(line.substr(3)) >> line_cpu_number; + while (line_cpu_number > current_cpu_number) { + // Fill in 0 for offline CPUs missing inside the lines of /proc/stat + cpuinfo.emplace_back(0, 0); + current_cpu_number++; + } + } std::stringstream sline(line.substr(5)); std::vector times; - for (size_t time = 0; sline >> time; times.push_back(time)) - ; + for (size_t time = 0; sline >> time; times.push_back(time)); size_t idle_time = 0; size_t total_time = 0; @@ -27,6 +53,14 @@ std::vector> waybar::modules::CpuUsage::parseCpuinfo( total_time = std::accumulate(times.begin(), times.end(), 0); } cpuinfo.emplace_back(idle_time, total_time); + current_cpu_number++; } + + while (cpu_present_last >= current_cpu_number) { + // Fill in 0 for offline CPUs missing after the lines of /proc/stat + cpuinfo.emplace_back(0, 0); + current_cpu_number++; + } + return cpuinfo; } From 4efa1231835f87b55852cdf9e27b96d0cdb3d60c Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 2 Aug 2024 22:30:56 -0500 Subject: [PATCH 26/35] group: clang-tidy --- include/group.hpp | 2 +- src/group.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/group.hpp b/include/group.hpp index b10402c6..5ce331a8 100644 --- a/include/group.hpp +++ b/include/group.hpp @@ -12,7 +12,7 @@ namespace waybar { class Group : public AModule { public: Group(const std::string &, const std::string &, const Json::Value &, bool); - virtual ~Group() = default; + ~Group() override = default; auto update() -> void override; operator Gtk::Widget &() override; diff --git a/src/group.cpp b/src/group.cpp index deeecc75..2660868a 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -9,7 +9,7 @@ namespace waybar { -const Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical) { +Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical) { /* The transition direction of a drawer is not actually determined by the transition type, * but rather by the order of 'box' and 'revealer_box': * 'REVEALER_TRANSITION_TYPE_SLIDE_LEFT' and 'REVEALER_TRANSITION_TYPE_SLIDE_RIGHT' @@ -112,7 +112,7 @@ bool Group::handleToggle(GdkEventButton* const& e) { if (!click_to_reveal || e->button != 1) { return false; } - if (box.get_state_flags() & Gtk::StateFlags::STATE_FLAG_PRELIGHT) { + if ((box.get_state_flags() & Gtk::StateFlags::STATE_FLAG_PRELIGHT) != 0U) { hide_group(); } else { show_group(); From 3ae81d62bc300ece26c23e4f01c44180d6cc3edc Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 2 Aug 2024 22:32:22 -0500 Subject: [PATCH 27/35] group: fix hover regression We aren't including the hover detection on the revealer, so when the animation fires we fire the leave event which starts an infinite loop of enter/leave while we watch boxes move back and forth. --- include/group.hpp | 1 + src/group.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/group.hpp b/include/group.hpp index 5ce331a8..f5c6864b 100644 --- a/include/group.hpp +++ b/include/group.hpp @@ -30,6 +30,7 @@ class Group : public AModule { bool handleMouseEnter(GdkEventCrossing *const &ev) override; bool handleMouseLeave(GdkEventCrossing *const &ev) override; bool handleToggle(GdkEventButton *const &ev) override; + void addHoverHandlerTo(Gtk::Widget &widget); void show_group(); void hide_group(); }; diff --git a/src/group.cpp b/src/group.cpp index 2660868a..9b7ac2d5 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -81,9 +81,16 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value& } } + addHoverHandlerTo(revealer); event_box_.add(box); } +void Group::addHoverHandlerTo(Gtk::Widget& widget) { + widget.add_events(Gdk::EventMask::ENTER_NOTIFY_MASK | Gdk::EventMask::LEAVE_NOTIFY_MASK); + widget.signal_enter_notify_event().connect(sigc::mem_fun(*this, &Group::handleMouseEnter)); + widget.signal_leave_notify_event().connect(sigc::mem_fun(*this, &Group::handleMouseLeave)); +} + void Group::show_group() { box.set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); revealer.set_reveal_child(true); From 05d69ae82244cb28d4ce22009dc2bc486d278574 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 2 Aug 2024 22:37:06 -0500 Subject: [PATCH 28/35] src/util/css_reload_helper: clang-format --- src/util/css_reload_helper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/css_reload_helper.cpp b/src/util/css_reload_helper.cpp index e440c3c1..274bdeed 100644 --- a/src/util/css_reload_helper.cpp +++ b/src/util/css_reload_helper.cpp @@ -44,7 +44,7 @@ std::string waybar::CssReloadHelper::findPath(const std::string& filename) { // File monitor does not work with symlinks, so resolve them std::string original = result; - while(std::filesystem::is_symlink(result)) { + while (std::filesystem::is_symlink(result)) { result = std::filesystem::read_symlink(result); // prevent infinite cycle From 17f07b24522da93da28f3e9083d25cd7126489cf Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 2 Aug 2024 23:37:52 -0500 Subject: [PATCH 29/35] group: proper fix of enter/leave Ignore mouse leave event when we are still within the parent element --- include/group.hpp | 1 - src/group.cpp | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/include/group.hpp b/include/group.hpp index f5c6864b..5ce331a8 100644 --- a/include/group.hpp +++ b/include/group.hpp @@ -30,7 +30,6 @@ class Group : public AModule { bool handleMouseEnter(GdkEventCrossing *const &ev) override; bool handleMouseLeave(GdkEventCrossing *const &ev) override; bool handleToggle(GdkEventButton *const &ev) override; - void addHoverHandlerTo(Gtk::Widget &widget); void show_group(); void hide_group(); }; diff --git a/src/group.cpp b/src/group.cpp index 9b7ac2d5..50841efd 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -81,16 +81,9 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value& } } - addHoverHandlerTo(revealer); event_box_.add(box); } -void Group::addHoverHandlerTo(Gtk::Widget& widget) { - widget.add_events(Gdk::EventMask::ENTER_NOTIFY_MASK | Gdk::EventMask::LEAVE_NOTIFY_MASK); - widget.signal_enter_notify_event().connect(sigc::mem_fun(*this, &Group::handleMouseEnter)); - widget.signal_leave_notify_event().connect(sigc::mem_fun(*this, &Group::handleMouseLeave)); -} - void Group::show_group() { box.set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); revealer.set_reveal_child(true); @@ -109,7 +102,7 @@ bool Group::handleMouseEnter(GdkEventCrossing* const& e) { } bool Group::handleMouseLeave(GdkEventCrossing* const& e) { - if (!click_to_reveal) { + if (!click_to_reveal && e->detail != GDK_NOTIFY_INFERIOR) { hide_group(); } return false; From fdc8431709447bbfaf124115e2cffa1b54b391cb Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Sun, 4 Aug 2024 22:49:51 -0600 Subject: [PATCH 30/35] taskbar: Send minimize geometry hints This allows compositors to know the minimize widget geometry so that minimize animations work properly. --- include/modules/wlr/taskbar.hpp | 7 +++++++ src/modules/wlr/taskbar.cpp | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/include/modules/wlr/taskbar.hpp b/include/modules/wlr/taskbar.hpp index 4465dd06..026f364a 100644 --- a/include/modules/wlr/taskbar.hpp +++ b/include/modules/wlr/taskbar.hpp @@ -24,6 +24,10 @@ namespace waybar::modules::wlr { +struct widget_geometry { + int x, y, w, h; +}; + class Taskbar; class Task { @@ -42,6 +46,7 @@ class Task { }; // made public so TaskBar can reorder based on configuration. Gtk::Button button; + struct widget_geometry minimize_hint; private: static uint32_t global_id; @@ -82,6 +87,8 @@ class Task { private: std::string repr() const; std::string state_string(bool = false) const; + void set_minimize_hint(); + void on_button_size_allocated(Gtk::Allocation &alloc); void set_app_info_from_app_id_list(const std::string &app_id_list); bool image_load_icon(Gtk::Image &image, const Glib::RefPtr &icon_theme, Glib::RefPtr app_info, int size); diff --git a/src/modules/wlr/taskbar.cpp b/src/modules/wlr/taskbar.cpp index e6c8e536..7ff11baf 100644 --- a/src/modules/wlr/taskbar.cpp +++ b/src/modules/wlr/taskbar.cpp @@ -387,6 +387,10 @@ void Task::handle_title(const char *title) { hide_if_ignored(); } +void Task::set_minimize_hint() { + zwlr_foreign_toplevel_handle_v1_set_rectangle(handle_, bar_.surface, minimize_hint.x, minimize_hint.y, minimize_hint.w, minimize_hint.h); +} + void Task::hide_if_ignored() { if (tbar_->ignore_list().count(app_id_) || tbar_->ignore_list().count(title_)) { ignored_ = true; @@ -447,6 +451,12 @@ void Task::handle_app_id(const char *app_id) { spdlog::debug("Couldn't find icon for {}", app_id_); } +void Task::on_button_size_allocated(Gtk::Allocation &alloc) { + gtk_widget_translate_coordinates(GTK_WIDGET(button.gobj()), GTK_WIDGET(bar_.window.gobj()), 0, 0, &minimize_hint.x, &minimize_hint.y); + minimize_hint.w = button.get_width(); + minimize_hint.h = button.get_height(); +} + void Task::handle_output_enter(struct wl_output *output) { if (ignored_) { spdlog::debug("{} is ignored", repr()); @@ -457,6 +467,7 @@ void Task::handle_output_enter(struct wl_output *output) { if (!button_visible_ && (tbar_->all_outputs() || tbar_->show_output(output))) { /* The task entered the output of the current bar make the button visible */ + button.signal_size_allocate().connect_notify(sigc::mem_fun(this, &Task::on_button_size_allocated)); tbar_->add_button(button); button.show(); button_visible_ = true; @@ -553,9 +564,11 @@ bool Task::handle_clicked(GdkEventButton *bt) { return true; else if (action == "activate") activate(); - else if (action == "minimize") + else if (action == "minimize") { + set_minimize_hint(); minimize(!minimized()); - else if (action == "minimize-raise") { + } else if (action == "minimize-raise") { + set_minimize_hint(); if (minimized()) minimize(false); else if (active()) From c468119f5220b61045f6fcc4588f2bba7528b3a1 Mon Sep 17 00:00:00 2001 From: hacrvlq Date: Tue, 6 Aug 2024 18:01:37 +0200 Subject: [PATCH 31/35] fix(wireplumber): Handle changes to the default node ID --- src/modules/wireplumber.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index bd019b62..eddc3e6b 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -163,7 +163,8 @@ void waybar::modules::Wireplumber::onDefaultNodesApiChanged(waybar::modules::Wir "[{}]: (onDefaultNodesApiChanged) - got the following default node: Node(name: {}, id: {})", self->name_, defaultNodeName, defaultNodeId); - if (g_strcmp0(self->default_node_name_, defaultNodeName) == 0) { + if (g_strcmp0(self->default_node_name_, defaultNodeName) == 0 && + self->node_id_ == defaultNodeId) { spdlog::debug( "[{}]: (onDefaultNodesApiChanged) - Default node has not changed. Node(name: {}, id: {}). " "Ignoring.", From 1f23b30b560b4577bf65adc6f77bb5595abaccb0 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Sat, 17 Aug 2024 22:24:15 -0700 Subject: [PATCH 32/35] hyprland/backend: drop unnecessary getaddrinfo call Hyprland hasn't been using TCP sockets for IPC since the first release, so this getaddrinfo call and its result was never needed. Additionally, it leaks the `aiRes`, causing test failure under ASan. --- src/modules/hyprland/backend.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/modules/hyprland/backend.cpp b/src/modules/hyprland/backend.cpp index 60453dcb..77f534e0 100644 --- a/src/modules/hyprland/backend.cpp +++ b/src/modules/hyprland/backend.cpp @@ -148,22 +148,12 @@ void IPC::unregisterForIPC(EventHandler* ev_handler) { std::string IPC::getSocket1Reply(const std::string& rq) { // basically hyprctl - struct addrinfo aiHints; - struct addrinfo* aiRes = nullptr; const auto serverSocket = socket(AF_UNIX, SOCK_STREAM, 0); if (serverSocket < 0) { throw std::runtime_error("Hyprland IPC: Couldn't open a socket (1)"); } - memset(&aiHints, 0, sizeof(struct addrinfo)); - aiHints.ai_family = AF_UNSPEC; - aiHints.ai_socktype = SOCK_STREAM; - - if (getaddrinfo("localhost", nullptr, &aiHints, &aiRes) != 0) { - throw std::runtime_error("Hyprland IPC: Couldn't get host (2)"); - } - // get the instance signature auto* instanceSig = getenv("HYPRLAND_INSTANCE_SIGNATURE"); From fd478bf2ab3d00be7889054b4c517463e48df7ca Mon Sep 17 00:00:00 2001 From: yangyingchao Date: Mon, 19 Aug 2024 12:35:52 +0800 Subject: [PATCH 33/35] fix crash caused by use bar instance after it is freed (use-after-free) --- include/bar.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bar.hpp b/include/bar.hpp index 43756bfd..936bc749 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -54,7 +54,7 @@ class BarIpcClient; } #endif // HAVE_SWAY -class Bar { +class Bar : public sigc::trackable { public: using bar_mode_map = std::map; static const bar_mode_map PRESET_MODES; From 0fb1957daedee6316932be438fbbcf6140003849 Mon Sep 17 00:00:00 2001 From: Andrea Scarpino Date: Tue, 20 Aug 2024 13:57:29 +0200 Subject: [PATCH 34/35] fix: check format-source before use --- src/modules/pulseaudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index 3efd9d23..255ca571 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -106,7 +106,7 @@ auto waybar::modules::Pulseaudio::update() -> void { } } else { label_.get_style_context()->remove_class("source-muted"); - if (config_["format-source-muted"].isString()) { + if (config_["format-source"].isString()) { format_source = config_["format-source"].asString(); } } From 4d89c64bed8b5f5963615e65850238f1a4ee9cc6 Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Mon, 26 Aug 2024 04:44:22 -0600 Subject: [PATCH 35/35] taskbar: Fixup whitespace --- include/modules/wlr/taskbar.hpp | 2 +- src/modules/wlr/taskbar.cpp | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/modules/wlr/taskbar.hpp b/include/modules/wlr/taskbar.hpp index 026f364a..07110dde 100644 --- a/include/modules/wlr/taskbar.hpp +++ b/include/modules/wlr/taskbar.hpp @@ -25,7 +25,7 @@ namespace waybar::modules::wlr { struct widget_geometry { - int x, y, w, h; + int x, y, w, h; }; class Taskbar; diff --git a/src/modules/wlr/taskbar.cpp b/src/modules/wlr/taskbar.cpp index 7ff11baf..30e4ee48 100644 --- a/src/modules/wlr/taskbar.cpp +++ b/src/modules/wlr/taskbar.cpp @@ -388,7 +388,8 @@ void Task::handle_title(const char *title) { } void Task::set_minimize_hint() { - zwlr_foreign_toplevel_handle_v1_set_rectangle(handle_, bar_.surface, minimize_hint.x, minimize_hint.y, minimize_hint.w, minimize_hint.h); + zwlr_foreign_toplevel_handle_v1_set_rectangle(handle_, bar_.surface, minimize_hint.x, + minimize_hint.y, minimize_hint.w, minimize_hint.h); } void Task::hide_if_ignored() { @@ -452,9 +453,10 @@ void Task::handle_app_id(const char *app_id) { } void Task::on_button_size_allocated(Gtk::Allocation &alloc) { - gtk_widget_translate_coordinates(GTK_WIDGET(button.gobj()), GTK_WIDGET(bar_.window.gobj()), 0, 0, &minimize_hint.x, &minimize_hint.y); - minimize_hint.w = button.get_width(); - minimize_hint.h = button.get_height(); + gtk_widget_translate_coordinates(GTK_WIDGET(button.gobj()), GTK_WIDGET(bar_.window.gobj()), 0, 0, + &minimize_hint.x, &minimize_hint.y); + minimize_hint.w = button.get_width(); + minimize_hint.h = button.get_height(); } void Task::handle_output_enter(struct wl_output *output) { @@ -467,7 +469,8 @@ void Task::handle_output_enter(struct wl_output *output) { if (!button_visible_ && (tbar_->all_outputs() || tbar_->show_output(output))) { /* The task entered the output of the current bar make the button visible */ - button.signal_size_allocate().connect_notify(sigc::mem_fun(this, &Task::on_button_size_allocated)); + button.signal_size_allocate().connect_notify( + sigc::mem_fun(this, &Task::on_button_size_allocated)); tbar_->add_button(button); button.show(); button_visible_ = true;