diff --git a/README.md b/README.md index addee57a..2b57b139 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,14 @@ - Network - Bluetooth - Pulseaudio +- Wireplumber - Disk - Memory - Cpu load average - Temperature - MPD - Custom scripts +- Custom image - Multiple output configuration - And many more customizations diff --git a/include/AButton.hpp b/include/AButton.hpp deleted file mode 100644 index ce29a09f..00000000 --- a/include/AButton.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "AModule.hpp" - -namespace waybar { - -class AButton : public AModule { - public: - AButton(const Json::Value &, const std::string &, const std::string &, const std::string &format, - uint16_t interval = 0, bool ellipsize = false, bool enable_click = false, - bool enable_scroll = false); - virtual ~AButton() = default; - virtual auto update() -> void; - virtual std::string getIcon(uint16_t, const std::string &alt = "", uint16_t max = 0); - virtual std::string getIcon(uint16_t, const std::vector &alts, uint16_t max = 0); - - protected: - Gtk::Button button_ = Gtk::Button(name_); - Gtk::Label *label_ = (Gtk::Label *)button_.get_child(); - std::string format_; - const std::chrono::seconds interval_; - bool alt_ = false; - std::string default_format_; - - virtual bool handleToggle(GdkEventButton *const &e); - virtual std::string getState(uint8_t value, bool lesser = false); -}; - -} // namespace waybar diff --git a/include/factory.hpp b/include/factory.hpp index 8ac015a5..d69930f9 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -77,6 +77,7 @@ #endif #include "bar.hpp" #include "modules/custom.hpp" +#include "modules/image.hpp" #include "modules/temperature.hpp" #include "modules/user.hpp" diff --git a/include/modules/backlight.hpp b/include/modules/backlight.hpp index 90567716..81e2516a 100644 --- a/include/modules/backlight.hpp +++ b/include/modules/backlight.hpp @@ -5,7 +5,7 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/json.hpp" #include "util/sleeper_thread.hpp" @@ -14,7 +14,7 @@ struct udev_device; namespace waybar::modules { -class Backlight : public AButton { +class Backlight : public ALabel { class BacklightDev { public: BacklightDev() = default; diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp index 614b36ab..54a7dd3c 100644 --- a/include/modules/battery.hpp +++ b/include/modules/battery.hpp @@ -15,7 +15,7 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { @@ -26,7 +26,7 @@ namespace fs = std::experimental::filesystem; namespace fs = std::filesystem; #endif -class Battery : public AButton { +class Battery : public ALabel { public: Battery(const std::string&, const Json::Value&); ~Battery(); diff --git a/include/modules/bluetooth.hpp b/include/modules/bluetooth.hpp index 6aac0747..bd9737b1 100644 --- a/include/modules/bluetooth.hpp +++ b/include/modules/bluetooth.hpp @@ -1,6 +1,6 @@ #pragma once -#include "AButton.hpp" +#include "ALabel.hpp" #ifdef WANT_RFKILL #include "util/rfkill.hpp" #endif @@ -12,7 +12,7 @@ namespace waybar::modules { -class Bluetooth : public AButton { +class Bluetooth : public ALabel { struct ControllerInfo { std::string path; std::string address; diff --git a/include/modules/clock.hpp b/include/modules/clock.hpp index b3e49888..08ab05e0 100644 --- a/include/modules/clock.hpp +++ b/include/modules/clock.hpp @@ -2,7 +2,7 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar { @@ -14,7 +14,7 @@ namespace modules { const std::string kCalendarPlaceholder = "calendar"; const std::string KTimezonedTimeListPlaceholder = "timezoned_time_list"; -class Clock : public AButton { +class Clock : public ALabel { public: Clock(const std::string&, const Json::Value&); ~Clock() = default; diff --git a/include/modules/cpu.hpp b/include/modules/cpu.hpp index 4ad5771f..539f926c 100644 --- a/include/modules/cpu.hpp +++ b/include/modules/cpu.hpp @@ -9,12 +9,12 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Cpu : public AButton { +class Cpu : public ALabel { public: Cpu(const std::string&, const Json::Value&); ~Cpu() = default; diff --git a/include/modules/disk.hpp b/include/modules/disk.hpp index 761314e2..ec386b21 100644 --- a/include/modules/disk.hpp +++ b/include/modules/disk.hpp @@ -5,13 +5,13 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/format.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Disk : public AButton { +class Disk : public ALabel { public: Disk(const std::string&, const Json::Value&); ~Disk() = default; diff --git a/include/modules/hyprland/backend.hpp b/include/modules/hyprland/backend.hpp index 9401bf5a..d8767818 100644 --- a/include/modules/hyprland/backend.hpp +++ b/include/modules/hyprland/backend.hpp @@ -1,6 +1,6 @@ #pragma once -#include #include +#include #include #include #include @@ -9,7 +9,7 @@ namespace waybar::modules::hyprland { class EventHandler { -public: + public: virtual void onEvent(const std::string& ev) = 0; virtual ~EventHandler() = default; }; diff --git a/include/modules/hyprland/language.hpp b/include/modules/hyprland/language.hpp index 04fe3825..a07cfc00 100644 --- a/include/modules/hyprland/language.hpp +++ b/include/modules/hyprland/language.hpp @@ -1,14 +1,13 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "bar.hpp" #include "modules/hyprland/backend.hpp" #include "util/json.hpp" namespace waybar::modules::hyprland { -class Language : public waybar::AButton, -public EventHandler { +class Language : public waybar::ALabel, public EventHandler { public: Language(const std::string&, const waybar::Bar&, const Json::Value&); ~Language(); diff --git a/include/modules/hyprland/window.hpp b/include/modules/hyprland/window.hpp index 4b697cf3..35438cdd 100644 --- a/include/modules/hyprland/window.hpp +++ b/include/modules/hyprland/window.hpp @@ -9,8 +9,7 @@ namespace waybar::modules::hyprland { -class Window : public waybar::ALabel, - public EventHandler { +class Window : public waybar::ALabel, public EventHandler { public: Window(const std::string&, const waybar::Bar&, const Json::Value&); ~Window(); @@ -18,8 +17,8 @@ class Window : public waybar::ALabel, auto update() -> void; private: - uint getActiveWorkspaceID(std::string); - std::string getLastWindowTitle(uint); + int getActiveWorkspaceID(std::string); + std::string getLastWindowTitle(int); void onEvent(const std::string&); bool separate_outputs; diff --git a/include/modules/idle_inhibitor.hpp b/include/modules/idle_inhibitor.hpp index 80d370c4..8378e58d 100644 --- a/include/modules/idle_inhibitor.hpp +++ b/include/modules/idle_inhibitor.hpp @@ -2,13 +2,13 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "bar.hpp" #include "client.hpp" namespace waybar::modules { -class IdleInhibitor : public AButton { +class IdleInhibitor : public ALabel { sigc::connection timeout_; public: diff --git a/include/modules/image.hpp b/include/modules/image.hpp new file mode 100644 index 00000000..00b8393c --- /dev/null +++ b/include/modules/image.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#include +#include + +#include "ALabel.hpp" +#include "util/command.hpp" +#include "util/json.hpp" +#include "util/sleeper_thread.hpp" + +namespace waybar::modules { + +class Image : public AModule { + public: + Image(const std::string&, const std::string&, const Json::Value&); + auto update() -> void; + void refresh(int /*signal*/); + + private: + void delayWorker(); + void handleEvent(); + + Gtk::Image image_; + std::string path_; + int size_; + int interval_; + + util::SleeperThread thread_; +}; + +} // namespace waybar::modules diff --git a/include/modules/inhibitor.hpp b/include/modules/inhibitor.hpp index 9a012035..a5f300d6 100644 --- a/include/modules/inhibitor.hpp +++ b/include/modules/inhibitor.hpp @@ -4,12 +4,12 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "bar.hpp" namespace waybar::modules { -class Inhibitor : public AButton { +class Inhibitor : public ALabel { public: Inhibitor(const std::string&, const waybar::Bar&, const Json::Value&); ~Inhibitor() override; diff --git a/include/modules/memory.hpp b/include/modules/memory.hpp index a5887e3d..e23ed841 100644 --- a/include/modules/memory.hpp +++ b/include/modules/memory.hpp @@ -5,12 +5,12 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Memory : public AButton { +class Memory : public ALabel { public: Memory(const std::string&, const Json::Value&); ~Memory() = default; diff --git a/include/modules/mpd/mpd.hpp b/include/modules/mpd/mpd.hpp index b85906d1..ae3f9152 100644 --- a/include/modules/mpd/mpd.hpp +++ b/include/modules/mpd/mpd.hpp @@ -7,12 +7,12 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "modules/mpd/state.hpp" namespace waybar::modules { -class MPD : public AButton { +class MPD : public ALabel { friend class detail::Context; // State machine diff --git a/include/modules/mpd/state.hpp b/include/modules/mpd/state.hpp index 28ca6410..1276e3c3 100644 --- a/include/modules/mpd/state.hpp +++ b/include/modules/mpd/state.hpp @@ -7,7 +7,7 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" namespace waybar::modules { class MPD; diff --git a/include/modules/network.hpp b/include/modules/network.hpp index 9f13da59..8ec6b6df 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -10,7 +10,7 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" #ifdef WANT_RFKILL #include "util/rfkill.hpp" @@ -18,7 +18,7 @@ namespace waybar::modules { -class Network : public AButton { +class Network : public ALabel { public: Network(const std::string&, const Json::Value&); ~Network(); diff --git a/include/modules/pulseaudio.hpp b/include/modules/pulseaudio.hpp index f222f9e7..a8e4890a 100644 --- a/include/modules/pulseaudio.hpp +++ b/include/modules/pulseaudio.hpp @@ -7,11 +7,11 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" namespace waybar::modules { -class Pulseaudio : public AButton { +class Pulseaudio : public ALabel { public: Pulseaudio(const std::string&, const Json::Value&); ~Pulseaudio(); diff --git a/include/modules/simpleclock.hpp b/include/modules/simpleclock.hpp index 2945d86e..5cbee4c6 100644 --- a/include/modules/simpleclock.hpp +++ b/include/modules/simpleclock.hpp @@ -2,12 +2,12 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Clock : public AButton { +class Clock : public ALabel { public: Clock(const std::string&, const Json::Value&); ~Clock() = default; diff --git a/include/modules/sndio.hpp b/include/modules/sndio.hpp index 6d7350cf..eb9b218e 100644 --- a/include/modules/sndio.hpp +++ b/include/modules/sndio.hpp @@ -4,12 +4,12 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Sndio : public AButton { +class Sndio : public ALabel { public: Sndio(const std::string &, const Json::Value &); ~Sndio(); diff --git a/include/modules/sway/language.hpp b/include/modules/sway/language.hpp index 8673067b..f7602765 100644 --- a/include/modules/sway/language.hpp +++ b/include/modules/sway/language.hpp @@ -6,7 +6,7 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "bar.hpp" #include "client.hpp" #include "modules/sway/ipc/client.hpp" @@ -14,7 +14,7 @@ namespace waybar::modules::sway { -class Language : public AButton, public sigc::trackable { +class Language : public ALabel, public sigc::trackable { public: Language(const std::string& id, const Json::Value& config); ~Language() = default; diff --git a/include/modules/sway/mode.hpp b/include/modules/sway/mode.hpp index 041f68ac..5543c4eb 100644 --- a/include/modules/sway/mode.hpp +++ b/include/modules/sway/mode.hpp @@ -2,7 +2,7 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "bar.hpp" #include "client.hpp" #include "modules/sway/ipc/client.hpp" @@ -10,7 +10,7 @@ namespace waybar::modules::sway { -class Mode : public AButton, public sigc::trackable { +class Mode : public ALabel, public sigc::trackable { public: Mode(const std::string&, const Json::Value&); ~Mode() = default; diff --git a/include/modules/temperature.hpp b/include/modules/temperature.hpp index 47898015..04caafc5 100644 --- a/include/modules/temperature.hpp +++ b/include/modules/temperature.hpp @@ -4,12 +4,12 @@ #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Temperature : public AButton { +class Temperature : public ALabel { public: Temperature(const std::string&, const Json::Value&); ~Temperature() = default; diff --git a/include/modules/wireplumber.hpp b/include/modules/wireplumber.hpp index 5aa9e222..c0ee7f0b 100644 --- a/include/modules/wireplumber.hpp +++ b/include/modules/wireplumber.hpp @@ -6,35 +6,34 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" namespace waybar::modules { -class Wireplumber : public AButton { - public: - Wireplumber(const std::string&, const Json::Value&); - ~Wireplumber(); - auto update() -> void; +class Wireplumber : public ALabel { + public: + Wireplumber(const std::string&, const Json::Value&); + ~Wireplumber(); + auto update() -> void; - private: - void loadRequiredApiModules(); - void prepare(); - void activatePlugins(); - static void updateVolume(waybar::modules::Wireplumber* self); - static void updateNodeName(waybar::modules::Wireplumber* self); - static uint32_t getDefaultNodeId(waybar::modules::Wireplumber* self); - static void onPluginActivated(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self); - static void onObjectManagerInstalled(waybar::modules::Wireplumber* self); - - WpCore* wp_core_; - GPtrArray* apis_; - WpObjectManager* om_; - uint32_t pending_plugins_; - bool muted_; - double volume_; - uint32_t node_id_{0}; - std::string node_name_; + private: + void loadRequiredApiModules(); + void prepare(); + void activatePlugins(); + static void updateVolume(waybar::modules::Wireplumber* self); + static void updateNodeName(waybar::modules::Wireplumber* self); + static uint32_t getDefaultNodeId(waybar::modules::Wireplumber* self); + static void onPluginActivated(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self); + static void onObjectManagerInstalled(waybar::modules::Wireplumber* self); + WpCore* wp_core_; + GPtrArray* apis_; + WpObjectManager* om_; + uint32_t pending_plugins_; + bool muted_; + double volume_; + uint32_t node_id_{0}; + std::string node_name_; }; -} // namespace waybar::modules \ No newline at end of file +} // namespace waybar::modules diff --git a/man/waybar-image.5.scd b/man/waybar-image.5.scd new file mode 100644 index 00000000..feff9f6e --- /dev/null +++ b/man/waybar-image.5.scd @@ -0,0 +1,72 @@ +waybar-custom(5) + +# NAME + +waybar - image module + +# DESCRIPTION + +The *image* module displays an image from a path. + +# CONFIGURATION + +Addressed by *custom/* + +*path*: ++ + typeof: string ++ + The path to the image. + +*size*: ++ + typeof: integer ++ + The width/height to render the image. + +*interval*: ++ + typeof: integer ++ + The interval (in seconds) to re-render the image. + This is useful if the contents of *path* changes. + If no *interval* is defined, the image will only be rendered once. + +*signal*: ++ + typeof: integer ++ + The signal number used to update the module. + This can be used instead of *interval* if the file changes irregularly. + The number is valid between 1 and N, where *SIGRTMIN+N* = *SIGRTMAX*. + +*on-click*: ++ + 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. + +*on-update*: ++ + typeof: string ++ + Command to execute when the module is updated. + +*on-scroll-up*: ++ + typeof: string ++ + Command to execute when scrolling up on the module. + +*on-scroll-down*: ++ + typeof: string ++ + Command to execute when scrolling down on the module. + +*smooth-scrolling-threshold*: ++ + typeof: double ++ + Threshold to be used when scrolling. + +# EXAMPLES + +## Spotify: + +## mpd: + +``` +"image/album-art": { + "path": "/tmp/mpd_art", + "size": 32, + "interval": 5, + "on-click": "mpc toggle" +} +``` \ No newline at end of file diff --git a/man/waybar-upower.5.scd b/man/waybar-upower.5.scd index dae974dd..a6ba4df0 100644 --- a/man/waybar-upower.5.scd +++ b/man/waybar-upower.5.scd @@ -47,6 +47,10 @@ compatible devices in the tooltip. default: 4 ++ Defines the spacing between the tooltip window edge and the tooltip content. +*on-click*: ++ + typeof: string ++ + Command to execute when clicked on the module. + # FORMAT REPLACEMENTS *{percentage}*: The battery capacity in percentage diff --git a/meson.build b/meson.build index 3f033106..557a02dc 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project( 'waybar', 'cpp', 'c', - version: '0.9.15', + version: '0.9.16', license: 'MIT', meson_version: '>= 0.49.0', default_options : [ @@ -146,12 +146,12 @@ endif src_files = files( 'src/factory.cpp', 'src/AModule.cpp', - 'src/AButton.cpp', 'src/ALabel.cpp', 'src/AIconLabel.cpp', 'src/modules/custom.cpp', 'src/modules/disk.cpp', 'src/modules/idle_inhibitor.cpp', + 'src/modules/image.cpp', 'src/modules/temperature.cpp', 'src/modules/user.cpp', 'src/main.cpp', diff --git a/src/AButton.cpp b/src/AButton.cpp deleted file mode 100644 index 3457bcfa..00000000 --- a/src/AButton.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "AButton.hpp" - -#include - -#include - -namespace waybar { - -AButton::AButton(const Json::Value& config, const std::string& name, const std::string& id, - const std::string& format, uint16_t interval, bool ellipsize, bool enable_click, - bool enable_scroll) - : AModule(config, name, id, config["format-alt"].isString() || enable_click, enable_scroll), - format_(config_["format"].isString() ? config_["format"].asString() : format), - interval_(config_["interval"] == "once" - ? std::chrono::seconds(100000000) - : std::chrono::seconds( - config_["interval"].isUInt() ? config_["interval"].asUInt() : interval)), - default_format_(format_) { - button_.set_name(name); - button_.set_relief(Gtk::RELIEF_NONE); - - /* https://github.com/Alexays/Waybar/issues/1731 */ - auto css = Gtk::CssProvider::create(); - css->load_from_data( - "button { all: unset; min-width: 0; } label:disabled,button:disabled { all: inherit; } label " - "{ all: unset; }"); - button_.get_style_context()->add_provider(css, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - - if (!id.empty()) { - button_.get_style_context()->add_class(id); - } - event_box_.add(button_); - if (config_["max-length"].isUInt()) { - label_->set_max_width_chars(config_["max-length"].asInt()); - label_->set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); - label_->set_single_line_mode(true); - } else if (ellipsize && label_->get_max_width_chars() == -1) { - label_->set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); - label_->set_single_line_mode(true); - } - - if (config_["min-length"].isUInt()) { - label_->set_width_chars(config_["min-length"].asUInt()); - } - - uint rotate = 0; - - if (config_["rotate"].isUInt()) { - rotate = config["rotate"].asUInt(); - label_->set_angle(rotate); - } - - if (config_["align"].isDouble()) { - auto align = config_["align"].asFloat(); - if (rotate == 90 || rotate == 270) { - label_->set_yalign(align); - } else { - label_->set_xalign(align); - } - } - - if (!(config_["on-click"].isString() || config_["on-click-middle"].isString() || - config_["on-click-backward"].isString() || config_["on-click-forward"].isString() || - config_["on-click-right"].isString() || config_["format-alt"].isString() || enable_click)) { - button_.set_sensitive(false); - } else { - button_.signal_pressed().connect([this] { - GdkEventButton* e = (GdkEventButton*)gdk_event_new(GDK_BUTTON_PRESS); - e->button = 1; - handleToggle(e); - }); - } -} - -auto AButton::update() -> void { AModule::update(); } - -std::string AButton::getIcon(uint16_t percentage, const std::string& alt, uint16_t max) { - auto format_icons = config_["format-icons"]; - if (format_icons.isObject()) { - if (!alt.empty() && (format_icons[alt].isString() || format_icons[alt].isArray())) { - format_icons = format_icons[alt]; - } else { - format_icons = format_icons["default"]; - } - } - if (format_icons.isArray()) { - auto size = format_icons.size(); - auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1); - format_icons = format_icons[idx]; - } - if (format_icons.isString()) { - return format_icons.asString(); - } - return ""; -} - -std::string AButton::getIcon(uint16_t percentage, const std::vector& alts, - uint16_t max) { - auto format_icons = config_["format-icons"]; - if (format_icons.isObject()) { - std::string _alt = "default"; - for (const auto& alt : alts) { - if (!alt.empty() && (format_icons[alt].isString() || format_icons[alt].isArray())) { - _alt = alt; - break; - } - } - format_icons = format_icons[_alt]; - } - if (format_icons.isArray()) { - auto size = format_icons.size(); - auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1); - format_icons = format_icons[idx]; - } - if (format_icons.isString()) { - return format_icons.asString(); - } - return ""; -} - -bool waybar::AButton::handleToggle(GdkEventButton* const& e) { - if (config_["format-alt-click"].isUInt() && e->button == config_["format-alt-click"].asUInt()) { - alt_ = !alt_; - if (alt_ && config_["format-alt"].isString()) { - format_ = config_["format-alt"].asString(); - } else { - format_ = default_format_; - } - } - return AModule::handleToggle(e); -} - -std::string AButton::getState(uint8_t value, bool lesser) { - if (!config_["states"].isObject()) { - return ""; - } - // Get current state - std::vector> states; - if (config_["states"].isObject()) { - for (auto it = config_["states"].begin(); it != config_["states"].end(); ++it) { - if (it->isUInt() && it.key().isString()) { - states.emplace_back(it.key().asString(), it->asUInt()); - } - } - } - // Sort states - std::sort(states.begin(), states.end(), [&lesser](auto& a, auto& b) { - return lesser ? a.second < b.second : a.second > b.second; - }); - std::string valid_state; - for (auto const& state : states) { - if ((lesser ? value <= state.second : value >= state.second) && valid_state.empty()) { - button_.get_style_context()->add_class(state.first); - valid_state = state.first; - } else { - button_.get_style_context()->remove_class(state.first); - } - } - return valid_state; -} - -} // namespace waybar diff --git a/src/factory.cpp b/src/factory.cpp index d911872c..77f8ca0f 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -148,6 +148,8 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { } if (ref.compare(0, 7, "custom/") == 0 && ref.size() > 7) { return new waybar::modules::Custom(ref.substr(7), bar_, id, config_[name]); + } else if (ref.compare(0, 6, "image/") == 0 && ref.size() > 6) { + return new waybar::modules::Image(ref.substr(6), id, config_[name]); } } catch (const std::exception& e) { auto err = fmt::format("Disabling module \"{}\", {}", name, e.what()); diff --git a/src/modules/backlight.cpp b/src/modules/backlight.cpp index a3c612ca..aa734a4f 100644 --- a/src/modules/backlight.cpp +++ b/src/modules/backlight.cpp @@ -92,7 +92,7 @@ bool waybar::modules::Backlight::BacklightDev::get_powered() const { return powe void waybar::modules::Backlight::BacklightDev::set_powered(bool powered) { powered_ = powered; } waybar::modules::Backlight::Backlight(const std::string &id, const Json::Value &config) - : AButton(config, "backlight", id, "{percent}%", 2), + : ALabel(config, "backlight", id, "{percent}%", 2), preferred_device_(config["device"].isString() ? config["device"].asString() : "") { // Get initial state { @@ -181,8 +181,8 @@ auto waybar::modules::Backlight::update() -> void { event_box_.show(); const uint8_t percent = best->get_max() == 0 ? 100 : round(best->get_actual() * 100.0f / best->get_max()); - label_->set_markup(fmt::format(format_, fmt::arg("percent", std::to_string(percent)), - fmt::arg("icon", getIcon(percent)))); + label_.set_markup(fmt::format(format_, fmt::arg("percent", std::to_string(percent)), + fmt::arg("icon", getIcon(percent)))); getState(percent); } else { event_box_.hide(); @@ -191,12 +191,12 @@ auto waybar::modules::Backlight::update() -> void { if (!previous_best_.has_value()) { return; } - label_->set_markup(""); + label_.set_markup(""); } previous_best_ = best == nullptr ? std::nullopt : std::optional{*best}; previous_format_ = format_; // Call parent update - AButton::update(); + ALabel::update(); } template diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 0ddd8246..bb06781e 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -6,7 +6,7 @@ #include waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config) - : AButton(config, "battery", id, "{capacity}%", 60) { + : ALabel(config, "battery", id, "{capacity}%", 60) { #if defined(__linux__) battery_watch_fd_ = inotify_init1(IN_CLOEXEC); if (battery_watch_fd_ == -1) { @@ -613,14 +613,14 @@ auto waybar::modules::Battery::update() -> void { } else if (config_["tooltip-format"].isString()) { tooltip_format = config_["tooltip-format"].asString(); } - button_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("timeTo", tooltip_text_default), - fmt::arg("power", power), fmt::arg("capacity", capacity), - fmt::arg("time", time_remaining_formatted))); + label_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("timeTo", tooltip_text_default), + fmt::arg("power", power), fmt::arg("capacity", capacity), + fmt::arg("time", time_remaining_formatted))); } if (!old_status_.empty()) { - button_.get_style_context()->remove_class(old_status_); + label_.get_style_context()->remove_class(old_status_); } - button_.get_style_context()->add_class(status); + label_.get_style_context()->add_class(status); old_status_ = status; if (!state.empty() && config_["format-" + status + "-" + state].isString()) { format = config_["format-" + status + "-" + state].asString(); @@ -634,10 +634,10 @@ auto waybar::modules::Battery::update() -> void { } else { event_box_.show(); auto icons = std::vector{status + "-" + state, status, state}; - label_->set_markup(fmt::format(format, fmt::arg("capacity", capacity), fmt::arg("power", power), - fmt::arg("icon", getIcon(capacity, icons)), - fmt::arg("time", time_remaining_formatted))); + label_.set_markup(fmt::format(format, fmt::arg("capacity", capacity), fmt::arg("power", power), + fmt::arg("icon", getIcon(capacity, icons)), + fmt::arg("time", time_remaining_formatted))); } // Call parent update - AButton::update(); + ALabel::update(); } diff --git a/src/modules/bluetooth.cpp b/src/modules/bluetooth.cpp index a1233361..e6a1fe39 100644 --- a/src/modules/bluetooth.cpp +++ b/src/modules/bluetooth.cpp @@ -80,7 +80,7 @@ auto getUcharProperty(GDBusProxy* proxy, const char* property_name) -> unsigned } // namespace waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config) - : AButton(config, "bluetooth", id, " {status}", 10), + : ALabel(config, "bluetooth", id, " {status}", 10), #ifdef WANT_RFKILL rfkill_{RFKILL_TYPE_BLUETOOTH}, #endif @@ -190,10 +190,10 @@ auto waybar::modules::Bluetooth::update() -> void { format_.empty() ? event_box_.hide() : event_box_.show(); auto update_style_context = [this](const std::string& style_class, bool in_next_state) { - if (in_next_state && !button_.get_style_context()->has_class(style_class)) { - button_.get_style_context()->add_class(style_class); - } else if (!in_next_state && button_.get_style_context()->has_class(style_class)) { - button_.get_style_context()->remove_class(style_class); + if (in_next_state && !label_.get_style_context()->has_class(style_class)) { + label_.get_style_context()->add_class(style_class); + } else if (!in_next_state && label_.get_style_context()->has_class(style_class)) { + label_.get_style_context()->remove_class(style_class); } }; update_style_context("discoverable", cur_controller_.discoverable); @@ -205,7 +205,7 @@ auto waybar::modules::Bluetooth::update() -> void { update_style_context(state, true); state_ = state; - label_->set_markup(fmt::format( + label_.set_markup(fmt::format( format_, fmt::arg("status", state_), fmt::arg("num_connections", connected_devices_.size()), fmt::arg("controller_address", cur_controller_.address), fmt::arg("controller_address_type", cur_controller_.address_type), @@ -246,7 +246,7 @@ auto waybar::modules::Bluetooth::update() -> void { device_enumerate_.erase(0, 1); } } - button_.set_tooltip_text(fmt::format( + label_.set_tooltip_text(fmt::format( tooltip_format, fmt::arg("status", state_), fmt::arg("num_connections", connected_devices_.size()), fmt::arg("controller_address", cur_controller_.address), @@ -260,7 +260,7 @@ auto waybar::modules::Bluetooth::update() -> void { } // Call parent update - AButton::update(); + ALabel::update(); } // NOTE: only for when the org.bluez.Battery1 interface is added/removed after/before a device is diff --git a/src/modules/clock.cpp b/src/modules/clock.cpp index 80c02a45..71b24c19 100644 --- a/src/modules/clock.cpp +++ b/src/modules/clock.cpp @@ -18,7 +18,7 @@ using waybar::waybar_time; waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) - : AButton(config, "clock", id, "{:%H:%M}", 60, false, false, true), + : ALabel(config, "clock", id, "{:%H:%M}", 60, false, false, true), current_time_zone_idx_(0), is_calendar_in_tooltip_(false), is_timezoned_list_in_tooltip_(false) { @@ -107,7 +107,7 @@ auto waybar::modules::Clock::update() -> void { } else { text = fmt::format(format_, wtime); } - label_->set_markup(text); + label_.set_markup(text); if (tooltipEnabled()) { if (config_["tooltip-format"].isString()) { @@ -119,12 +119,12 @@ auto waybar::modules::Clock::update() -> void { text = fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines), fmt::arg(KTimezonedTimeListPlaceholder.c_str(), timezoned_time_lines)); - button_.set_tooltip_markup(text); + label_.set_tooltip_markup(text); } } // Call parent update - AButton::update(); + ALabel::update(); } bool waybar::modules::Clock::handleScroll(GdkEventScroll* e) { diff --git a/src/modules/cpu/common.cpp b/src/modules/cpu/common.cpp index 8201ed09..cdbbc3d4 100644 --- a/src/modules/cpu/common.cpp +++ b/src/modules/cpu/common.cpp @@ -10,7 +10,7 @@ #endif waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config) - : AButton(config, "cpu", id, "{usage}%", 10) { + : ALabel(config, "cpu", id, "{usage}%", 10) { thread_ = [this] { dp.emit(); thread_.sleep_for(interval_); @@ -23,7 +23,7 @@ auto waybar::modules::Cpu::update() -> void { auto [cpu_usage, tooltip] = getCpuUsage(); auto [max_frequency, min_frequency, avg_frequency] = getCpuFrequency(); if (tooltipEnabled()) { - button_.set_tooltip_text(tooltip); + label_.set_tooltip_text(tooltip); } auto format = format_; auto total_usage = cpu_usage.empty() ? 0 : cpu_usage[0]; @@ -52,11 +52,11 @@ auto waybar::modules::Cpu::update() -> void { auto icon_format = fmt::format("icon{}", core_i); store.push_back(fmt::arg(icon_format.c_str(), getIcon(cpu_usage[i], icons))); } - label_->set_markup(fmt::vformat(format, store)); + label_.set_markup(fmt::vformat(format, store)); } // Call parent update - AButton::update(); + ALabel::update(); } double waybar::modules::Cpu::getCpuLoad() { diff --git a/src/modules/disk.cpp b/src/modules/disk.cpp index 626378ca..5578dc2f 100644 --- a/src/modules/disk.cpp +++ b/src/modules/disk.cpp @@ -3,7 +3,7 @@ using namespace waybar::util; waybar::modules::Disk::Disk(const std::string& id, const Json::Value& config) - : AButton(config, "disk", id, "{}%", 30), path_("/") { + : ALabel(config, "disk", id, "{}%", 30), path_("/") { thread_ = [this] { dp.emit(); thread_.sleep_for(interval_); @@ -58,7 +58,7 @@ auto waybar::modules::Disk::update() -> void { event_box_.hide(); } else { event_box_.show(); - label_->set_markup( + label_.set_markup( fmt::format(format, stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free), fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks), fmt::arg("used", used), fmt::arg("percentage_used", percentage_used), @@ -70,12 +70,12 @@ auto waybar::modules::Disk::update() -> void { if (config_["tooltip-format"].isString()) { tooltip_format = config_["tooltip-format"].asString(); } - button_.set_tooltip_text( + label_.set_tooltip_text( fmt::format(tooltip_format, stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free), fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks), fmt::arg("used", used), fmt::arg("percentage_used", percentage_used), fmt::arg("total", total), fmt::arg("path", path_))); } // Call parent update - AButton::update(); + ALabel::update(); } diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index b6d7c0fa..ad0cdb81 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -11,7 +11,7 @@ namespace waybar::modules::hyprland { Language::Language(const std::string& id, const Bar& bar, const Json::Value& config) - : AButton(config, "language", id, "{}", 0, true), bar_(bar) { + : ALabel(config, "language", id, "{}", 0, true), bar_(bar) { modulesReady = true; if (!gIPC.get()) { @@ -21,8 +21,8 @@ Language::Language(const std::string& id, const Bar& bar, const Json::Value& con // get the active layout when open initLanguage(); - button_.hide(); - AButton::update(); + label_.hide(); + ALabel::update(); // register for hyprland ipc gIPC->registerForIPC("activelayout", this); @@ -38,13 +38,13 @@ auto Language::update() -> void { std::lock_guard lg(mutex_); if (!format_.empty()) { - button_.show(); - label_->set_markup(layoutName_); + label_.show(); + label_.set_markup(layoutName_); } else { - button_.hide(); + label_.hide(); } - AButton::update(); + ALabel::update(); } void Language::onEvent(const std::string& ev) { diff --git a/src/modules/hyprland/window.cpp b/src/modules/hyprland/window.cpp index c3bebe49..d3d06cc5 100644 --- a/src/modules/hyprland/window.cpp +++ b/src/modules/hyprland/window.cpp @@ -49,7 +49,7 @@ auto Window::update() -> void { ALabel::update(); } -uint Window::getActiveWorkspaceID(std::string monitorName) { +int Window::getActiveWorkspaceID(std::string monitorName) { auto cmd = waybar::util::command::exec("hyprctl monitors -j"); assert(cmd.exit_code == 0); Json::Value json = parser_.parse(cmd.out); @@ -59,16 +59,16 @@ uint Window::getActiveWorkspaceID(std::string monitorName) { if (monitor == std::end(json)) { return 0; } - return (*monitor)["activeWorkspace"]["id"].as(); + return (*monitor)["activeWorkspace"]["id"].as(); } -std::string Window::getLastWindowTitle(uint workspaceID) { +std::string Window::getLastWindowTitle(int workspaceID) { auto cmd = waybar::util::command::exec("hyprctl workspaces -j"); assert(cmd.exit_code == 0); Json::Value json = parser_.parse(cmd.out); assert(json.isArray()); auto workspace = std::find_if(json.begin(), json.end(), [&](Json::Value workspace) { - return workspace["id"].as() == workspaceID; + return workspace["id"].as() == workspaceID; }); if (workspace == std::end(json)) { diff --git a/src/modules/idle_inhibitor.cpp b/src/modules/idle_inhibitor.cpp index 0c82a08e..c4109b0e 100644 --- a/src/modules/idle_inhibitor.cpp +++ b/src/modules/idle_inhibitor.cpp @@ -8,7 +8,7 @@ bool waybar::modules::IdleInhibitor::status = false; waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, const Json::Value& config) - : AButton(config, "idle_inhibitor", id, "{status}", 0, false, true), + : ALabel(config, "idle_inhibitor", id, "{status}", 0, false, true), bar_(bar), idle_inhibitor_(nullptr), pid_(-1) { @@ -49,13 +49,13 @@ waybar::modules::IdleInhibitor::~IdleInhibitor() { auto waybar::modules::IdleInhibitor::update() -> void { // Check status if (status) { - button_.get_style_context()->remove_class("deactivated"); + label_.get_style_context()->remove_class("deactivated"); if (idle_inhibitor_ == nullptr) { idle_inhibitor_ = zwp_idle_inhibit_manager_v1_create_inhibitor( waybar::Client::inst()->idle_inhibit_manager, bar_.surface); } } else { - button_.get_style_context()->remove_class("activated"); + label_.get_style_context()->remove_class("activated"); if (idle_inhibitor_ != nullptr) { zwp_idle_inhibitor_v1_destroy(idle_inhibitor_); idle_inhibitor_ = nullptr; @@ -63,11 +63,11 @@ auto waybar::modules::IdleInhibitor::update() -> void { } std::string status_text = status ? "activated" : "deactivated"; - label_->set_markup(fmt::format(format_, fmt::arg("status", status_text), - fmt::arg("icon", getIcon(0, status_text)))); - button_.get_style_context()->add_class(status_text); + label_.set_markup(fmt::format(format_, fmt::arg("status", status_text), + fmt::arg("icon", getIcon(0, status_text)))); + label_.get_style_context()->add_class(status_text); if (tooltipEnabled()) { - button_.set_tooltip_markup( + label_.set_tooltip_markup( status ? fmt::format(config_["tooltip-format-activated"].isString() ? config_["tooltip-format-activated"].asString() : "{status}", @@ -80,7 +80,7 @@ auto waybar::modules::IdleInhibitor::update() -> void { fmt::arg("icon", getIcon(0, status_text)))); } // Call parent update - AButton::update(); + ALabel::update(); } void waybar::modules::IdleInhibitor::toggleStatus() { @@ -124,6 +124,6 @@ bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) { } } - AButton::handleToggle(e); + ALabel::handleToggle(e); return true; } diff --git a/src/modules/image.cpp b/src/modules/image.cpp new file mode 100644 index 00000000..eed19aea --- /dev/null +++ b/src/modules/image.cpp @@ -0,0 +1,59 @@ +#include "modules/image.hpp" + +#include + +waybar::modules::Image::Image(const std::string& name, const std::string& id, + const Json::Value& config) + : AModule(config, "image-" + name, id, "{}") { + event_box_.add(image_); + + dp.emit(); + + path_ = config["path"].asString(); + size_ = config["size"].asInt(); + + interval_ = config_["interval"].asInt(); + + if (size_ == 0) { + size_ = 16; + } + + if (interval_ == 0) { + interval_ = INT_MAX; + } + + delayWorker(); +} + +void waybar::modules::Image::delayWorker() { + thread_ = [this] { + dp.emit(); + auto interval = std::chrono::seconds(interval_); + thread_.sleep_for(interval); + }; +} + +void waybar::modules::Image::refresh(int sig) { + if (sig == SIGRTMIN + config_["signal"].asInt()) { + thread_.wake_up(); + } +} + +auto waybar::modules::Image::update() -> void { + Glib::RefPtr pixbuf; + + if (Glib::file_test(path_, Glib::FILE_TEST_EXISTS)) + pixbuf = Gdk::Pixbuf::create_from_file(path_, size_, size_); + else + pixbuf = {}; + + if (pixbuf) { + image_.set(pixbuf); + image_.show(); + } else { + image_.clear(); + image_.hide(); + } + + AModule::update(); +} diff --git a/src/modules/inhibitor.cpp b/src/modules/inhibitor.cpp index 73af5037..e4340b14 100644 --- a/src/modules/inhibitor.cpp +++ b/src/modules/inhibitor.cpp @@ -98,7 +98,7 @@ auto getInhibitors(const Json::Value& config) -> std::string { namespace waybar::modules { Inhibitor::Inhibitor(const std::string& id, const Bar& bar, const Json::Value& config) - : AButton(config, "inhibitor", id, "{status}", true), + : ALabel(config, "inhibitor", id, "{status}", true), dbus_(::dbus()), inhibitors_(::getInhibitors(config)) { event_box_.add_events(Gdk::BUTTON_PRESS_MASK); @@ -117,16 +117,16 @@ auto Inhibitor::activated() -> bool { return handle_ != -1; } auto Inhibitor::update() -> void { std::string status_text = activated() ? "activated" : "deactivated"; - button_.get_style_context()->remove_class(activated() ? "deactivated" : "activated"); - label_->set_markup(fmt::format(format_, fmt::arg("status", status_text), - fmt::arg("icon", getIcon(0, status_text)))); - button_.get_style_context()->add_class(status_text); + label_.get_style_context()->remove_class(activated() ? "deactivated" : "activated"); + label_.set_markup(fmt::format(format_, fmt::arg("status", status_text), + fmt::arg("icon", getIcon(0, status_text)))); + label_.get_style_context()->add_class(status_text); if (tooltipEnabled()) { - button_.set_tooltip_text(status_text); + label_.set_tooltip_text(status_text); } - return AButton::update(); + return ALabel::update(); } auto Inhibitor::handleToggle(GdkEventButton* const& e) -> bool { @@ -142,7 +142,7 @@ auto Inhibitor::handleToggle(GdkEventButton* const& e) -> bool { } } - return AButton::handleToggle(e); + return ALabel::handleToggle(e); } } // namespace waybar::modules diff --git a/src/modules/memory/common.cpp b/src/modules/memory/common.cpp index 8f190d2d..4a0e6347 100644 --- a/src/modules/memory/common.cpp +++ b/src/modules/memory/common.cpp @@ -1,7 +1,7 @@ #include "modules/memory.hpp" waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config) - : AButton(config, "memory", id, "{}%", 30) { + : ALabel(config, "memory", id, "{}%", 30) { thread_ = [this] { dp.emit(); thread_.sleep_for(interval_); @@ -55,7 +55,7 @@ auto waybar::modules::Memory::update() -> void { } else { event_box_.show(); auto icons = std::vector{state}; - label_->set_markup(fmt::format( + label_.set_markup(fmt::format( format, used_ram_percentage, fmt::arg("icon", getIcon(used_ram_percentage, icons)), fmt::arg("total", total_ram_gigabytes), fmt::arg("swapTotal", total_swap_gigabytes), fmt::arg("percentage", used_ram_percentage), @@ -67,7 +67,7 @@ auto waybar::modules::Memory::update() -> void { if (tooltipEnabled()) { if (config_["tooltip-format"].isString()) { auto tooltip_format = config_["tooltip-format"].asString(); - button_.set_tooltip_text(fmt::format( + label_.set_tooltip_text(fmt::format( tooltip_format, used_ram_percentage, fmt::arg("total", total_ram_gigabytes), fmt::arg("swapTotal", total_swap_gigabytes), fmt::arg("percentage", used_ram_percentage), @@ -75,12 +75,12 @@ auto waybar::modules::Memory::update() -> void { fmt::arg("swapUsed", used_swap_gigabytes), fmt::arg("avail", available_ram_gigabytes), fmt::arg("swapAvail", available_swap_gigabytes))); } else { - button_.set_tooltip_text(fmt::format("{:.{}f}GiB used", used_ram_gigabytes, 1)); + label_.set_tooltip_text(fmt::format("{:.{}f}GiB used", used_ram_gigabytes, 1)); } } } else { event_box_.hide(); } // Call parent update - AButton::update(); + ALabel::update(); } diff --git a/src/modules/mpd/mpd.cpp b/src/modules/mpd/mpd.cpp index 04d7a46d..99ba2bea 100644 --- a/src/modules/mpd/mpd.cpp +++ b/src/modules/mpd/mpd.cpp @@ -15,7 +15,7 @@ namespace waybar::modules { #endif waybar::modules::MPD::MPD(const std::string& id, const Json::Value& config) - : AButton(config, "mpd", id, "{album} - {artist} - {title}", 5, false, true), + : ALabel(config, "mpd", id, "{album} - {artist} - {title}", 5, false, true), module_name_(id.empty() ? "mpd" : "mpd#" + id), server_(nullptr), port_(config_["port"].isUInt() ? config["port"].asUInt() : 0), @@ -47,7 +47,7 @@ auto waybar::modules::MPD::update() -> void { context_.update(); // Call parent update - AButton::update(); + ALabel::update(); } void waybar::modules::MPD::queryMPD() { @@ -88,15 +88,15 @@ std::string waybar::modules::MPD::getFilename() const { void waybar::modules::MPD::setLabel() { if (connection_ == nullptr) { - button_.get_style_context()->add_class("disconnected"); - button_.get_style_context()->remove_class("stopped"); - button_.get_style_context()->remove_class("playing"); - button_.get_style_context()->remove_class("paused"); + label_.get_style_context()->add_class("disconnected"); + label_.get_style_context()->remove_class("stopped"); + label_.get_style_context()->remove_class("playing"); + label_.get_style_context()->remove_class("paused"); auto format = config_["format-disconnected"].isString() ? config_["format-disconnected"].asString() : "disconnected"; - label_->set_markup(format); + label_.set_markup(format); if (tooltipEnabled()) { std::string tooltip_format; @@ -104,11 +104,11 @@ void waybar::modules::MPD::setLabel() { ? config_["tooltip-format-disconnected"].asString() : "MPD (disconnected)"; // Nothing to format - button_.set_tooltip_text(tooltip_format); + label_.set_tooltip_text(tooltip_format); } return; } else { - button_.get_style_context()->remove_class("disconnected"); + label_.get_style_context()->remove_class("disconnected"); } auto format = format_; @@ -121,19 +121,19 @@ void waybar::modules::MPD::setLabel() { if (stopped()) { format = config_["format-stopped"].isString() ? config_["format-stopped"].asString() : "stopped"; - button_.get_style_context()->add_class("stopped"); - button_.get_style_context()->remove_class("playing"); - button_.get_style_context()->remove_class("paused"); + label_.get_style_context()->add_class("stopped"); + label_.get_style_context()->remove_class("playing"); + label_.get_style_context()->remove_class("paused"); } else { - button_.get_style_context()->remove_class("stopped"); + label_.get_style_context()->remove_class("stopped"); if (playing()) { - button_.get_style_context()->add_class("playing"); - button_.get_style_context()->remove_class("paused"); + label_.get_style_context()->add_class("playing"); + label_.get_style_context()->remove_class("paused"); } else if (paused()) { format = config_["format-paused"].isString() ? config_["format-paused"].asString() : config_["format"].asString(); - button_.get_style_context()->add_class("paused"); - button_.get_style_context()->remove_class("playing"); + label_.get_style_context()->add_class("paused"); + label_.get_style_context()->remove_class("playing"); } stateIcon = getStateIcon(); @@ -169,7 +169,7 @@ void waybar::modules::MPD::setLabel() { if (config_["title-len"].isInt()) title = title.substr(0, config_["title-len"].asInt()); try { - label_->set_markup(fmt::format( + label_.set_markup(fmt::format( format, fmt::arg("artist", artist.raw()), fmt::arg("albumArtist", album_artist.raw()), fmt::arg("album", album.raw()), fmt::arg("title", title.raw()), fmt::arg("date", date), fmt::arg("volume", volume), fmt::arg("elapsedTime", elapsedTime), @@ -196,7 +196,7 @@ void waybar::modules::MPD::setLabel() { fmt::arg("queueLength", queue_length), fmt::arg("stateIcon", stateIcon), fmt::arg("consumeIcon", consumeIcon), fmt::arg("randomIcon", randomIcon), fmt::arg("repeatIcon", repeatIcon), fmt::arg("singleIcon", singleIcon)); - button_.set_tooltip_text(tooltip_text); + label_.set_tooltip_text(tooltip_text); } catch (fmt::format_error const& e) { spdlog::warn("mpd: format error (tooltip): {}", e.what()); } diff --git a/src/modules/network.cpp b/src/modules/network.cpp index c787d5bd..a4797eec 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -78,7 +78,7 @@ waybar::modules::Network::readBandwidthUsage() { } waybar::modules::Network::Network(const std::string &id, const Json::Value &config) - : AButton(config, "network", id, DEFAULT_FORMAT, 60), + : ALabel(config, "network", id, DEFAULT_FORMAT, 60), ifid_(-1), family_(config["family"] == "ipv6" ? AF_INET6 : AF_INET), efd_(-1), @@ -95,11 +95,11 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf #endif frequency_(0.0) { - // Start with some "text" in the module's label_-> update() will then + // Start with some "text" in the module's label_. update() will then // update it. Since the text should be different, update() will be able // to show or hide the event_box_. This is to work around the case where // the module start with no text, but the the event_box_ is shown. - label_->set_markup(""); + label_.set_markup(""); auto bandwidth = readBandwidthUsage(); if (bandwidth.has_value()) { @@ -309,8 +309,8 @@ auto waybar::modules::Network::update() -> void { if (!alt_) { auto state = getNetworkState(); - if (!state_.empty() && button_.get_style_context()->has_class(state_)) { - button_.get_style_context()->remove_class(state_); + if (!state_.empty() && label_.get_style_context()->has_class(state_)) { + label_.get_style_context()->remove_class(state_); } if (config_["format-" + state].isString()) { default_format_ = config_["format-" + state].asString(); @@ -322,8 +322,8 @@ auto waybar::modules::Network::update() -> void { if (config_["tooltip-format-" + state].isString()) { tooltip_format = config_["tooltip-format-" + state].asString(); } - if (!button_.get_style_context()->has_class(state)) { - button_.get_style_context()->add_class(state); + if (!label_.get_style_context()->has_class(state)) { + label_.get_style_context()->add_class(state); } format_ = default_format_; state_ = state; @@ -349,8 +349,8 @@ auto waybar::modules::Network::update() -> void { fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / interval_.count(), "B/s")), fmt::arg("bandwidthTotalBytes", pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s"))); - if (text.compare(label_->get_label()) != 0) { - label_->set_markup(text); + if (text.compare(label_.get_label()) != 0) { + label_.set_markup(text); if (text.empty()) { event_box_.hide(); } else { @@ -382,16 +382,16 @@ auto waybar::modules::Network::update() -> void { fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / interval_.count(), "B/s")), fmt::arg("bandwidthTotalBytes", pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s"))); - if (button_.get_tooltip_text() != tooltip_text) { - button_.set_tooltip_markup(tooltip_text); + if (label_.get_tooltip_text() != tooltip_text) { + label_.set_tooltip_markup(tooltip_text); } - } else if (button_.get_tooltip_text() != text) { - button_.set_tooltip_markup(text); + } else if (label_.get_tooltip_text() != text) { + label_.set_tooltip_markup(text); } } // Call parent update - AButton::update(); + ALabel::update(); } bool waybar::modules::Network::checkInterface(std::string name) { diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index ce995ca2..4ba88de0 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -1,7 +1,7 @@ #include "modules/pulseaudio.hpp" waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value &config) - : AButton(config, "pulseaudio", id, "{volume}%"), + : ALabel(config, "pulseaudio", id, "{volume}%"), mainloop_(nullptr), mainloop_api_(nullptr), context_(nullptr), @@ -263,9 +263,9 @@ auto waybar::modules::Pulseaudio::update() -> void { monitor_.find("a2dp-sink") != std::string::npos || // PipeWire monitor_.find("bluez") != std::string::npos) { format_name = format_name + "-bluetooth"; - button_.get_style_context()->add_class("bluetooth"); + label_.get_style_context()->add_class("bluetooth"); } else { - button_.get_style_context()->remove_class("bluetooth"); + label_.get_style_context()->remove_class("bluetooth"); } if (muted_) { // Check muted bluetooth format exist, otherwise fallback to default muted format @@ -273,29 +273,29 @@ auto waybar::modules::Pulseaudio::update() -> void { format_name = "format"; } format_name = format_name + "-muted"; - button_.get_style_context()->add_class("muted"); - button_.get_style_context()->add_class("sink-muted"); + label_.get_style_context()->add_class("muted"); + label_.get_style_context()->add_class("sink-muted"); } else { - button_.get_style_context()->remove_class("muted"); - button_.get_style_context()->remove_class("sink-muted"); + label_.get_style_context()->remove_class("muted"); + label_.get_style_context()->remove_class("sink-muted"); } format = config_[format_name].isString() ? config_[format_name].asString() : format; } // TODO: find a better way to split source/sink std::string format_source = "{volume}%"; if (source_muted_) { - button_.get_style_context()->add_class("source-muted"); + label_.get_style_context()->add_class("source-muted"); if (config_["format-source-muted"].isString()) { format_source = config_["format-source-muted"].asString(); } } else { - button_.get_style_context()->remove_class("source-muted"); + label_.get_style_context()->remove_class("source-muted"); if (config_["format-source-muted"].isString()) { format_source = config_["format-source"].asString(); } } format_source = fmt::format(format_source, fmt::arg("volume", source_volume_)); - label_->set_markup(fmt::format( + label_.set_markup(fmt::format( format, fmt::arg("desc", desc_), fmt::arg("volume", volume_), fmt::arg("format_source", format_source), fmt::arg("source_volume", source_volume_), fmt::arg("source_desc", source_desc_), fmt::arg("icon", getIcon(volume_, getPulseIcon())))); @@ -306,16 +306,16 @@ auto waybar::modules::Pulseaudio::update() -> void { tooltip_format = config_["tooltip-format"].asString(); } if (!tooltip_format.empty()) { - button_.set_tooltip_text(fmt::format( + label_.set_tooltip_text(fmt::format( tooltip_format, fmt::arg("desc", desc_), fmt::arg("volume", volume_), fmt::arg("format_source", format_source), fmt::arg("source_volume", source_volume_), fmt::arg("source_desc", source_desc_), fmt::arg("icon", getIcon(volume_, getPulseIcon())))); } else { - button_.set_tooltip_text(desc_); + label_.set_tooltip_text(desc_); } } // Call parent update - AButton::update(); + ALabel::update(); } diff --git a/src/modules/simpleclock.cpp b/src/modules/simpleclock.cpp index f6fc17fb..27c7ac77 100644 --- a/src/modules/simpleclock.cpp +++ b/src/modules/simpleclock.cpp @@ -3,7 +3,7 @@ #include waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) - : AButton(config, "clock", id, "{:%H:%M}", 60) { + : ALabel(config, "clock", id, "{:%H:%M}", 60) { thread_ = [this] { dp.emit(); auto now = std::chrono::system_clock::now(); @@ -19,17 +19,17 @@ auto waybar::modules::Clock::update() -> void { auto now = std::chrono::system_clock::now(); auto localtime = fmt::localtime(std::chrono::system_clock::to_time_t(now)); auto text = fmt::format(format_, localtime); - label_->set_markup(text); + label_.set_markup(text); if (tooltipEnabled()) { if (config_["tooltip-format"].isString()) { auto tooltip_format = config_["tooltip-format"].asString(); auto tooltip_text = fmt::format(tooltip_format, localtime); - button_.set_tooltip_text(tooltip_text); + label_.set_tooltip_text(tooltip_text); } else { - button_.set_tooltip_text(text); + label_.set_tooltip_text(text); } } // Call parent update - AButton::update(); + ALabel::update(); } diff --git a/src/modules/sndio.cpp b/src/modules/sndio.cpp index dfab0d2a..92a8d3da 100644 --- a/src/modules/sndio.cpp +++ b/src/modules/sndio.cpp @@ -41,7 +41,7 @@ auto Sndio::connect_to_sndio() -> void { } Sndio::Sndio(const std::string &id, const Json::Value &config) - : AButton(config, "sndio", id, "{volume}%", 1, false, true), + : ALabel(config, "sndio", id, "{volume}%", 1, false, true), hdl_(nullptr), pfds_(0), addr_(0), @@ -105,14 +105,14 @@ auto Sndio::update() -> void { unsigned int vol = 100. * static_cast(volume_) / static_cast(maxval_); if (volume_ == 0) { - button_.get_style_context()->add_class("muted"); + label_.get_style_context()->add_class("muted"); } else { - button_.get_style_context()->remove_class("muted"); + label_.get_style_context()->remove_class("muted"); } - label_->set_markup(fmt::format(format, fmt::arg("volume", vol), fmt::arg("raw_value", volume_))); + label_.set_markup(fmt::format(format, fmt::arg("volume", vol), fmt::arg("raw_value", volume_))); - AButton::update(); + ALabel::update(); } auto Sndio::set_desc(struct sioctl_desc *d, unsigned int val) -> void { diff --git a/src/modules/sway/language.cpp b/src/modules/sway/language.cpp index 8a6af618..d3730a11 100644 --- a/src/modules/sway/language.cpp +++ b/src/modules/sway/language.cpp @@ -18,7 +18,7 @@ const std::string Language::XKB_LAYOUT_NAMES_KEY = "xkb_layout_names"; const std::string Language::XKB_ACTIVE_LAYOUT_NAME_KEY = "xkb_active_layout_name"; Language::Language(const std::string& id, const Json::Value& config) - : AButton(config, "language", id, "{}", 0, true) { + : ALabel(config, "language", id, "{}", 0, true) { is_variant_displayed = format_.find("{variant}") != std::string::npos; if (format_.find("{}") != std::string::npos || format_.find("{short}") != std::string::npos) { displayed_short_flag |= static_cast(DispayedShortFlag::ShortName); @@ -99,7 +99,7 @@ auto Language::update() -> void { format_, fmt::arg("short", layout_.short_name), fmt::arg("shortDescription", layout_.short_description), fmt::arg("long", layout_.full_name), fmt::arg("variant", layout_.variant), fmt::arg("flag", layout_.country_flag()))); - label_->set_markup(display_layout); + label_.set_markup(display_layout); if (tooltipEnabled()) { if (tooltip_format_ != "") { auto tooltip_display_layout = trim( @@ -107,22 +107,22 @@ auto Language::update() -> void { fmt::arg("shortDescription", layout_.short_description), fmt::arg("long", layout_.full_name), fmt::arg("variant", layout_.variant), fmt::arg("flag", layout_.country_flag()))); - button_.set_tooltip_markup(tooltip_display_layout); + label_.set_tooltip_markup(tooltip_display_layout); } else { - button_.set_tooltip_markup(display_layout); + label_.set_tooltip_markup(display_layout); } } event_box_.show(); // Call parent update - AButton::update(); + ALabel::update(); } auto Language::set_current_layout(std::string current_layout) -> void { - button_.get_style_context()->remove_class(layout_.short_name); + label_.get_style_context()->remove_class(layout_.short_name); layout_ = layouts_map_[current_layout]; - button_.get_style_context()->add_class(layout_.short_name); + label_.get_style_context()->add_class(layout_.short_name); } auto Language::init_layouts_map(const std::vector& used_layouts) -> void { diff --git a/src/modules/sway/mode.cpp b/src/modules/sway/mode.cpp index b6c9fc2b..7eaa523a 100644 --- a/src/modules/sway/mode.cpp +++ b/src/modules/sway/mode.cpp @@ -5,7 +5,7 @@ namespace waybar::modules::sway { Mode::Mode(const std::string& id, const Json::Value& config) - : AButton(config, "mode", id, "{}", 0, true) { + : ALabel(config, "mode", id, "{}", 0, true) { ipc_.subscribe(R"(["mode"])"); ipc_.signal_event.connect(sigc::mem_fun(*this, &Mode::onEvent)); // Launch worker @@ -42,14 +42,14 @@ auto Mode::update() -> void { if (mode_.empty()) { event_box_.hide(); } else { - label_->set_markup(fmt::format(format_, mode_)); + label_.set_markup(fmt::format(format_, mode_)); if (tooltipEnabled()) { - button_.set_tooltip_text(mode_); + label_.set_tooltip_text(mode_); } event_box_.show(); } // Call parent update - AButton::update(); + ALabel::update(); } } // namespace waybar::modules::sway diff --git a/src/modules/temperature.cpp b/src/modules/temperature.cpp index 935fea30..eca05a7d 100644 --- a/src/modules/temperature.cpp +++ b/src/modules/temperature.cpp @@ -7,7 +7,7 @@ #endif waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config) - : AButton(config, "temperature", id, "{temperatureC}°C", 10) { + : ALabel(config, "temperature", id, "{temperatureC}°C", 10) { #if defined(__FreeBSD__) // try to read sysctl? #else @@ -42,9 +42,9 @@ auto waybar::modules::Temperature::update() -> void { auto format = format_; if (critical) { format = config_["format-critical"].isString() ? config_["format-critical"].asString() : format; - button_.get_style_context()->add_class("critical"); + label_.get_style_context()->add_class("critical"); } else { - button_.get_style_context()->remove_class("critical"); + label_.get_style_context()->remove_class("critical"); } if (format.empty()) { @@ -55,21 +55,21 @@ auto waybar::modules::Temperature::update() -> void { } auto max_temp = config_["critical-threshold"].isInt() ? config_["critical-threshold"].asInt() : 0; - label_->set_markup(fmt::format(format, fmt::arg("temperatureC", temperature_c), - fmt::arg("temperatureF", temperature_f), - fmt::arg("temperatureK", temperature_k), - fmt::arg("icon", getIcon(temperature_c, "", max_temp)))); + label_.set_markup(fmt::format(format, fmt::arg("temperatureC", temperature_c), + fmt::arg("temperatureF", temperature_f), + fmt::arg("temperatureK", temperature_k), + fmt::arg("icon", getIcon(temperature_c, "", max_temp)))); if (tooltipEnabled()) { std::string tooltip_format = "{temperatureC}°C"; if (config_["tooltip-format"].isString()) { tooltip_format = config_["tooltip-format"].asString(); } - button_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("temperatureC", temperature_c), - fmt::arg("temperatureF", temperature_f), - fmt::arg("temperatureK", temperature_k))); + label_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("temperatureC", temperature_c), + fmt::arg("temperatureF", temperature_f), + fmt::arg("temperatureK", temperature_k))); } // Call parent update - AButton::update(); + ALabel::update(); } float waybar::modules::Temperature::getTemperature() { diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index 41fc362b..eb29913e 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -252,8 +252,7 @@ const std::string UPower::getDeviceStatus(UpDeviceState& state) { bool UPower::handleToggle(GdkEventButton* const& event) { std::lock_guard guard(m_Mutex); showAltText = !showAltText; - dp.emit(); - return true; + return AModule::handleToggle(event); } std::string UPower::timeToString(gint64 time) { diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index 81e639c2..0ab129e66 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -1,7 +1,7 @@ #include "modules/wireplumber.hpp" -waybar::modules::Wireplumber::Wireplumber(const std::string &id, const Json::Value &config) - : AButton(config, "wireplumber", id, "{volume}%"), +waybar::modules::Wireplumber::Wireplumber(const std::string& id, const Json::Value& config) + : ALabel(config, "wireplumber", id, "{volume}%"), wp_core_(nullptr), apis_(nullptr), om_(nullptr), @@ -9,31 +9,30 @@ waybar::modules::Wireplumber::Wireplumber(const std::string &id, const Json::Val muted_(false), volume_(0.0), node_id_(0) { - wp_init(WP_INIT_ALL); - wp_core_ = wp_core_new(NULL, NULL); - apis_ = g_ptr_array_new_with_free_func(g_object_unref); - om_ = wp_object_manager_new(); + wp_init(WP_INIT_ALL); + wp_core_ = wp_core_new(NULL, NULL); + apis_ = g_ptr_array_new_with_free_func(g_object_unref); + om_ = wp_object_manager_new(); - prepare(); + prepare(); - loadRequiredApiModules(); + loadRequiredApiModules(); - if (!wp_core_connect(wp_core_)) { - throw std::runtime_error("Could not connect to PipeWire\n"); - } + if (!wp_core_connect(wp_core_)) { + throw std::runtime_error("Could not connect to PipeWire\n"); + } - g_signal_connect_swapped(om_, "installed", (GCallback)onObjectManagerInstalled, this); - - activatePlugins(); - - dp.emit(); - } + g_signal_connect_swapped(om_, "installed", (GCallback)onObjectManagerInstalled, this); + + activatePlugins(); + + dp.emit(); +} waybar::modules::Wireplumber::~Wireplumber() { g_clear_pointer(&apis_, g_ptr_array_unref); g_clear_object(&om_); g_clear_object(&wp_core_); - } uint32_t waybar::modules::Wireplumber::getDefaultNodeId(waybar::modules::Wireplumber* self) { @@ -55,7 +54,9 @@ uint32_t waybar::modules::Wireplumber::getDefaultNodeId(waybar::modules::Wireplu } void waybar::modules::Wireplumber::updateNodeName(waybar::modules::Wireplumber* self) { - auto proxy = static_cast(wp_object_manager_lookup(self->om_, WP_TYPE_GLOBAL_PROXY, WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "object.id", "=u", self->node_id_, NULL)); + auto proxy = static_cast(wp_object_manager_lookup( + self->om_, WP_TYPE_GLOBAL_PROXY, WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "object.id", "=u", + self->node_id_, NULL)); if (!proxy) { throw std::runtime_error(fmt::format("Object '{}' not found\n", self->node_id_)); @@ -85,7 +86,8 @@ void waybar::modules::Wireplumber::updateVolume(waybar::modules::Wireplumber* se } void waybar::modules::Wireplumber::onObjectManagerInstalled(waybar::modules::Wireplumber* self) { - self->node_id_ = self->config_["node-id"].isInt() ? self->config_["node-id"].asInt() : getDefaultNodeId(self); + self->node_id_ = + self->config_["node-id"].isInt() ? self->config_["node-id"].asInt() : getDefaultNodeId(self); g_autoptr(WpPlugin) mixer_api = wp_plugin_find(self->wp_core_, "mixer-api"); @@ -94,7 +96,8 @@ void waybar::modules::Wireplumber::onObjectManagerInstalled(waybar::modules::Wir g_signal_connect_swapped(mixer_api, "changed", (GCallback)updateVolume, self); } -void waybar::modules::Wireplumber::onPluginActivated(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self) { +void waybar::modules::Wireplumber::onPluginActivated(WpObject* p, GAsyncResult* res, + waybar::modules::Wireplumber* self) { g_autoptr(GError) error = NULL; if (!wp_object_activate_finish(p, res, &error)) { @@ -108,34 +111,38 @@ void waybar::modules::Wireplumber::onPluginActivated(WpObject* p, GAsyncResult* void waybar::modules::Wireplumber::activatePlugins() { for (uint16_t i = 0; i < apis_->len; i++) { - WpPlugin* plugin = static_cast(g_ptr_array_index(apis_, i)); + WpPlugin* plugin = static_cast(g_ptr_array_index(apis_, i)); pending_plugins_++; - wp_object_activate(WP_OBJECT(plugin), WP_PLUGIN_FEATURE_ENABLED, NULL, (GAsyncReadyCallback)onPluginActivated, this); + wp_object_activate(WP_OBJECT(plugin), WP_PLUGIN_FEATURE_ENABLED, NULL, + (GAsyncReadyCallback)onPluginActivated, this); } } void waybar::modules::Wireplumber::prepare() { wp_object_manager_add_interest(om_, WP_TYPE_NODE, NULL); - wp_object_manager_request_object_features(om_, WP_TYPE_GLOBAL_PROXY, WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL); + wp_object_manager_request_object_features(om_, WP_TYPE_GLOBAL_PROXY, + WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL); } void waybar::modules::Wireplumber::loadRequiredApiModules() { g_autoptr(GError) error = NULL; - if (!wp_core_load_component(wp_core_, "libwireplumber-module-default-nodes-api", "module", NULL, &error)) { + if (!wp_core_load_component(wp_core_, "libwireplumber-module-default-nodes-api", "module", NULL, + &error)) { throw std::runtime_error(error->message); } - if (!wp_core_load_component(wp_core_, "libwireplumber-module-mixer-api", "module", NULL, &error)) { + if (!wp_core_load_component(wp_core_, "libwireplumber-module-mixer-api", "module", NULL, + &error)) { throw std::runtime_error(error->message); } g_ptr_array_add(apis_, wp_plugin_find(wp_core_, "default-nodes-api")); - g_ptr_array_add (apis_, ({ - WpPlugin *p = wp_plugin_find(wp_core_, "mixer-api"); - g_object_set (G_OBJECT (p), "scale", 1 /* cubic */, NULL); - p; - })); + g_ptr_array_add(apis_, ({ + WpPlugin* p = wp_plugin_find(wp_core_, "mixer-api"); + g_object_set(G_OBJECT(p), "scale", 1 /* cubic */, NULL); + p; + })); } auto waybar::modules::Wireplumber::update() -> void { @@ -144,13 +151,14 @@ auto waybar::modules::Wireplumber::update() -> void { if (muted_) { format = config_["format-muted"].isString() ? config_["format-muted"].asString() : format; - button_.get_style_context()->add_class("muted"); + label_.get_style_context()->add_class("muted"); } else { - button_.get_style_context()->remove_class("muted"); + label_.get_style_context()->remove_class("muted"); } - std::string markup = fmt::format(format, fmt::arg("node_name", node_name_), fmt::arg("volume", volume_)); - label_->set_markup(markup); + std::string markup = + fmt::format(format, fmt::arg("node_name", node_name_), fmt::arg("volume", volume_)); + label_.set_markup(markup); getState(volume_); @@ -160,13 +168,13 @@ auto waybar::modules::Wireplumber::update() -> void { } if (!tooltip_format.empty()) { - button_.set_tooltip_text(fmt::format( - tooltip_format, fmt::arg("node_name", node_name_), fmt::arg("volume", volume_))); + label_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("node_name", node_name_), + fmt::arg("volume", volume_))); } else { - button_.set_tooltip_text(node_name_); + label_.set_tooltip_text(node_name_); } } // Call parent update - AButton::update(); -} \ No newline at end of file + ALabel::update(); +} diff --git a/src/modules/wlr/workspace_manager.cpp b/src/modules/wlr/workspace_manager.cpp index da83cb79..6f11e1f2 100644 --- a/src/modules/wlr/workspace_manager.cpp +++ b/src/modules/wlr/workspace_manager.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include "gtkmm/widget.h" @@ -66,10 +67,13 @@ auto WorkspaceManager::workspace_comparator() const auto is_name_less = lhs->get_name() < rhs->get_name(); auto is_name_eq = lhs->get_name() == rhs->get_name(); auto is_coords_less = lhs->get_coords() < rhs->get_coords(); - auto is_number_less = std::stoi(lhs->get_name()) < std::stoi(rhs->get_name()); if (sort_by_number_) { - return is_number_less; + try { + auto is_number_less = std::stoi(lhs->get_name()) < std::stoi(rhs->get_name()); + return is_number_less; + } catch (std::invalid_argument) { + } } if (sort_by_name_) {