From 048c3e23416c9e1692d3551f9ebc068a10a6fd04 Mon Sep 17 00:00:00 2001 From: Viktar Lukashonak Date: Wed, 23 Oct 2024 19:19:43 +0300 Subject: [PATCH] GTK4 migration Signed-off-by: Viktar Lukashonak --- include/AAppIconLabel.hpp | 6 +- include/AIconLabel.hpp | 1 + include/ALabel.hpp | 20 +- include/AModule.hpp | 119 +++++--- include/ASlider.hpp | 7 +- include/bar.hpp | 25 +- include/client.hpp | 7 +- include/factory.hpp | 2 - include/group.hpp | 30 +- include/modules/backlight.hpp | 20 +- include/modules/backlight_slider.hpp | 6 +- include/modules/battery.hpp | 15 +- include/modules/bluetooth.hpp | 7 +- include/modules/cffi.hpp | 9 +- include/modules/cpu.hpp | 11 +- include/modules/cpu_frequency.hpp | 9 - include/modules/custom.hpp | 11 +- include/modules/disk.hpp | 8 +- include/modules/dwl/tags.hpp | 13 +- include/modules/dwl/window.hpp | 2 - include/modules/gamemode.hpp | 19 +- include/modules/idle_inhibitor.hpp | 6 +- include/modules/image.hpp | 12 +- include/modules/inhibitor.hpp | 17 +- include/modules/keyboard_state.hpp | 5 +- include/modules/load.hpp | 9 - include/modules/memory.hpp | 5 +- include/modules/mpd/mpd.hpp | 4 +- include/modules/{mpris => }/mpris.hpp | 4 +- include/modules/network.hpp | 9 +- include/modules/power_profiles_daemon.hpp | 2 +- include/modules/privacy/privacy.hpp | 9 +- include/modules/privacy/privacy_item.hpp | 6 +- include/modules/pulseaudio.hpp | 12 +- include/modules/pulseaudio_slider.hpp | 8 +- include/modules/sndio.hpp | 9 +- include/modules/sway/bar.hpp | 2 - include/modules/sway/ipc/client.hpp | 16 +- include/modules/sway/language.hpp | 8 +- include/modules/sway/mode.hpp | 6 +- include/modules/sway/scratchpad.hpp | 7 +- include/modules/sway/window.hpp | 7 +- include/modules/sway/workspaces.hpp | 11 +- include/modules/systemd_failed_units.hpp | 2 +- include/modules/temperature.hpp | 6 +- include/modules/ui.hpp | 17 ++ include/modules/upower.hpp | 6 +- include/modules/user.hpp | 9 +- include/modules/wireplumber.hpp | 4 +- include/util/SafeSignal.hpp | 17 +- include/util/audio_backend.hpp | 6 +- include/util/backend_common.hpp | 4 +- include/util/backlight_backend.hpp | 16 +- include/util/css_reload_helper.hpp | 10 +- include/util/format.hpp | 22 +- include/util/gtk_icon.hpp | 14 - include/util/pipewire/pipewire_backend.hpp | 5 +- include/util/pipewire/privacy_node_info.hpp | 32 +-- include/util/portal.hpp | 2 +- include/util/regex_collection.hpp | 1 - include/util/rfkill.hpp | 8 +- meson.build | 263 ++++++++--------- resources/ui/ui-power.xml | 43 +++ src/AAppIconLabel.cpp | 60 ++-- src/AIconLabel.cpp | 13 +- src/ALabel.cpp | 119 ++------ src/AModule.cpp | 302 +++++++++++--------- src/ASlider.cpp | 10 +- src/bar.cpp | 159 +++++------ src/client.cpp | 55 ++-- src/factory.cpp | 13 +- src/group.cpp | 100 +++---- src/main.cpp | 8 +- src/modules/backlight.cpp | 27 +- src/modules/backlight_slider.cpp | 2 +- src/modules/battery.cpp | 32 ++- src/modules/bluetooth.cpp | 8 +- src/modules/cffi.cpp | 7 +- src/modules/clock.cpp | 13 +- src/modules/cpu.cpp | 4 +- src/modules/cpu_frequency/common.cpp | 8 +- src/modules/cpu_frequency/linux.cpp | 1 + src/modules/cpu_usage/common.cpp | 4 +- src/modules/custom.cpp | 23 +- src/modules/disk.cpp | 13 +- src/modules/dwl/tags.cpp | 58 ++-- src/modules/dwl/window.cpp | 4 +- src/modules/gamemode.cpp | 62 ++-- src/modules/idle_inhibitor.cpp | 41 ++- src/modules/image.cpp | 35 ++- src/modules/inhibitor.cpp | 33 +-- src/modules/keyboard_state.cpp | 145 +++++----- src/modules/load.cpp | 6 +- src/modules/memory/common.cpp | 8 +- src/modules/memory/linux.cpp | 2 + src/modules/mpd/mpd.cpp | 17 +- src/modules/mpd/state.cpp | 13 +- src/modules/{mpris => }/mpris.cpp | 28 +- src/modules/network.cpp | 198 +++++++------ src/modules/power_profiles_daemon.cpp | 16 +- src/modules/privacy/privacy.cpp | 29 +- src/modules/privacy/privacy_item.cpp | 60 ++-- src/modules/pulseaudio.cpp | 56 ++-- src/modules/pulseaudio_slider.cpp | 8 +- src/modules/sndio.cpp | 57 ++-- src/modules/sway/bar.cpp | 37 ++- src/modules/sway/ipc/client.cpp | 30 +- src/modules/sway/language.cpp | 66 ++--- src/modules/sway/mode.cpp | 9 +- src/modules/sway/scratchpad.cpp | 24 +- src/modules/sway/window.cpp | 93 +++--- src/modules/sway/workspaces.cpp | 133 +++++---- src/modules/systemd_failed_units.cpp | 18 +- src/modules/temperature.cpp | 7 +- src/modules/ui.cpp | 40 +++ src/modules/upower.cpp | 74 +++-- src/modules/user.cpp | 20 +- src/modules/wireplumber.cpp | 9 +- src/util/audio_backend.cpp | 44 ++- src/util/backlight_backend.cpp | 9 +- src/util/css_reload_helper.cpp | 4 +- src/util/gtk_icon.cpp | 25 -- src/util/pipewire/pipewire_backend.cpp | 2 - src/util/pipewire/privacy_node_info.cpp | 4 +- src/util/portal.cpp | 2 +- src/util/regex_collection.cpp | 2 - src/util/rfkill.cpp | 13 +- subprojects/gtk-layer-shell.wrap | 5 - subprojects/gtk4-layer-shell.wrap | 8 + 129 files changed, 1659 insertions(+), 1884 deletions(-) rename include/modules/{mpris => }/mpris.hpp (96%) create mode 100644 include/modules/ui.hpp delete mode 100644 include/util/gtk_icon.hpp create mode 100644 resources/ui/ui-power.xml rename src/modules/{mpris => }/mpris.cpp (98%) create mode 100644 src/modules/ui.cpp delete mode 100644 src/util/gtk_icon.cpp delete mode 100644 subprojects/gtk-layer-shell.wrap create mode 100644 subprojects/gtk4-layer-shell.wrap diff --git a/include/AAppIconLabel.hpp b/include/AAppIconLabel.hpp index d09ab14a6..70d99edd5 100644 --- a/include/AAppIconLabel.hpp +++ b/include/AAppIconLabel.hpp @@ -1,7 +1,6 @@ #pragma once -#include -#include +#include #include "AIconLabel.hpp" @@ -19,9 +18,12 @@ class AAppIconLabel : public AIconLabel { void updateAppIconName(const std::string &app_identifier, const std::string &alternative_app_identifier); void updateAppIcon(); + + private: unsigned app_icon_size_{24}; bool update_app_icon_{true}; std::string app_icon_name_; + Glib::RefPtr gtkTheme_; }; } // namespace waybar diff --git a/include/AIconLabel.hpp b/include/AIconLabel.hpp index 054d031a3..e3ef39169 100644 --- a/include/AIconLabel.hpp +++ b/include/AIconLabel.hpp @@ -14,6 +14,7 @@ class AIconLabel : public ALabel { bool enable_click = false, bool enable_scroll = false); virtual ~AIconLabel() = default; auto update() -> void override; + operator Gtk::Widget &() override; protected: Gtk::Image image_; diff --git a/include/ALabel.hpp b/include/ALabel.hpp index a1aae9da9..2bbd63c76 100644 --- a/include/ALabel.hpp +++ b/include/ALabel.hpp @@ -1,8 +1,8 @@ #pragma once -#include #include -#include + +#include #include "AModule.hpp" @@ -10,27 +10,25 @@ namespace waybar { class ALabel : public AModule { public: - ALabel(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 ~ALabel() = default; auto update() -> void override; 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); + operator Gtk::Widget &() override; protected: - Gtk::Label label_; + ALabel(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); + std::string format_; + Gtk::Label label_; const std::chrono::seconds interval_; bool alt_ = false; std::string default_format_; - bool handleToggle(GdkEventButton *const &e) override; + void handleToggle(int n_press, double dx, double dy) override; virtual std::string getState(uint8_t value, bool lesser = false); - - std::map submenus_; - std::map menuActionsMap_; - static void handleGtkMenuEvent(GtkMenuItem *menuitem, gpointer data); }; } // namespace waybar diff --git a/include/AModule.hpp b/include/AModule.hpp index 94a883718..a9e45eb86 100644 --- a/include/AModule.hpp +++ b/include/AModule.hpp @@ -1,18 +1,17 @@ #pragma once #include -#include -#include -#include +#include +#include +#include #include #include "IModule.hpp" - namespace waybar { class AModule : public IModule { public: - static constexpr const char *MODULE_CLASS = "module"; + static constexpr const char *MODULE_CLASS{"module"}; ~AModule() override; auto update() -> void override; @@ -28,54 +27,88 @@ class AModule : public IModule { // Derived classes are able to use it AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false, bool enable_scroll = false); - + const std::string name_; + const Json::Value &config_; + Glib::RefPtr controllClick_; + Glib::RefPtr controllScroll_; + Glib::RefPtr controllMotion_; enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT }; - SCROLL_DIR getScrollDir(GdkEventScroll *e); + void bindEvents(Gtk::Widget &wg); + void unBindEvents(); bool tooltipEnabled() const; - const std::string name_; - const Json::Value &config_; - Gtk::EventBox event_box_; - - virtual void setCursor(Gdk::CursorType const &c); + virtual void setCursor(const Glib::RefPtr &cur); + virtual void setCursor(const Glib::ustring &name); - virtual bool handleToggle(GdkEventButton *const &ev); - virtual bool handleMouseEnter(GdkEventCrossing *const &ev); - virtual bool handleMouseLeave(GdkEventCrossing *const &ev); - virtual bool handleScroll(GdkEventScroll *); - virtual bool handleRelease(GdkEventButton *const &ev); - GObject *menu_; + virtual void handleToggle(int n_press, double dx, double dy); + virtual void handleRelease(int n_press, double dx, double dy); + virtual bool handleScroll(double dx, double dy); + virtual void handleMouseEnter(double x, double y); + virtual void handleMouseLeave(); + const SCROLL_DIR getScrollDir(Glib::RefPtr e); private: - bool handleUserEvent(GdkEventButton *const &ev); const bool isTooltip; - bool hasUserEvents_; + const bool isAfter{true}; + bool enableClick_{false}; + bool enableScroll_{false}; + bool hasPressEvents_{false}; + bool hasReleaseEvents_{false}; std::vector pid_; - gdouble distance_scrolled_y_; - gdouble distance_scrolled_x_; + double distance_scrolled_x_{0.0}; + double distance_scrolled_y_{0.0}; + const Glib::RefPtr curDefault; + const Glib::RefPtr curPoint; + Glib::RefPtr currEvent_; std::map eventActionMap_; - static const inline std::map, std::string> eventMap_{ - {std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"}, - {std::make_pair(1, GdkEventType::GDK_BUTTON_RELEASE), "on-click-release"}, - {std::make_pair(1, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click"}, - {std::make_pair(1, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click"}, - {std::make_pair(2, GdkEventType::GDK_BUTTON_PRESS), "on-click-middle"}, - {std::make_pair(2, GdkEventType::GDK_BUTTON_RELEASE), "on-click-middle-release"}, - {std::make_pair(2, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-middle"}, - {std::make_pair(2, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-middle"}, - {std::make_pair(3, GdkEventType::GDK_BUTTON_PRESS), "on-click-right"}, - {std::make_pair(3, GdkEventType::GDK_BUTTON_RELEASE), "on-click-right-release"}, - {std::make_pair(3, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-right"}, - {std::make_pair(3, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-right"}, - {std::make_pair(8, GdkEventType::GDK_BUTTON_PRESS), "on-click-backward"}, - {std::make_pair(8, GdkEventType::GDK_BUTTON_RELEASE), "on-click-backward-release"}, - {std::make_pair(8, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-backward"}, - {std::make_pair(8, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-backward"}, - {std::make_pair(9, GdkEventType::GDK_BUTTON_PRESS), "on-click-forward"}, - {std::make_pair(9, GdkEventType::GDK_BUTTON_RELEASE), "on-click-forward-release"}, - {std::make_pair(9, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-forward"}, - {std::make_pair(9, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-forward"}}; + static const inline std::map, Gdk::Event::Type>, std::string> + eventMap_{ + {std::make_pair(std::make_pair(1u, 1), Gdk::Event::Type::BUTTON_PRESS), "on-click"}, + {std::make_pair(std::make_pair(1u, 1), Gdk::Event::Type::BUTTON_RELEASE), + "on-click-release"}, + {std::make_pair(std::make_pair(1u, 2), Gdk::Event::Type::BUTTON_PRESS), + "on-double-click"}, + {std::make_pair(std::make_pair(1u, 3), Gdk::Event::Type::BUTTON_PRESS), + "on-triple-click"}, + {std::make_pair(std::make_pair(2u, 1), Gdk::Event::Type::BUTTON_PRESS), + "on-click-middle"}, + {std::make_pair(std::make_pair(2u, 1), Gdk::Event::Type::BUTTON_RELEASE), + "on-click-middle-release"}, + {std::make_pair(std::make_pair(2u, 2), Gdk::Event::Type::BUTTON_PRESS), + "on-double-click-middle"}, + {std::make_pair(std::make_pair(2u, 3), Gdk::Event::Type::BUTTON_PRESS), + "on-triple-click-middle"}, + {std::make_pair(std::make_pair(3u, 1), Gdk::Event::Type::BUTTON_PRESS), "on-click-right"}, + {std::make_pair(std::make_pair(3u, 1), Gdk::Event::Type::BUTTON_RELEASE), + "on-click-right-release"}, + {std::make_pair(std::make_pair(3u, 2), Gdk::Event::Type::BUTTON_PRESS), + "on-double-click-right"}, + {std::make_pair(std::make_pair(3u, 3), Gdk::Event::Type::BUTTON_PRESS), + "on-triple-click-right"}, + {std::make_pair(std::make_pair(8u, 1), Gdk::Event::Type::BUTTON_PRESS), + "on-click-backward"}, + {std::make_pair(std::make_pair(8u, 1), Gdk::Event::Type::BUTTON_RELEASE), + "on-click-backward-release"}, + {std::make_pair(std::make_pair(8u, 2), Gdk::Event::Type::BUTTON_PRESS), + "on-double-click-backward"}, + {std::make_pair(std::make_pair(8u, 3), Gdk::Event::Type::BUTTON_PRESS), + "on-triple-click-backward"}, + {std::make_pair(std::make_pair(9u, 1), Gdk::Event::Type::BUTTON_PRESS), + "on-click-forward"}, + {std::make_pair(std::make_pair(9u, 1), Gdk::Event::Type::BUTTON_RELEASE), + "on-click-forward-release"}, + {std::make_pair(std::make_pair(9u, 2), Gdk::Event::Type::BUTTON_PRESS), + "on-double-click-forward"}, + {std::make_pair(std::make_pair(9u, 3), Gdk::Event::Type::BUTTON_PRESS), + "on-triple-click-forward"}}; + void handleClickEvent(uint n_button, int n_press, Gdk::Event::Type n_evtype); + void makeControllClick(); + void makeControllScroll(); + void makeControllMotion(); + void removeControllClick(); + void removeControllScroll(); + void removeControllMotion(); }; } // namespace waybar diff --git a/include/ASlider.hpp b/include/ASlider.hpp index 44cde5077..b612a1301 100644 --- a/include/ASlider.hpp +++ b/include/ASlider.hpp @@ -9,11 +9,12 @@ class ASlider : public AModule { public: ASlider(const Json::Value& config, const std::string& name, const std::string& id); virtual void onValueChanged(); + operator Gtk::Widget&() override; protected: - bool vertical_ = false; - int min_ = 0, max_ = 100, curr_ = 50; + bool vertical_{false}; + int min_{0}, max_{100}, curr_{50}; Gtk::Scale scale_; }; -} // namespace waybar \ No newline at end of file +} // namespace waybar diff --git a/include/bar.hpp b/include/bar.hpp index 9b407abf4..91ba614c5 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -1,16 +1,10 @@ #pragma once #include -#include #include +#include #include -#include #include -#include - -#include -#include -#include #include "AModule.hpp" #include "group.hpp" @@ -75,18 +69,15 @@ class Bar : public sigc::trackable { struct wl_surface *surface; bool visible = true; Gtk::Window window; - Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL; - Gtk::PositionType position = Gtk::POS_TOP; - - int x_global; - int y_global; + Gtk::Orientation orientation{Gtk::Orientation::HORIZONTAL}; + Gtk::PositionType position{Gtk::PositionType::TOP}; #ifdef HAVE_SWAY std::string bar_id; #endif private: - void onMap(GdkEventAny *); + void onMap(); auto setupWidgets() -> void; void getModules(const Factory &, const std::string &, waybar::Group *); void setupAltFormatKeyForModule(const std::string &module_name); @@ -94,10 +85,14 @@ class Bar : public sigc::trackable { void setMode(const bar_mode &); void setPassThrough(bool passthrough); void setPosition(Gtk::PositionType position); - void onConfigure(GdkEventConfigure *ev); + void onConfigure(int width, int height); void configureGlobalOffset(int width, int height); void onOutputGeometryChanged(); + Glib::RefPtr gdk_surface_; + int x_global; + int y_global; + /* Copy initial set of modes to allow customization */ bar_mode_map configured_modes = PRESET_MODES; std::string last_mode_{MODE_DEFAULT}; @@ -109,7 +104,7 @@ class Bar : public sigc::trackable { Gtk::Box left_; Gtk::Box center_; Gtk::Box right_; - Gtk::Box box_; + Gtk::CenterBox box_; std::vector> modules_left_; std::vector> modules_center_; std::vector> modules_right_; diff --git a/include/client.hpp b/include/client.hpp index 0e68f0025..307b241ec 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -1,9 +1,6 @@ #pragma once -#include -#include -#include -#include +#include #include "bar.hpp" #include "config.hpp" @@ -33,6 +30,7 @@ class Client { private: Client() = default; + Glib::RefPtr monitors_; const std::string getStyle(const std::string &style, std::optional appearance); void bindInterfaces(); void handleOutput(struct waybar_output &output); @@ -50,7 +48,6 @@ class Client { void handleMonitorRemoved(Glib::RefPtr monitor); void handleDeferredMonitorRemoval(Glib::RefPtr monitor); - Glib::RefPtr style_context_; Glib::RefPtr css_provider_; std::unique_ptr portal; std::list outputs_; diff --git a/include/factory.hpp b/include/factory.hpp index f805aab5e..81530db09 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include namespace waybar { diff --git a/include/group.hpp b/include/group.hpp index 5ce331a8d..8dffa148a 100644 --- a/include/group.hpp +++ b/include/group.hpp @@ -1,35 +1,33 @@ #pragma once #include -#include -#include +#include #include "AModule.hpp" -#include "gtkmm/revealer.h" namespace waybar { -class Group : public AModule { +class Group final : public AModule { public: Group(const std::string &, const std::string &, const Json::Value &, bool); ~Group() override = default; auto update() -> void override; - operator Gtk::Widget &() override; virtual Gtk::Box &getBox(); void addWidget(Gtk::Widget &widget); - protected: - Gtk::Box box; - Gtk::Box revealer_box; - 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; + private: + Gtk::Box box_; + Gtk::Box revealer_box_; + Gtk::Revealer revealer_; + bool is_first_widget_{true}; + bool is_drawer_{false}; + bool click_to_reveal_{false}; + std::string add_class_to_drawer_children_; + + void handleMouseEnter(double x, double y) override; + void handleMouseLeave() override; + void handleToggle(int n_press, double dx, double dy) override; void show_group(); void hide_group(); }; diff --git a/include/modules/backlight.hpp b/include/modules/backlight.hpp index 110cd434b..12361294c 100644 --- a/include/modules/backlight.hpp +++ b/include/modules/backlight.hpp @@ -1,32 +1,22 @@ #pragma once -#include -#include -#include -#include -#include - #include "ALabel.hpp" #include "util/backlight_backend.hpp" -#include "util/json.hpp" - -struct udev; -struct udev_device; namespace waybar::modules { -class Backlight : public ALabel { +class Backlight final : public ALabel { public: Backlight(const std::string &, const Json::Value &); virtual ~Backlight() = default; auto update() -> void override; - bool handleScroll(GdkEventScroll *e) override; - + private: const std::string preferred_device_; - std::string previous_format_; - util::BacklightBackend backend; + + bool handleScroll(double dx, double dy) override; }; + } // namespace waybar::modules diff --git a/include/modules/backlight_slider.hpp b/include/modules/backlight_slider.hpp index 437c53c45..30fad3fca 100644 --- a/include/modules/backlight_slider.hpp +++ b/include/modules/backlight_slider.hpp @@ -1,13 +1,11 @@ #pragma once -#include - #include "ASlider.hpp" #include "util/backlight_backend.hpp" namespace waybar::modules { -class BacklightSlider : public ASlider { +class BacklightSlider final : public ASlider { public: BacklightSlider(const std::string&, const Json::Value&); virtual ~BacklightSlider() = default; @@ -21,4 +19,4 @@ class BacklightSlider : public ASlider { util::BacklightBackend backend; }; -} // namespace waybar::modules \ No newline at end of file +} // namespace waybar::modules diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp index 8e1a2ad2b..29828efd5 100644 --- a/include/modules/battery.hpp +++ b/include/modules/battery.hpp @@ -1,33 +1,25 @@ #pragma once -#include - #include #if defined(__linux__) #include #endif -#include -#include -#include -#include - #include "ALabel.hpp" -#include "bar.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { namespace fs = std::filesystem; -class Battery : public ALabel { +class Battery final : public ALabel { public: - Battery(const std::string&, const waybar::Bar&, const Json::Value&); + Battery(const std::string&, const Json::Value&); virtual ~Battery(); auto update() -> void override; private: - static inline const fs::path data_dir_ = "/sys/class/power_supply/"; + static inline const fs::path data_dir_{"/sys/class/power_supply/"}; void refreshBatteries(); void worker(); @@ -44,7 +36,6 @@ class Battery : public ALabel { std::mutex battery_list_mutex_; std::string old_status_; bool warnFirstTime_{true}; - const Bar& bar_; util::SleeperThread thread_; util::SleeperThread thread_battery_update_; diff --git a/include/modules/bluetooth.hpp b/include/modules/bluetooth.hpp index b89383a04..7e0770fa0 100644 --- a/include/modules/bluetooth.hpp +++ b/include/modules/bluetooth.hpp @@ -4,15 +4,10 @@ #ifdef WANT_RFKILL #include "util/rfkill.hpp" #endif -#include - -#include -#include -#include namespace waybar::modules { -class Bluetooth : public ALabel { +class Bluetooth final : public ALabel { struct ControllerInfo { std::string path; std::string address; diff --git a/include/modules/cffi.hpp b/include/modules/cffi.hpp index 85f129896..7a94f3eff 100644 --- a/include/modules/cffi.hpp +++ b/include/modules/cffi.hpp @@ -1,11 +1,6 @@ #pragma once -#include - #include "AModule.hpp" -#include "util/command.hpp" -#include "util/json.hpp" -#include "util/sleeper_thread.hpp" namespace waybar::modules { @@ -16,7 +11,7 @@ typedef struct wbcffi_module wbcffi_module; typedef struct { wbcffi_module* obj; const char* waybar_version; - GtkContainer* (*get_root_widget)(wbcffi_module*); + GtkWidget* (*get_root_widget)(wbcffi_module*); void (*queue_update)(wbcffi_module*); } wbcffi_init_info; @@ -27,7 +22,7 @@ struct wbcffi_config_entry { } } // namespace ffi -class CFFI : public AModule { +class CFFI final : public AModule { public: CFFI(const std::string&, const std::string&, const Json::Value&); virtual ~CFFI(); diff --git a/include/modules/cpu.hpp b/include/modules/cpu.hpp index 7f78c1650..739461846 100644 --- a/include/modules/cpu.hpp +++ b/include/modules/cpu.hpp @@ -1,20 +1,11 @@ #pragma once -#include - -#include -#include -#include -#include -#include -#include - #include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Cpu : public ALabel { +class Cpu final : public ALabel { public: Cpu(const std::string&, const Json::Value&); virtual ~Cpu() = default; diff --git a/include/modules/cpu_frequency.hpp b/include/modules/cpu_frequency.hpp index 49ca1b86a..fc4ad13fc 100644 --- a/include/modules/cpu_frequency.hpp +++ b/include/modules/cpu_frequency.hpp @@ -1,14 +1,5 @@ #pragma once -#include - -#include -#include -#include -#include -#include -#include - #include "ALabel.hpp" #include "util/sleeper_thread.hpp" diff --git a/include/modules/custom.hpp b/include/modules/custom.hpp index 6c17c6e45..faf728bc0 100644 --- a/include/modules/custom.hpp +++ b/include/modules/custom.hpp @@ -1,10 +1,5 @@ #pragma once -#include - -#include -#include - #include "ALabel.hpp" #include "util/command.hpp" #include "util/json.hpp" @@ -12,7 +7,7 @@ namespace waybar::modules { -class Custom : public ALabel { +class Custom final : public ALabel { public: Custom(const std::string&, const std::string&, const Json::Value&, const std::string&); virtual ~Custom(); @@ -26,8 +21,8 @@ class Custom : public ALabel { void parseOutputRaw(); void parseOutputJson(); void handleEvent(); - bool handleScroll(GdkEventScroll* e) override; - bool handleToggle(GdkEventButton* const& e) override; + bool handleScroll(double dx, double dy); + void handleToggle(int n_press, double dx, double dy); const std::string name_; const std::string output_name_; diff --git a/include/modules/disk.hpp b/include/modules/disk.hpp index 1b4f31761..d0f31c5fd 100644 --- a/include/modules/disk.hpp +++ b/include/modules/disk.hpp @@ -1,17 +1,11 @@ #pragma once -#include -#include - -#include - #include "ALabel.hpp" -#include "util/format.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Disk : public ALabel { +class Disk final : public ALabel { public: Disk(const std::string&, const Json::Value&); virtual ~Disk() = default; diff --git a/include/modules/dwl/tags.hpp b/include/modules/dwl/tags.hpp index 53dff9899..02758c185 100644 --- a/include/modules/dwl/tags.hpp +++ b/include/modules/dwl/tags.hpp @@ -1,26 +1,22 @@ #pragma once #include -#include #include "AModule.hpp" #include "bar.hpp" #include "dwl-ipc-unstable-v2-client-protocol.h" -#include "xdg-output-unstable-v1-client-protocol.h" namespace waybar::modules::dwl { -class Tags : public waybar::AModule { +class Tags final : public waybar::AModule { public: Tags(const std::string &, const waybar::Bar &, const Json::Value &); virtual ~Tags(); + operator Gtk::Widget &() override; // Handlers for wayland events void handle_view_tags(uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused); - void handle_primary_clicked(uint32_t tag); - bool handle_button_press(GdkEventButton *event_button, uint32_t tag); - struct zdwl_ipc_manager_v2 *status_manager_; struct wl_seat *seat_; @@ -28,7 +24,12 @@ class Tags : public waybar::AModule { const waybar::Bar &bar_; Gtk::Box box_; std::vector buttons_; + std::vector> clickControls_; struct zdwl_ipc_output_v2 *output_status_; + + void handle_primary_clicked(int n_press, double dx, double dy, uint32_t tag); + void handle_button_press(int n_press, double dx, double dy, uint32_t tag, + Glib::RefPtr controlClick); }; } /* namespace waybar::modules::dwl */ diff --git a/include/modules/dwl/window.hpp b/include/modules/dwl/window.hpp index 435863999..2c01be9a5 100644 --- a/include/modules/dwl/window.hpp +++ b/include/modules/dwl/window.hpp @@ -7,7 +7,6 @@ #include "AAppIconLabel.hpp" #include "bar.hpp" #include "dwl-ipc-unstable-v2-client-protocol.h" -#include "util/json.hpp" namespace waybar::modules::dwl { @@ -26,7 +25,6 @@ class Window : public AAppIconLabel, public sigc::trackable { private: const Bar &bar_; - std::string title_; std::string appid_; std::string layout_symbol_; diff --git a/include/modules/gamemode.hpp b/include/modules/gamemode.hpp index 69c0c3aeb..1d763ee9d 100644 --- a/include/modules/gamemode.hpp +++ b/include/modules/gamemode.hpp @@ -1,21 +1,15 @@ #pragma once -#include -#include -#include +#include +#include +#include +#include #include "ALabel.hpp" -#include "giomm/dbusconnection.h" -#include "giomm/dbusproxy.h" -#include "glibconfig.h" -#include "gtkmm/box.h" -#include "gtkmm/image.h" -#include "gtkmm/label.h" -#include "gtkmm/overlay.h" namespace waybar::modules { -class Gamemode : public AModule { +class Gamemode final : public ALabel { public: Gamemode(const std::string &, const Json::Value &); virtual ~Gamemode(); @@ -39,7 +33,7 @@ class Gamemode : public AModule { const Glib::VariantContainerBase &arguments); void getData(); - bool handleToggle(GdkEventButton *const &) override; + void handleToggle(int n_press, double dx, double dy) override; // Config std::string format = DEFAULT_FORMAT; @@ -70,6 +64,7 @@ class Gamemode : public AModule { guint login1_id; Glib::RefPtr gamemode_proxy; Glib::RefPtr system_connection; + Glib::RefPtr gtkTheme_; bool gamemodeRunning; guint gamemodeWatcher_id; }; diff --git a/include/modules/idle_inhibitor.hpp b/include/modules/idle_inhibitor.hpp index 22bd808fc..26f701269 100644 --- a/include/modules/idle_inhibitor.hpp +++ b/include/modules/idle_inhibitor.hpp @@ -1,14 +1,12 @@ #pragma once -#include - #include "ALabel.hpp" #include "bar.hpp" #include "client.hpp" namespace waybar::modules { -class IdleInhibitor : public ALabel { +class IdleInhibitor final : public ALabel { sigc::connection timeout_; public: @@ -19,7 +17,7 @@ class IdleInhibitor : public ALabel { static bool status; private: - bool handleToggle(GdkEventButton* const& e) override; + void handleToggle(int n_press, double dx, double dy); void toggleStatus(); const Bar& bar_; diff --git a/include/modules/image.hpp b/include/modules/image.hpp index 7c0d014fb..266b6f295 100644 --- a/include/modules/image.hpp +++ b/include/modules/image.hpp @@ -1,25 +1,21 @@ #pragma once -#include #include -#include -#include - -#include "ALabel.hpp" +#include "AModule.hpp" #include "gtkmm/box.h" #include "util/command.hpp" -#include "util/json.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Image : public AModule { +class Image final : public AModule { public: Image(const std::string&, const Json::Value&); virtual ~Image() = default; auto update() -> void override; void refresh(int /*signal*/) override; + operator Gtk::Widget&() override; private: void delayWorker(); @@ -29,7 +25,7 @@ class Image : public AModule { Gtk::Box box_; Gtk::Image image_; std::string path_; - std::string tooltip_; + Glib::ustring tooltip_; int size_; int interval_; util::command::res output_; diff --git a/include/modules/inhibitor.hpp b/include/modules/inhibitor.hpp index 43cb6cab1..5da8e6bb5 100644 --- a/include/modules/inhibitor.hpp +++ b/include/modules/inhibitor.hpp @@ -1,27 +1,26 @@ #pragma once -#include - -#include - #include "ALabel.hpp" -#include "bar.hpp" namespace waybar::modules { -class Inhibitor : public ALabel { +class Inhibitor final : public ALabel { public: - Inhibitor(const std::string&, const waybar::Bar&, const Json::Value&); + Inhibitor(const std::string&, const Json::Value&); virtual ~Inhibitor(); auto update() -> void override; + auto doAction(const std::string& name) -> void override; auto activated() -> bool; private: - auto handleToggle(::GdkEventButton* const& e) -> bool override; - const std::unique_ptr<::GDBusConnection, void (*)(::GDBusConnection*)> dbus_; const std::string inhibitors_; int handle_ = -1; + // Module actions + void toggle(); + // Module Action Map + static inline std::map actionMap_{ + {"toggle", &waybar::modules::Inhibitor::toggle}}; }; } // namespace waybar::modules diff --git a/include/modules/keyboard_state.hpp b/include/modules/keyboard_state.hpp index be90eee4d..eda9bc0f2 100644 --- a/include/modules/keyboard_state.hpp +++ b/include/modules/keyboard_state.hpp @@ -4,24 +4,23 @@ #include #include -#include #include "AModule.hpp" #include "bar.hpp" #include "util/sleeper_thread.hpp" extern "C" { -#include #include } namespace waybar::modules { -class KeyboardState : public AModule { +class KeyboardState final : public AModule { public: KeyboardState(const std::string&, const waybar::Bar&, const Json::Value&); virtual ~KeyboardState(); auto update() -> void override; + operator Gtk::Widget&() override; private: auto tryAddDevice(const std::string&) -> void; diff --git a/include/modules/load.hpp b/include/modules/load.hpp index c4c06d264..275108bd1 100644 --- a/include/modules/load.hpp +++ b/include/modules/load.hpp @@ -1,14 +1,5 @@ #pragma once -#include - -#include -#include -#include -#include -#include -#include - #include "ALabel.hpp" #include "util/sleeper_thread.hpp" diff --git a/include/modules/memory.hpp b/include/modules/memory.hpp index 3b6342b34..628a8b3a0 100644 --- a/include/modules/memory.hpp +++ b/include/modules/memory.hpp @@ -1,8 +1,5 @@ #pragma once -#include - -#include #include #include "ALabel.hpp" @@ -10,7 +7,7 @@ namespace waybar::modules { -class Memory : public ALabel { +class Memory final : public ALabel { public: Memory(const std::string&, const Json::Value&); virtual ~Memory() = default; diff --git a/include/modules/mpd/mpd.hpp b/include/modules/mpd/mpd.hpp index 32d526e93..ac289e681 100644 --- a/include/modules/mpd/mpd.hpp +++ b/include/modules/mpd/mpd.hpp @@ -12,7 +12,7 @@ namespace waybar::modules { -class MPD : public ALabel { +class MPD final : public ALabel { friend class detail::Context; // State machine @@ -47,7 +47,7 @@ class MPD : public ALabel { std::string getOptionIcon(std::string optionName, bool activated) const; // GUI-side methods - bool handlePlayPause(GdkEventButton* const&); + void handlePlayPause(int n_press, double dx, double dy); void emit() { dp.emit(); } // MPD-side, Non-GUI methods. diff --git a/include/modules/mpris/mpris.hpp b/include/modules/mpris.hpp similarity index 96% rename from include/modules/mpris/mpris.hpp rename to include/modules/mpris.hpp index ad4dac1e1..8e7c5d625 100644 --- a/include/modules/mpris/mpris.hpp +++ b/include/modules/mpris.hpp @@ -16,12 +16,12 @@ extern "C" { namespace waybar::modules::mpris { -class Mpris : public ALabel { +class Mpris final : public ALabel { public: Mpris(const std::string&, const Json::Value&); virtual ~Mpris(); auto update() -> void override; - bool handleToggle(GdkEventButton* const&) override; + void handleToggle(int n_press, double dx, double dy) override; private: static auto onPlayerNameAppeared(PlayerctlPlayerManager*, PlayerctlPlayerName*, gpointer) -> void; diff --git a/include/modules/network.hpp b/include/modules/network.hpp index 4a84b02f9..52d97c169 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -1,15 +1,8 @@ #pragma once -#include -#include -#include -#include #include -#include #include -#include - #include "ALabel.hpp" #include "util/sleeper_thread.hpp" #ifdef WANT_RFKILL @@ -18,7 +11,7 @@ namespace waybar::modules { -class Network : public ALabel { +class Network final : public ALabel { public: Network(const std::string&, const Json::Value&); virtual ~Network(); diff --git a/include/modules/power_profiles_daemon.hpp b/include/modules/power_profiles_daemon.hpp index a2bd38587..9829f3a88 100644 --- a/include/modules/power_profiles_daemon.hpp +++ b/include/modules/power_profiles_daemon.hpp @@ -24,7 +24,7 @@ class PowerProfilesDaemon : public ALabel { void getAllPropsCb(Glib::RefPtr &r); void setPropCb(Glib::RefPtr &r); void populateInitState(); - bool handleToggle(GdkEventButton *const &e) override; + void handleToggle(int n_press, double dx, double dy) override; private: // True if we're connected to the dbug interface. False if we're diff --git a/include/modules/privacy/privacy.hpp b/include/modules/privacy/privacy.hpp index d7656d312..4a3d5d7ef 100644 --- a/include/modules/privacy/privacy.hpp +++ b/include/modules/privacy/privacy.hpp @@ -1,20 +1,19 @@ #pragma once -#include +#include -#include "gtkmm/box.h" -#include "modules/privacy/privacy_item.hpp" +#include "AModule.hpp" #include "util/pipewire/pipewire_backend.hpp" -#include "util/pipewire/privacy_node_info.hpp" using waybar::util::PipewireBackend::PrivacyNodeInfo; namespace waybar::modules::privacy { -class Privacy : public AModule { +class Privacy final : public AModule { public: Privacy(const std::string &, const Json::Value &, const std::string &pos); auto update() -> void override; + operator Gtk::Widget &() override; void onPrivacyNodesChanged(); diff --git a/include/modules/privacy/privacy_item.hpp b/include/modules/privacy/privacy_item.hpp index 836bd994c..a1a9be8ae 100644 --- a/include/modules/privacy/privacy_item.hpp +++ b/include/modules/privacy/privacy_item.hpp @@ -2,9 +2,8 @@ #include -#include - #include "gtkmm/box.h" +#include "gtkmm/icontheme.h" #include "gtkmm/image.h" #include "gtkmm/revealer.h" #include "util/pipewire/privacy_node_info.hpp" @@ -14,7 +13,7 @@ using waybar::util::PipewireBackend::PrivacyNodeType; namespace waybar::modules::privacy { -class PrivacyItem : public Gtk::Revealer { +class PrivacyItem final : public Gtk::Revealer { public: PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privacy_type_, std::list *nodes, const std::string &pos, const uint icon_size, @@ -41,6 +40,7 @@ class PrivacyItem : public Gtk::Revealer { Gtk::Box box_; Gtk::Image icon_; + Glib::RefPtr gtkTheme_; void update_tooltip(); }; diff --git a/include/modules/pulseaudio.hpp b/include/modules/pulseaudio.hpp index eead664f1..abc3724fe 100644 --- a/include/modules/pulseaudio.hpp +++ b/include/modules/pulseaudio.hpp @@ -1,27 +1,21 @@ #pragma once -#include - -#include -#include -#include - #include "ALabel.hpp" #include "util/audio_backend.hpp" namespace waybar::modules { -class Pulseaudio : public ALabel { +class Pulseaudio final : public ALabel { public: Pulseaudio(const std::string&, const Json::Value&); virtual ~Pulseaudio() = default; auto update() -> void override; private: - bool handleScroll(GdkEventScroll* e) override; + bool handleScroll(double dx, double dy) override; const std::vector getPulseIcon() const; - std::shared_ptr backend = nullptr; + std::shared_ptr backend{nullptr}; }; } // namespace waybar::modules diff --git a/include/modules/pulseaudio_slider.hpp b/include/modules/pulseaudio_slider.hpp index 3ef446847..7b3d994fa 100644 --- a/include/modules/pulseaudio_slider.hpp +++ b/include/modules/pulseaudio_slider.hpp @@ -11,7 +11,7 @@ enum class PulseaudioSliderTarget { Source, }; -class PulseaudioSlider : public ASlider { +class PulseaudioSlider final : public ASlider { public: PulseaudioSlider(const std::string&, const Json::Value&); virtual ~PulseaudioSlider() = default; @@ -20,8 +20,8 @@ class PulseaudioSlider : public ASlider { void onValueChanged() override; private: - std::shared_ptr backend = nullptr; - PulseaudioSliderTarget target = PulseaudioSliderTarget::Sink; + std::shared_ptr backend{nullptr}; + PulseaudioSliderTarget target{PulseaudioSliderTarget::Sink}; }; -} // namespace waybar::modules \ No newline at end of file +} // namespace waybar::modules diff --git a/include/modules/sndio.hpp b/include/modules/sndio.hpp index 3fe36fadf..0f394f778 100644 --- a/include/modules/sndio.hpp +++ b/include/modules/sndio.hpp @@ -2,24 +2,23 @@ #include -#include - #include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Sndio : public ALabel { +class Sndio final : public ALabel { public: Sndio(const std::string &, const Json::Value &); virtual ~Sndio(); auto update() -> void override; auto set_desc(struct sioctl_desc *, unsigned int) -> void; auto put_val(unsigned int, unsigned int) -> void; - bool handleScroll(GdkEventScroll *) override; - bool handleToggle(GdkEventButton *const &) override; private: + bool handleScroll(double dx, double dy) override; + void handleToggle(int n_press, double dx, double dy) override; + auto connect_to_sndio() -> void; util::SleeperThread thread_; struct sioctl_hdl *hdl_; diff --git a/include/modules/sway/bar.hpp b/include/modules/sway/bar.hpp index fd48e5a35..68aaeff37 100644 --- a/include/modules/sway/bar.hpp +++ b/include/modules/sway/bar.hpp @@ -1,6 +1,4 @@ #pragma once -#include -#include #include "modules/sway/ipc/client.hpp" #include "util/SafeSignal.hpp" diff --git a/include/modules/sway/ipc/client.hpp b/include/modules/sway/ipc/client.hpp index a9a3e4e9d..5ca476a52 100644 --- a/include/modules/sway/ipc/client.hpp +++ b/include/modules/sway/ipc/client.hpp @@ -1,22 +1,14 @@ #pragma once -#include #include #include -#include - -#include -#include -#include -#include -#include #include "ipc.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules::sway { -class Ipc { +class Ipc final { public: Ipc(); ~Ipc(); @@ -27,15 +19,15 @@ class Ipc { std::string payload; }; - sigc::signal signal_event; - sigc::signal signal_cmd; + sigc::signal signal_event; + sigc::signal signal_cmd; void sendCmd(uint32_t type, const std::string &payload = ""); void subscribe(const std::string &payload); void handleEvent(); void setWorker(std::function &&func); - protected: + private: static inline const std::string ipc_magic_ = "i3-ipc"; static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8; diff --git a/include/modules/sway/language.hpp b/include/modules/sway/language.hpp index ea58c4f09..030e72940 100644 --- a/include/modules/sway/language.hpp +++ b/include/modules/sway/language.hpp @@ -1,20 +1,14 @@ #pragma once -#include #include -#include -#include - #include "ALabel.hpp" -#include "bar.hpp" -#include "client.hpp" #include "modules/sway/ipc/client.hpp" #include "util/json.hpp" namespace waybar::modules::sway { -class Language : public ALabel, public sigc::trackable { +class Language final : public ALabel, public sigc::trackable { public: Language(const std::string& id, const Json::Value& config); virtual ~Language() = default; diff --git a/include/modules/sway/mode.hpp b/include/modules/sway/mode.hpp index 44585355c..507537b6c 100644 --- a/include/modules/sway/mode.hpp +++ b/include/modules/sway/mode.hpp @@ -1,16 +1,12 @@ #pragma once -#include - #include "ALabel.hpp" -#include "bar.hpp" -#include "client.hpp" #include "modules/sway/ipc/client.hpp" #include "util/json.hpp" namespace waybar::modules::sway { -class Mode : public ALabel, public sigc::trackable { +class Mode final : public ALabel, public sigc::trackable { public: Mode(const std::string&, const Json::Value&); virtual ~Mode() = default; diff --git a/include/modules/sway/scratchpad.hpp b/include/modules/sway/scratchpad.hpp index 551cc8c8e..f43290887 100644 --- a/include/modules/sway/scratchpad.hpp +++ b/include/modules/sway/scratchpad.hpp @@ -1,18 +1,13 @@ #pragma once -#include - #include -#include #include "ALabel.hpp" -#include "bar.hpp" -#include "client.hpp" #include "modules/sway/ipc/client.hpp" #include "util/json.hpp" namespace waybar::modules::sway { -class Scratchpad : public ALabel { +class Scratchpad final : public ALabel { public: Scratchpad(const std::string&, const Json::Value&); virtual ~Scratchpad() = default; diff --git a/include/modules/sway/window.hpp b/include/modules/sway/window.hpp index 427c2e81a..6394146dd 100644 --- a/include/modules/sway/window.hpp +++ b/include/modules/sway/window.hpp @@ -1,18 +1,13 @@ #pragma once -#include - -#include - #include "AAppIconLabel.hpp" -#include "bar.hpp" #include "client.hpp" #include "modules/sway/ipc/client.hpp" #include "util/json.hpp" namespace waybar::modules::sway { -class Window : public AAppIconLabel, public sigc::trackable { +class Window final : public AAppIconLabel, public sigc::trackable { public: Window(const std::string&, const waybar::Bar&, const Json::Value&); virtual ~Window() = default; diff --git a/include/modules/sway/workspaces.hpp b/include/modules/sway/workspaces.hpp index 97f4e9503..9740df7cf 100644 --- a/include/modules/sway/workspaces.hpp +++ b/include/modules/sway/workspaces.hpp @@ -1,14 +1,8 @@ #pragma once -#include #include #include -#include -#include - -#include "AModule.hpp" -#include "bar.hpp" #include "client.hpp" #include "modules/sway/ipc/client.hpp" #include "util/json.hpp" @@ -16,11 +10,12 @@ namespace waybar::modules::sway { -class Workspaces : public AModule, public sigc::trackable { +class Workspaces final : public AModule, public sigc::trackable { public: Workspaces(const std::string&, const waybar::Bar&, const Json::Value&); ~Workspaces() override = default; auto update() -> void override; + operator Gtk::Widget&() override; private: static constexpr std::string_view workspace_switch_cmd_ = "workspace {} \"{}\""; @@ -41,7 +36,7 @@ class Workspaces : public AModule, public sigc::trackable { std::string getCycleWorkspace(std::vector::iterator, bool prev) const; uint16_t getWorkspaceIndex(const std::string& name) const; static std::string trimWorkspaceName(std::string); - bool handleScroll(GdkEventScroll* /*unused*/) override; + bool handleScroll(double dx, double dy) override; const Bar& bar_; std::vector workspaces_; diff --git a/include/modules/systemd_failed_units.hpp b/include/modules/systemd_failed_units.hpp index 9c3fbcee1..26ad44487 100644 --- a/include/modules/systemd_failed_units.hpp +++ b/include/modules/systemd_failed_units.hpp @@ -8,7 +8,7 @@ namespace waybar::modules { -class SystemdFailedUnits : public ALabel { +class SystemdFailedUnits final : public ALabel { public: SystemdFailedUnits(const std::string &, const Json::Value &); virtual ~SystemdFailedUnits(); diff --git a/include/modules/temperature.hpp b/include/modules/temperature.hpp index 5440df77b..6a34d9b08 100644 --- a/include/modules/temperature.hpp +++ b/include/modules/temperature.hpp @@ -1,15 +1,11 @@ #pragma once -#include - -#include - #include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Temperature : public ALabel { +class Temperature final : public ALabel { public: Temperature(const std::string&, const Json::Value&); virtual ~Temperature() = default; diff --git a/include/modules/ui.hpp b/include/modules/ui.hpp new file mode 100644 index 000000000..a50a0d92a --- /dev/null +++ b/include/modules/ui.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "AModule.hpp" + +namespace waybar::modules { + +class UI final : public AModule { + public: + UI(const std::string&, const std::string&, const Json::Value&); + virtual ~UI() = default; + operator Gtk::Widget&() override; + + private: + Glib::RefPtr uiWg_; +}; + +} // namespace waybar::modules diff --git a/include/modules/upower.hpp b/include/modules/upower.hpp index 60a276dbf..7f87bdd12 100644 --- a/include/modules/upower.hpp +++ b/include/modules/upower.hpp @@ -37,8 +37,9 @@ class UPower final : public AIconLabel { guint64 time_empty{0u}; gchar *icon_name{(char *)'\0'}; bool upDeviceValid{false}; - UpDeviceState state; - UpDeviceKind kind; + UpDeviceState state{UP_DEVICE_STATE_UNKNOWN}; + UpDeviceLevel level{UP_DEVICE_LEVEL_UNKNOWN}; + UpDeviceKind kind{UP_DEVICE_KIND_UNKNOWN}; char *nativePath{(char *)'\0'}; char *model{(char *)'\0'}; }; @@ -50,6 +51,7 @@ class UPower final : public AIconLabel { Glib::ustring label_markup_; std::mutex mutex_; Glib::RefPtr gtkTheme_; + const char *lastWarningLevel_{nullptr}; bool sleeping_; // Technical functions diff --git a/include/modules/user.hpp b/include/modules/user.hpp index bcb03da47..ffc01c28f 100644 --- a/include/modules/user.hpp +++ b/include/modules/user.hpp @@ -1,20 +1,15 @@ #pragma once -#include -#include -#include - #include "AIconLabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class User : public AIconLabel { +class User final : public AIconLabel { public: User(const std::string&, const Json::Value&); virtual ~User() = default; auto update() -> void override; - - bool handleToggle(GdkEventButton* const& e) override; + void handleToggle(int n_press, double dx, double dy) override; private: util::SleeperThread thread_; diff --git a/include/modules/wireplumber.hpp b/include/modules/wireplumber.hpp index 6255b95fd..f88c7133e 100644 --- a/include/modules/wireplumber.hpp +++ b/include/modules/wireplumber.hpp @@ -10,7 +10,7 @@ namespace waybar::modules { -class Wireplumber : public ALabel { +class Wireplumber final : public ALabel { public: Wireplumber(const std::string&, const Json::Value&); virtual ~Wireplumber(); @@ -30,7 +30,7 @@ class Wireplumber : public ALabel { static void onMixerChanged(waybar::modules::Wireplumber* self, uint32_t id); static void onDefaultNodesApiChanged(waybar::modules::Wireplumber* self); - bool handleScroll(GdkEventScroll* e) override; + bool handleScroll(double dx, double dy) override; WpCore* wp_core_; GPtrArray* apis_; diff --git a/include/util/SafeSignal.hpp b/include/util/SafeSignal.hpp index 458bc57ec..53f2cc37e 100644 --- a/include/util/SafeSignal.hpp +++ b/include/util/SafeSignal.hpp @@ -1,15 +1,10 @@ #pragma once #include -#include -#include #include #include #include -#include -#include -#include namespace waybar { @@ -35,7 +30,7 @@ struct SafeSignal : sigc::signal...)> { signal_t::emit(std::forward(args)...); } else { { - std::unique_lock lock(mutex_); + std::unique_lock lock{mutex_}; queue_.emplace(std::forward(args)...); } dp_.emit(); @@ -52,12 +47,12 @@ struct SafeSignal : sigc::signal...)> { using slot_t = decltype(std::declval().make_slot()); using arg_tuple_t = std::tuple...>; // ensure that unwrapped methods are not accessible - using signal_t::emit_reverse; + using signal_t::emit; using signal_t::make_slot; void handle_event() { - for (std::unique_lock lock(mutex_); !queue_.empty(); lock.lock()) { - auto args = queue_.front(); + for (std::unique_lock lock{mutex_}; !queue_.empty(); lock.lock()) { + auto args{queue_.front()}; queue_.pop(); lock.unlock(); std::apply(cached_fn_, args); @@ -67,9 +62,9 @@ struct SafeSignal : sigc::signal...)> { Glib::Dispatcher dp_; std::mutex mutex_; std::queue queue_; - const std::thread::id main_tid_ = std::this_thread::get_id(); + const std::thread::id main_tid_{std::this_thread::get_id()}; // cache functor for signal emission to avoid recreating it on each event - const slot_t cached_fn_ = make_slot(); + const slot_t cached_fn_{make_slot()}; }; } // namespace waybar diff --git a/include/util/audio_backend.hpp b/include/util/audio_backend.hpp index 2f53103e5..2d02d61e3 100644 --- a/include/util/audio_backend.hpp +++ b/include/util/audio_backend.hpp @@ -1,14 +1,10 @@ #pragma once #include -#include #include #include -#include #include -#include -#include #include "util/backend_common.hpp" @@ -93,4 +89,4 @@ class AudioBackend { bool isBluetooth(); }; -} // namespace waybar::util \ No newline at end of file +} // namespace waybar::util diff --git a/include/util/backend_common.hpp b/include/util/backend_common.hpp index dda6ac57b..6f6f348bd 100644 --- a/include/util/backend_common.hpp +++ b/include/util/backend_common.hpp @@ -1,10 +1,8 @@ #pragma once -#include "AModule.hpp" - namespace waybar::util { const static auto NOOP = []() {}; enum class ChangeType : char { Increase, Decrease }; -} // namespace waybar::util \ No newline at end of file +} // namespace waybar::util diff --git a/include/util/backlight_backend.hpp b/include/util/backlight_backend.hpp index eb42d3ccf..5b39c334d 100644 --- a/include/util/backlight_backend.hpp +++ b/include/util/backlight_backend.hpp @@ -1,14 +1,6 @@ #pragma once #include -#include - -#include -#include -#include -#include -#include -#include #include "giomm/dbusproxy.h" #include "util/backend_common.hpp" @@ -42,9 +34,9 @@ class BacklightDevice { private: std::string name_; - int actual_ = 1; - int max_ = 1; - bool powered_ = true; + int actual_{1}; + int max_{1}; + bool powered_{true}; }; class BacklightBackend { @@ -81,7 +73,7 @@ class BacklightBackend { Glib::RefPtr login_proxy_; - static constexpr int EPOLL_MAX_EVENTS = 16; + static constexpr int EPOLL_MAX_EVENTS{16}; }; } // namespace waybar::util diff --git a/include/util/css_reload_helper.hpp b/include/util/css_reload_helper.hpp index 032b23826..b5d6ba5dc 100644 --- a/include/util/css_reload_helper.hpp +++ b/include/util/css_reload_helper.hpp @@ -1,14 +1,14 @@ #pragma once +#include +#include +#include + #include #include #include #include -#include "giomm/file.h" -#include "giomm/filemonitor.h" -#include "glibmm/refptr.h" - struct pollfd; namespace waybar { @@ -37,7 +37,7 @@ class CssReloadHelper { void handleFileChange(Glib::RefPtr const& file, Glib::RefPtr const& other_type, - Gio::FileMonitorEvent event_type); + Gio::FileMonitor::Event event_type); private: std::string m_cssFile; diff --git a/include/util/format.hpp b/include/util/format.hpp index c8ed837a5..2321fdbff 100644 --- a/include/util/format.hpp +++ b/include/util/format.hpp @@ -16,12 +16,12 @@ class pow_format { namespace fmt { template <> struct formatter { - char spec = 0; - int width = 0; + char spec{0}; + int width{0}; template constexpr auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - auto it = ctx.begin(), end = ctx.end(); + auto it{ctx.begin()}, end{ctx.end()}; if (it != end && *it == ':') ++it; if (it && (*it == '>' || *it == '<' || *it == '=')) { spec = *it; @@ -46,21 +46,21 @@ struct formatter { template auto format(const pow_format& s, FormatContext& ctx) const -> decltype(ctx.out()) { - const char* units[] = {"", "k", "M", "G", "T", "P", nullptr}; + const char* units[]{"", "k", "M", "G", "T", "P", nullptr}; - auto base = s.binary_ ? 1024ull : 1000ll; - auto fraction = (double)s.val_; + auto base{s.binary_ ? 1024ull : 1000ll}; + auto fraction{(double)s.val_}; int pow; for (pow = 0; units[pow + 1] != nullptr && fraction / base >= 1; ++pow) { fraction /= base; } - auto number_width = 5 // coeff in {:.1f} format - + s.binary_; // potential 4th digit before the decimal point - auto max_width = number_width + 1 // prefix from units array - + s.binary_ // for the 'i' in GiB. - + s.unit_.length(); + auto number_width{5 // coeff in {:.1f} format + + s.binary_}; // potential 4th digit before the decimal point + auto max_width{number_width + 1 // prefix from units array + + s.binary_ // for the 'i' in GiB. + + s.unit_.length()}; const char* format; std::string string; diff --git a/include/util/gtk_icon.hpp b/include/util/gtk_icon.hpp deleted file mode 100644 index 44555f652..000000000 --- a/include/util/gtk_icon.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include - -#include -#include - -class DefaultGtkIconThemeWrapper { - private: - static std::mutex default_theme_mutex; - - public: - static bool has_icon(const std::string&); - static Glib::RefPtr load_icon(const char*, int, Gtk::IconLookupFlags); -}; diff --git a/include/util/pipewire/pipewire_backend.hpp b/include/util/pipewire/pipewire_backend.hpp index 90fb2bb22..8d80f4d5d 100644 --- a/include/util/pipewire/pipewire_backend.hpp +++ b/include/util/pipewire/pipewire_backend.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -9,7 +10,7 @@ namespace waybar::util::PipewireBackend { -class PipewireBackend { +class PipewireBackend final { private: pw_thread_loop* mainloop_; pw_context* context_; @@ -27,7 +28,7 @@ class PipewireBackend { struct PrivateConstructorTag {}; public: - sigc::signal privacy_nodes_changed_signal_event; + sigc::signal privacy_nodes_changed_signal_event; std::unordered_map privacy_nodes; std::mutex mutex_; diff --git a/include/util/pipewire/privacy_node_info.hpp b/include/util/pipewire/privacy_node_info.hpp index 7b8df0181..8715c009b 100644 --- a/include/util/pipewire/privacy_node_info.hpp +++ b/include/util/pipewire/privacy_node_info.hpp @@ -1,11 +1,8 @@ #pragma once +#include #include -#include - -#include "util/gtk_icon.hpp" - namespace waybar::util::PipewireBackend { enum PrivacyNodeType { @@ -15,31 +12,30 @@ enum PrivacyNodeType { PRIVACY_NODE_TYPE_AUDIO_OUTPUT }; -class PrivacyNodeInfo { +class PrivacyNodeInfo final { public: - PrivacyNodeType type = PRIVACY_NODE_TYPE_NONE; uint32_t id; - uint32_t client_id; + PrivacyNodeType type = PRIVACY_NODE_TYPE_NONE; enum pw_node_state state = PW_NODE_STATE_IDLE; + void *data; std::string media_class; - std::string media_name; - std::string node_name; - std::string application_name; - - std::string pipewire_access_portal_app_id; - std::string application_icon_name; - struct spa_hook object_listener; struct spa_hook proxy_listener; - void *data; - std::string getName(); - std::string getIconName(); - + std::string getIconName(const Glib::RefPtr theme); // Handlers for PipeWire events void handleProxyEventDestroy(); void handleNodeEventInfo(const struct pw_node_info *info); + + private: + uint32_t client_id; + std::string media_name; + std::string node_name; + std::string application_name; + + std::string pipewire_access_portal_app_id; + std::string application_icon_name; }; } // namespace waybar::util::PipewireBackend diff --git a/include/util/portal.hpp b/include/util/portal.hpp index 236191691..05458c7f2 100644 --- a/include/util/portal.hpp +++ b/include/util/portal.hpp @@ -19,7 +19,7 @@ class Portal : private DBus::Proxy { void refreshAppearance(); Appearance getAppearance(); - typedef sigc::signal type_signal_appearance_changed; + typedef sigc::signal type_signal_appearance_changed; type_signal_appearance_changed signal_appearance_changed() { return m_signal_appearance_changed; } private: diff --git a/include/util/regex_collection.hpp b/include/util/regex_collection.hpp index 30d26d4a8..3da487f52 100644 --- a/include/util/regex_collection.hpp +++ b/include/util/regex_collection.hpp @@ -5,7 +5,6 @@ #include #include #include -#include namespace waybar::util { diff --git a/include/util/rfkill.hpp b/include/util/rfkill.hpp index f620db534..8021eb4fd 100644 --- a/include/util/rfkill.hpp +++ b/include/util/rfkill.hpp @@ -2,12 +2,10 @@ #include #include -#include -#include namespace waybar::util { -class Rfkill : public sigc::trackable { +class Rfkill final : public sigc::trackable { public: Rfkill(enum rfkill_type rfkill_type); ~Rfkill(); @@ -17,8 +15,8 @@ class Rfkill : public sigc::trackable { private: enum rfkill_type rfkill_type_; - bool state_ = false; - int fd_ = -1; + bool state_{false}; + int fd_{-1}; bool on_event(Glib::IOCondition cond); }; diff --git a/meson.build b/meson.build index 726d492bb..4e8bd8b4e 100644 --- a/meson.build +++ b/meson.build @@ -1,10 +1,10 @@ project( 'waybar', 'cpp', 'c', - version: '0.11.0', + version: '4.1.0', license: 'MIT', - meson_version: '>= 0.59.0', + meson_version: '>= 1.3.0', default_options : [ - 'cpp_std=c++20', + 'cpp_std=c++23', 'buildtype=release', 'default_library=static' ], @@ -67,17 +67,16 @@ is_freebsd = host_machine.system() == 'freebsd' is_netbsd = host_machine.system() == 'netbsd' is_openbsd = host_machine.system() == 'openbsd' -thread_dep = dependency('threads') fmt = dependency('fmt', version : ['>=8.1.1'], fallback : ['fmt', 'fmt_dep']) spdlog = dependency('spdlog', version : ['>=1.10.0'], fallback : ['spdlog', 'spdlog_dep'], default_options : ['external_fmt=enabled', 'std_format=disabled', 'tests=disabled']) +jsoncpp = dependency('jsoncpp', version : ['>=1.9.6'], fallback : ['jsoncpp', 'jsoncpp_dep']) wayland_client = dependency('wayland-client') wayland_cursor = dependency('wayland-cursor') wayland_protos = dependency('wayland-protocols') -gtkmm = dependency('gtkmm-3.0', version : ['>=3.22.0']) +gtkmm = dependency('gtkmm-4.0', version : ['>=4.16.0']) dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk')) -giounix = dependency('gio-unix-2.0') -jsoncpp = dependency('jsoncpp', version : ['>=1.9.2'], fallback : ['jsoncpp', 'jsoncpp_dep']) -sigcpp = dependency('sigc++-2.0') +giounix = dependency('gio-unix-2.0', version: ['>=2.76.4']) +sigcpp = dependency('sigc++-3.0', version: ['>=3.4.0']) libinotify = dependency('libinotify', required: false) libepoll = dependency('epoll-shim', required: false) libinput = dependency('libinput', required: get_option('libinput')) @@ -106,9 +105,11 @@ if libsndio.found() endif endif -gtk_layer_shell = dependency('gtk-layer-shell-0', version: ['>=0.9.0'], - default_options: ['introspection=false', 'vapi=false'], - fallback: ['gtk-layer-shell', 'gtk_layer_shell']) +gtk_layer_shell = dependency('gtk4-layer-shell-0', + version : ['>=1.0.3'], + default_options : ['introspection=false', 'vapi=false'], + fallback : ['gtk4-layer-shell', 'gtk_layer_shell']) + systemd = dependency('systemd', required: get_option('systemd')) cpp_lib_chrono = compiler.compute_int('__cpp_lib_chrono', prefix : '#include ') @@ -176,15 +177,13 @@ src_files = files( 'src/config.cpp', 'src/group.cpp', 'src/util/portal.cpp', - 'src/util/enum.cpp', 'src/util/prepare_for_sleep.cpp', 'src/util/ustring_clen.cpp', 'src/util/sanitize_str.cpp', 'src/util/rewrite_string.cpp', - 'src/util/gtk_icon.cpp', 'src/util/regex_collection.cpp', - 'src/util/css_reload_helper.cpp' -) + 'src/util/css_reload_helper.cpp', + 'src/modules/ui.cpp') man_files = files( 'man/waybar-custom.5.scd', @@ -249,88 +248,68 @@ elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd endif endif -if true - add_project_arguments('-DHAVE_SWAY', language: 'cpp') - src_files += files( - 'src/modules/sway/ipc/client.cpp', - 'src/modules/sway/bar.cpp', - 'src/modules/sway/mode.cpp', - 'src/modules/sway/language.cpp', - 'src/modules/sway/window.cpp', - 'src/modules/sway/workspaces.cpp', - 'src/modules/sway/scratchpad.cpp' - ) - man_files += files( - 'man/waybar-sway-language.5.scd', - 'man/waybar-sway-mode.5.scd', - 'man/waybar-sway-scratchpad.5.scd', - 'man/waybar-sway-window.5.scd', - 'man/waybar-sway-workspaces.5.scd', - ) -endif - -if true - add_project_arguments('-DHAVE_WLR_TASKBAR', language: 'cpp') - src_files += files('src/modules/wlr/taskbar.cpp') - man_files += files('man/waybar-wlr-taskbar.5.scd') -endif - -if true - add_project_arguments('-DHAVE_RIVER', language: 'cpp') - src_files += files( - 'src/modules/river/layout.cpp', - 'src/modules/river/mode.cpp', - 'src/modules/river/tags.cpp', - 'src/modules/river/window.cpp', - ) - man_files += files( - 'man/waybar-river-layout.5.scd', - 'man/waybar-river-mode.5.scd', - 'man/waybar-river-tags.5.scd', - 'man/waybar-river-window.5.scd', - ) -endif - -if true - add_project_arguments('-DHAVE_DWL', language: 'cpp') - src_files += files('src/modules/dwl/tags.cpp') - src_files += files('src/modules/dwl/window.cpp') - man_files += files('man/waybar-dwl-tags.5.scd') - man_files += files('man/waybar-dwl-window.5.scd') -endif - -if true - add_project_arguments('-DHAVE_HYPRLAND', language: 'cpp') - src_files += files( - 'src/modules/hyprland/backend.cpp', - 'src/modules/hyprland/language.cpp', - 'src/modules/hyprland/submap.cpp', - 'src/modules/hyprland/window.cpp', - 'src/modules/hyprland/workspace.cpp', - 'src/modules/hyprland/workspaces.cpp', - 'src/modules/hyprland/windowcreationpayload.cpp', - ) - man_files += files( - 'man/waybar-hyprland-language.5.scd', - 'man/waybar-hyprland-submap.5.scd', - 'man/waybar-hyprland-window.5.scd', - 'man/waybar-hyprland-workspaces.5.scd', - ) -endif +add_project_arguments('-DHAVE_SWAY', language: 'cpp') +src_files += files('src/modules/sway/ipc/client.cpp', + 'src/modules/sway/bar.cpp', + 'src/modules/sway/mode.cpp', + 'src/modules/sway/language.cpp', + 'src/modules/sway/window.cpp', + 'src/modules/sway/workspaces.cpp', + 'src/modules/sway/scratchpad.cpp') + +man_files += files('man/waybar-sway-language.5.scd', + 'man/waybar-sway-mode.5.scd', + 'man/waybar-sway-scratchpad.5.scd', + 'man/waybar-sway-window.5.scd', + 'man/waybar-sway-workspaces.5.scd') +if 1 == 0 +add_project_arguments('-DHAVE_WLR_TASKBAR', language: 'cpp') +src_files += files('src/modules/wlr/taskbar.cpp') +man_files += files('man/waybar-wlr-taskbar.5.scd') + +add_project_arguments('-DHAVE_RIVER', language: 'cpp') +src_files += files('src/modules/river/layout.cpp', + 'src/modules/river/mode.cpp', + 'src/modules/river/tags.cpp', + 'src/modules/river/window.cpp') +man_files += files('man/waybar-river-layout.5.scd', + 'man/waybar-river-mode.5.scd', + 'man/waybar-river-tags.5.scd', + 'man/waybar-river-window.5.scd') +endif +add_project_arguments('-DHAVE_DWL', language: 'cpp') +src_files += files('src/modules/dwl/tags.cpp', + 'src/modules/dwl/window.cpp') +man_files += files('man/waybar-dwl-tags.5.scd', + 'man/waybar-dwl-window.5.scd') +if 1 == 0 +add_project_arguments('-DHAVE_HYPRLAND', language: 'cpp') +src_files += files('src/modules/hyprland/backend.cpp', + 'src/modules/hyprland/language.cpp', + 'src/modules/hyprland/submap.cpp', + 'src/modules/hyprland/window.cpp', + 'src/modules/hyprland/workspace.cpp', + 'src/modules/hyprland/workspaces.cpp', + 'src/modules/hyprland/windowcreationpayload.cpp') +man_files += files('man/waybar-hyprland-language.5.scd', + 'man/waybar-hyprland-submap.5.scd', + 'man/waybar-hyprland-window.5.scd', + 'man/waybar-hyprland-workspaces.5.scd') if get_option('niri') - add_project_arguments('-DHAVE_NIRI', language: 'cpp') - src_files += files( - 'src/modules/niri/backend.cpp', - 'src/modules/niri/language.cpp', - 'src/modules/niri/window.cpp', - 'src/modules/niri/workspaces.cpp', - ) - man_files += files( - 'man/waybar-niri-language.5.scd', - 'man/waybar-niri-window.5.scd', - 'man/waybar-niri-workspaces.5.scd', - ) +add_project_arguments('-DHAVE_NIRI', language: 'cpp') +src_files += files( + 'src/modules/niri/backend.cpp', + 'src/modules/niri/language.cpp', + 'src/modules/niri/window.cpp', + 'src/modules/niri/workspaces.cpp', +) +man_files += files( + 'man/waybar-niri-language.5.scd', + 'man/waybar-niri-window.5.scd', + 'man/waybar-niri-workspaces.5.scd', +) +endif endif if libnl.found() and libnlgen.found() @@ -357,7 +336,6 @@ if (upower_glib.found() and not get_option('logind').disabled()) man_files += files('man/waybar-upower.5.scd') endif - if pipewire.found() add_project_arguments('-DHAVE_PIPEWIRE', language: 'cpp') src_files += files( @@ -371,7 +349,7 @@ endif if playerctl.found() add_project_arguments('-DHAVE_MPRIS', language: 'cpp') - src_files += files('src/modules/mpris/mpris.cpp') + src_files += files('src/modules/mpris.cpp') man_files += files('man/waybar-mpris.5.scd') endif @@ -400,30 +378,25 @@ if libwireplumber.found() man_files += files('man/waybar-wireplumber.5.scd') endif +if 1 == 0 if dbusmenu_gtk.found() add_project_arguments('-DHAVE_DBUSMENU', language: 'cpp') src_files += files( 'src/modules/sni/tray.cpp', 'src/modules/sni/watcher.cpp', 'src/modules/sni/host.cpp', - 'src/modules/sni/item.cpp' - ) - man_files += files( - 'man/waybar-tray.5.scd', - ) + 'src/modules/sni/item.cpp') + man_files += files('man/waybar-tray.5.scd') +endif endif if libudev.found() and (is_linux or libepoll.found()) add_project_arguments('-DHAVE_LIBUDEV', language: 'cpp') - src_files += files( - 'src/modules/backlight.cpp', - 'src/modules/backlight_slider.cpp', - 'src/util/backlight_backend.cpp', - ) - man_files += files( - 'man/waybar-backlight.5.scd', - 'man/waybar-backlight-slider.5.scd', - ) + src_files += files('src/modules/backlight.cpp', + 'src/modules/backlight_slider.cpp', + 'src/util/backlight_backend.cpp') + man_files += files('man/waybar-backlight.5.scd', + 'man/waybar-backlight-slider.5.scd') endif if libevdev.found() and (is_linux or libepoll.found()) and libinput.found() and (is_linux or libinotify.found()) @@ -435,13 +408,9 @@ endif if libmpdclient.found() add_project_arguments('-DHAVE_LIBMPDCLIENT', language: 'cpp') - src_files += files( - 'src/modules/mpd/mpd.cpp', - 'src/modules/mpd/state.cpp', - ) - man_files += files( - 'man/waybar-mpd.5.scd', - ) + src_files += files('src/modules/mpd/mpd.cpp', + 'src/modules/mpd/state.cpp') + man_files += files('man/waybar-mpd.5.scd') endif if libsndio.found() @@ -452,9 +421,7 @@ endif if get_option('rfkill').enabled() and is_linux add_project_arguments('-DWANT_RFKILL', language: 'cpp') - src_files += files( - 'src/util/rfkill.cpp' - ) + src_files += files('src/util/rfkill.cpp') endif if have_chrono_timezones @@ -472,13 +439,9 @@ endif if get_option('experimental') add_project_arguments('-DHAVE_WLR_WORKSPACES', language: 'cpp') - src_files += files( - 'src/modules/wlr/workspace_manager.cpp', - 'src/modules/wlr/workspace_manager_binding.cpp', - ) - man_files += files( - 'man/waybar-wlr-workspaces.5.scd', - ) + src_files += files('src/modules/wlr/workspace_manager.cpp', + 'src/modules/wlr/workspace_manager_binding.cpp') + man_files += files('man/waybar-wlr-workspaces.5.scd') endif cava = dependency('cava', @@ -495,43 +458,36 @@ endif subdir('protocol') -app_resources = [] -subdir('resources/icons') - executable( 'waybar', - [src_files, app_resources], + [src_files], dependencies: [ - thread_dep, - client_protos, - wayland_client, - fmt, - spdlog, + gtk_layer_shell, + gtkmm, + giounix, sigcpp, + libevdev, + libudev, jsoncpp, + wayland_client, wayland_cursor, - gtkmm, - dbusmenu_gtk, - giounix, + client_protos, + spdlog, + xkbregistry, + cava, + libinotify, + libepoll, libinput, libnl, libnlgen, - upower_glib, - pipewire, playerctl, libpulse, + libmpdclient, libjack, libwireplumber, - libudev, - libinotify, - libepoll, - libmpdclient, - libevdev, - gtk_layer_shell, libsndio, - tz_dep, - xkbregistry, - cava + upower_glib, + pipewire ], include_directories: inc_dirs, install: true, @@ -543,6 +499,11 @@ install_data( install_dir: sysconfdir / 'xdg/waybar' ) +install_subdir( + 'resources/ui', + install_dir: sysconfdir / 'xdg/waybar' +) + scdoc = dependency('scdoc', version: '>=1.9.2', native: true, required: get_option('man-pages')) if scdoc.found() diff --git a/resources/ui/ui-power.xml b/resources/ui/ui-power.xml new file mode 100644 index 000000000..6b45b780c --- /dev/null +++ b/resources/ui/ui-power.xml @@ -0,0 +1,43 @@ + + + + +
+ + Suspend + ui-power.doAction + loginctl suspend + + + Hibernate + ui-power.doAction + loginctl hibernate + + + Shutdown + ui-power.doAction + loginctl poweroff + +
+
+ + Reboot + ui-power.doAction + loginctl reboot + +
+
+ + + waybar-power-menu + Power menu + + true + false + true + false + true + GTK_ARROW_NONE + label + +
diff --git a/src/AAppIconLabel.cpp b/src/AAppIconLabel.cpp index 3f47eff18..32cc9c913 100644 --- a/src/AAppIconLabel.cpp +++ b/src/AAppIconLabel.cpp @@ -1,15 +1,11 @@ #include "AAppIconLabel.hpp" -#include #include #include #include #include #include -#include - -#include "util/gtk_icon.hpp" namespace waybar { @@ -17,6 +13,9 @@ AAppIconLabel::AAppIconLabel(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) : AIconLabel(config, name, id, format, interval, ellipsize, enable_click, enable_scroll) { + // Get current theme + gtkTheme_ = Gtk::IconTheme::get_for_display(label_.get_display()); + // Icon size if (config["icon-size"].isUInt()) { app_icon_size_ = config["icon-size"].asUInt(); @@ -63,13 +62,13 @@ std::optional getDesktopFilePath(const std::string& app_identifier, return {}; } - const auto data_dirs = Glib::get_system_data_dirs(); + const auto data_dirs{Glib::get_system_data_dirs()}; for (const auto& data_dir : data_dirs) { - const auto data_app_dir = data_dir + "/applications/"; - auto desktop_file_suffix = app_identifier + ".desktop"; + const auto data_app_dir{data_dir + "/applications/"}; + auto desktop_file_suffix{app_identifier + ".desktop"}; // searching for file by suffix catches cases like terminal emulator "foot" where class is // "footclient" and desktop file is named "org.codeberg.dnkl.footclient.desktop" - auto desktop_file_path = getFileBySuffix(data_app_dir, desktop_file_suffix, true); + auto desktop_file_path{getFileBySuffix(data_app_dir, desktop_file_suffix, true)}; // "true" argument allows checking for lowercase - this catches cases where class name is // "LibreWolf" and desktop file is named "librewolf.desktop" if (desktop_file_path.has_value()) { @@ -87,32 +86,33 @@ std::optional getDesktopFilePath(const std::string& app_identifier, } std::optional getIconName(const std::string& app_identifier, - const std::string& alternative_app_identifier) { - const auto desktop_file_path = getDesktopFilePath(app_identifier, alternative_app_identifier); + const std::string& alternative_app_identifier, + const Glib::RefPtr gtkTheme) { + const auto desktop_file_path{getDesktopFilePath(app_identifier, alternative_app_identifier)}; if (!desktop_file_path.has_value()) { // Try some heuristics to find a matching icon - if (DefaultGtkIconThemeWrapper::has_icon(app_identifier)) { + if (gtkTheme->has_icon(app_identifier)) { return app_identifier; } - auto app_identifier_desktop = app_identifier + "-desktop"; - if (DefaultGtkIconThemeWrapper::has_icon(app_identifier_desktop)) { + const auto app_identifier_desktop{app_identifier + "-desktop"}; + if (gtkTheme->has_icon(app_identifier_desktop)) { return app_identifier_desktop; } - auto first_space = app_identifier.find_first_of(' '); + const auto first_space{app_identifier.find_first_of(' ')}; if (first_space != std::string::npos) { - auto first_word = toLowerCase(app_identifier.substr(0, first_space)); - if (DefaultGtkIconThemeWrapper::has_icon(first_word)) { + const auto first_word{toLowerCase(app_identifier.substr(0, first_space))}; + if (gtkTheme->has_icon(first_word)) { return first_word; } } - const auto first_dash = app_identifier.find_first_of('-'); + const auto first_dash{app_identifier.find_first_of('-')}; if (first_dash != std::string::npos) { - auto first_word = toLowerCase(app_identifier.substr(0, first_dash)); - if (DefaultGtkIconThemeWrapper::has_icon(first_word)) { + const auto first_word{toLowerCase(app_identifier.substr(0, first_dash))}; + if (gtkTheme->has_icon(first_word)) { return first_word; } } @@ -121,15 +121,15 @@ std::optional getIconName(const std::string& app_identifier, } try { - Glib::KeyFile desktop_file; - desktop_file.load_from_file(desktop_file_path.value()); - return desktop_file.get_string("Desktop Entry", "Icon"); + Glib::RefPtr desktop_file; + desktop_file->load_from_file(desktop_file_path.value()); + return desktop_file->get_string("Desktop Entry", "Icon"); } catch (Glib::FileError& error) { spdlog::warn("Error while loading desktop file {}: {}", desktop_file_path.value(), - error.what().c_str()); + error.what()); } catch (Glib::KeyFileError& error) { spdlog::warn("Error while loading desktop file {}: {}", desktop_file_path.value(), - error.what().c_str()); + error.what()); } return {}; } @@ -140,7 +140,7 @@ void AAppIconLabel::updateAppIconName(const std::string& app_identifier, return; } - const auto icon_name = getIconName(app_identifier, alternative_app_identifier); + const auto icon_name{getIconName(app_identifier, alternative_app_identifier, gtkTheme_)}; if (icon_name.has_value()) { app_icon_name_ = icon_name.value(); } else { @@ -155,16 +155,10 @@ void AAppIconLabel::updateAppIcon() { if (app_icon_name_.empty()) { image_.set_visible(false); } else if (app_icon_name_.front() == '/') { - auto pixbuf = Gdk::Pixbuf::create_from_file(app_icon_name_); - int scaled_icon_size = app_icon_size_ * image_.get_scale_factor(); - pixbuf = Gdk::Pixbuf::create_from_file(app_icon_name_, scaled_icon_size, scaled_icon_size); - - auto surface = Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image_.get_scale_factor(), - image_.get_window()); - image_.set(surface); + image_.set(app_icon_name_); image_.set_visible(true); } else { - image_.set_from_icon_name(app_icon_name_, Gtk::ICON_SIZE_INVALID); + image_.set_from_icon_name(app_icon_name_); image_.set_visible(true); } } diff --git a/src/AIconLabel.cpp b/src/AIconLabel.cpp index d7ee666e6..963805d03 100644 --- a/src/AIconLabel.cpp +++ b/src/AIconLabel.cpp @@ -1,14 +1,11 @@ #include "AIconLabel.hpp" -#include - namespace waybar { AIconLabel::AIconLabel(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) : ALabel(config, name, id, format, interval, ellipsize, enable_click, enable_scroll) { - event_box_.remove(); label_.unset_name(); label_.get_style_context()->remove_class(MODULE_CLASS); box_.get_style_context()->add_class(MODULE_CLASS); @@ -17,16 +14,14 @@ AIconLabel::AIconLabel(const Json::Value &config, const std::string &name, const box_.get_style_context()->add_class(id); } - box_.set_orientation(Gtk::Orientation::ORIENTATION_HORIZONTAL); + box_.set_orientation(Gtk::Orientation::HORIZONTAL); box_.set_name(name); int spacing = config_["icon-spacing"].isInt() ? config_["icon-spacing"].asInt() : 8; box_.set_spacing(spacing); - box_.add(image_); - box_.add(label_); - - event_box_.add(box_); + box_.append(image_); + box_.append(label_); } auto AIconLabel::update() -> void { @@ -38,4 +33,6 @@ bool AIconLabel::iconEnabled() const { return config_["icon"].isBool() ? config_["icon"].asBool() : false; } +AIconLabel::operator Gtk::Widget &() { return box_; }; + } // namespace waybar diff --git a/src/ALabel.cpp b/src/ALabel.cpp index 467572f18..b174aaa36 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -1,39 +1,28 @@ #include "ALabel.hpp" -#include - -#include -#include -#include - -#include "config.hpp" - namespace waybar { ALabel::ALabel(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() || config["menu"].isString() || enable_click, - enable_scroll), - format_(config_["format"].isString() ? config_["format"].asString() : format), - interval_(config_["interval"] == "once" + : 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::max() : std::chrono::seconds( - config_["interval"].isUInt() ? config_["interval"].asUInt() : interval)), - default_format_(format_) { + config_["interval"].isUInt() ? config_["interval"].asUInt() : interval)}, + default_format_{format_} { label_.set_name(name); if (!id.empty()) { label_.get_style_context()->add_class(id); } label_.get_style_context()->add_class(MODULE_CLASS); - event_box_.add(label_); if (config_["max-length"].isUInt()) { label_.set_max_width_chars(config_["max-length"].asInt()); - label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); + label_.set_ellipsize(Pango::EllipsizeMode::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_ellipsize(Pango::EllipsizeMode::END); label_.set_single_line_mode(true); } @@ -41,17 +30,18 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st label_.set_width_chars(config_["min-length"].asUInt()); } - uint rotate = 0; - + uint rotate{0}; + // gtk4 todo + /* if (config_["rotate"].isUInt()) { rotate = config["rotate"].asUInt(); if (not(rotate == 0 || rotate == 90 || rotate == 180 || rotate == 270)) spdlog::warn("'rotate' is only supported in 90 degree increments {} is not valid.", rotate); label_.set_angle(rotate); - } + }*/ if (config_["align"].isDouble()) { - auto align = config_["align"].asFloat(); + auto align{config_["align"].asFloat()}; if (rotate == 90 || rotate == 270) { label_.set_yalign(align); } else { @@ -59,71 +49,24 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st } } - // If a GTKMenu is requested in the config - if (config_["menu"].isString()) { - // Create the GTKMenu widget - 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()) { - throw std::runtime_error("Failed to open file: " + menuFile); - } - std::stringstream fileContent; - fileContent << file.rdbuf(); - GtkBuilder* builder = gtk_builder_new(); - - // Make the GtkBuilder and check for errors in his parsing - if (gtk_builder_add_from_string(builder, fileContent.str().c_str(), -1, nullptr) == 0U) { - throw std::runtime_error("Error found in the file " + menuFile); - } - - menu_ = gtk_builder_get_object(builder, "menu"); - if (menu_ == nullptr) { - throw std::runtime_error("Failed to get 'menu' object from GtkBuilder"); - } - submenus_ = std::map(); - menuActionsMap_ = std::map(); - - // Linking actions to the GTKMenu based on - for (Json::Value::const_iterator it = config_["menu-actions"].begin(); - it != config_["menu-actions"].end(); ++it) { - std::string key = it.key().asString(); - submenus_[key] = GTK_MENU_ITEM(gtk_builder_get_object(builder, key.c_str())); - menuActionsMap_[key] = it->asString(); - g_signal_connect(submenus_[key], "activate", G_CALLBACK(handleGtkMenuEvent), - (gpointer)menuActionsMap_[key].c_str()); - } - } catch (std::runtime_error& e) { - spdlog::warn("Error while creating the menu : {}. Menu popup not activated.", e.what()); - } - } - if (config_["justify"].isString()) { auto justify_str = config_["justify"].asString(); if (justify_str == "left") { - label_.set_justify(Gtk::Justification::JUSTIFY_LEFT); + label_.set_justify(Gtk::Justification::LEFT); } else if (justify_str == "right") { - label_.set_justify(Gtk::Justification::JUSTIFY_RIGHT); + label_.set_justify(Gtk::Justification::RIGHT); } else if (justify_str == "center") { - label_.set_justify(Gtk::Justification::JUSTIFY_CENTER); + label_.set_justify(Gtk::Justification::CENTER); } } + + AModule::bindEvents(*this); } auto ALabel::update() -> void { AModule::update(); } std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_t max) { - auto format_icons = config_["format-icons"]; + 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]; @@ -132,9 +75,9 @@ std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_ } } if (format_icons.isArray()) { - auto size = format_icons.size(); + auto size{format_icons.size()}; if (size != 0U) { - auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1); + auto idx{std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1)}; format_icons = format_icons[idx]; } } @@ -146,9 +89,9 @@ std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_ std::string ALabel::getIcon(uint16_t percentage, const std::vector& alts, uint16_t max) { - auto format_icons = config_["format-icons"]; + auto format_icons{config_["format-icons"]}; if (format_icons.isObject()) { - std::string _alt = "default"; + std::string _alt{"default"}; for (const auto& alt : alts) { if (!alt.empty() && (format_icons[alt].isString() || format_icons[alt].isArray())) { _alt = alt; @@ -158,9 +101,9 @@ std::string ALabel::getIcon(uint16_t percentage, const std::vector& format_icons = format_icons[_alt]; } if (format_icons.isArray()) { - auto size = format_icons.size(); + auto size{format_icons.size()}; if (size != 0U) { - auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1); + auto idx{std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1)}; format_icons = format_icons[idx]; } } @@ -170,8 +113,9 @@ std::string ALabel::getIcon(uint16_t percentage, const std::vector& return ""; } -bool waybar::ALabel::handleToggle(GdkEventButton* const& e) { - if (config_["format-alt-click"].isUInt() && e->button == config_["format-alt-click"].asUInt()) { +void waybar::ALabel::handleToggle(int n_press, double dx, double dy) { + if (config_["format-alt-click"].isUInt() && + controllClick_->get_current_button() == config_["format-alt-click"].asUInt()) { alt_ = !alt_; if (alt_ && config_["format-alt"].isString()) { format_ = config_["format-alt"].asString(); @@ -179,11 +123,8 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) { format_ = default_format_; } } - return AModule::handleToggle(e); -} -void ALabel::handleGtkMenuEvent(GtkMenuItem* /*menuitem*/, gpointer data) { - waybar::util::command::res res = waybar::util::command::exec((char*)data, "GtkMenu"); + AModule::handleToggle(n_press, dx, dy); } std::string ALabel::getState(uint8_t value, bool lesser) { @@ -193,7 +134,7 @@ std::string ALabel::getState(uint8_t value, bool lesser) { // Get current state std::vector> states; if (config_["states"].isObject()) { - for (auto it = config_["states"].begin(); it != config_["states"].end(); ++it) { + 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()); } @@ -215,4 +156,6 @@ std::string ALabel::getState(uint8_t value, bool lesser) { return valid_state; } +ALabel::operator Gtk::Widget&() { return label_; }; + } // namespace waybar diff --git a/src/AModule.cpp b/src/AModule.cpp index c180b4801..d4a0c8958 100644 --- a/src/AModule.cpp +++ b/src/AModule.cpp @@ -1,13 +1,6 @@ #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, @@ -15,12 +8,14 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std:: : name_(name), config_(config), isTooltip{config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true}, - distance_scrolled_y_(0.0), - distance_scrolled_x_(0.0) { + enableClick_{enable_click}, + enableScroll_{enable_scroll}, + curDefault{Gdk::Cursor::create("default")}, + curPoint{Gdk::Cursor::create("pointer")} { // Configure module action Map const Json::Value actions{config_["actions"]}; - for (Json::Value::const_iterator it = actions.begin(); it != actions.end(); ++it) { + for (Json::Value::const_iterator it{actions.begin()}; it != actions.end(); ++it) { if (it.key().isString() && it->isString()) if (!eventActionMap_.contains(it.key().asString())) { eventActionMap_.insert({it.key().asString(), it->asString()}); @@ -32,49 +27,37 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std:: spdlog::warn("Wrong actions section configuration. See config by index: {}", it.index()); } - event_box_.signal_enter_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseEnter)); - event_box_.signal_leave_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseLeave)); - // configure events' user commands // hasUserEvents is true if any element from eventMap_ is satisfying the condition in the lambda - bool hasUserEvents = + bool hasPressEvents{ std::find_if(eventMap_.cbegin(), eventMap_.cend(), [&config](const auto& eventEntry) { // True if there is any non-release type event - return eventEntry.first.second != GdkEventType::GDK_BUTTON_RELEASE && + return eventEntry.first.second != Gdk::Event::Type::BUTTON_RELEASE && config[eventEntry.second].isString(); - }) != eventMap_.cend(); - - if (enable_click || hasUserEvents) { - hasUserEvents_ = true; - event_box_.add_events(Gdk::BUTTON_PRESS_MASK); - event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &AModule::handleToggle)); + }) != eventMap_.cend()}; + if (enable_click || hasPressEvents) { + hasPressEvents_ = true; } else { - hasUserEvents_ = false; + hasPressEvents_ = false; } - bool hasReleaseEvent = + hasReleaseEvents_ = std::find_if(eventMap_.cbegin(), eventMap_.cend(), [&config](const auto& eventEntry) { - // True if there is any non-release type event - return eventEntry.first.second == GdkEventType::GDK_BUTTON_RELEASE && + // True if there is any release type event + return eventEntry.first.second == Gdk::Event::Type::BUTTON_RELEASE && config[eventEntry.second].isString(); }) != eventMap_.cend(); - if (hasReleaseEvent) { - event_box_.add_events(Gdk::BUTTON_RELEASE_MASK); - event_box_.signal_button_release_event().connect(sigc::mem_fun(*this, &AModule::handleRelease)); - } - if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString() || - config_["on-scroll-left"].isString() || config_["on-scroll-right"].isString() || - enable_scroll) { - event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); - event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll)); - } + + makeControllClick(); + makeControllScroll(); + makeControllMotion(); // Respect user configuration of cursor 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())); + setCursor(curPoint); + } else if (config_["cursor"].isString()) { + setCursor(config_["cursor"].asString()); } else { spdlog::warn("unknown cursor option configured on module {}", name_); } @@ -105,74 +88,46 @@ auto AModule::doAction(const std::string& name) -> void { } } -void AModule::setCursor(Gdk::CursorType const& c) { - auto gdk_window = event_box_.get_window(); - 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); - } +void AModule::handleToggle(int n_press, double dx, double dy) { + handleClickEvent(controllClick_->get_current_button(), n_press, Gdk::Event::Type::BUTTON_PRESS); +} +void AModule::handleRelease(int n_press, double dx, double dy) { + handleClickEvent(controllClick_->get_current_button(), n_press, Gdk::Event::Type::BUTTON_RELEASE); } -bool AModule::handleMouseEnter(GdkEventCrossing* const& e) { - if (auto* module = event_box_.get_child(); module != nullptr) { - module->set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); - } +void AModule::setCursor(const Glib::RefPtr& cur) { + ((Gtk::Widget&)*this).set_cursor(cur); +} + +void AModule::setCursor(const Glib::ustring& name) { ((Gtk::Widget&)*this).set_cursor(name); } + +void AModule::handleMouseEnter(double x, double y) { + controllMotion_->get_widget()->set_state_flags(Gtk::StateFlags::PRELIGHT); // Default behavior indicating event availability - if (hasUserEvents_ && !config_.isMember("cursor")) { - setCursor(Gdk::HAND2); + if (hasPressEvents_ && !config_.isMember("cursor")) { + setCursor(curPoint); } - - return false; } -bool AModule::handleMouseLeave(GdkEventCrossing* const& e) { - if (auto* module = event_box_.get_child(); module != nullptr) { - module->unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); - } +void AModule::handleMouseLeave() { + controllMotion_->get_widget()->unset_state_flags(Gtk::StateFlags::PRELIGHT); // Default behavior indicating event availability - if (hasUserEvents_ && !config_.isMember("cursor")) { - setCursor(Gdk::ARROW); + if (hasPressEvents_ && !config_.isMember("cursor")) { + setCursor(curDefault); } - - return false; } -bool AModule::handleToggle(GdkEventButton* const& e) { return handleUserEvent(e); } - -bool AModule::handleRelease(GdkEventButton* const& e) { return handleUserEvent(e); } - -bool AModule::handleUserEvent(GdkEventButton* const& e) { +void AModule::handleClickEvent(uint n_button, int n_press, Gdk::Event::Type n_evtype) { std::string format{}; - const std::map, std::string>::const_iterator& rec{ - eventMap_.find(std::pair(e->button, e->type))}; - + const std::map, Gdk::Event::Type>, std::string>::const_iterator& + rec{eventMap_.find(std::pair(std::pair(n_button, n_press), n_evtype))}; if (rec != eventMap_.cend()) { - // First call module actions + // First call module action this->AModule::doAction(rec->second); - format = rec->second; } - - // Check that a menu has been configured - if (config_["menu"].isString()) { - // Check if the event is the one specified for the "menu" option - if (rec->second == config_["menu"].asString()) { - // Popup the menu - gtk_widget_show_all(GTK_WIDGET(menu_)); - gtk_menu_popup_at_pointer(GTK_MENU(menu_), reinterpret_cast(e)); - } - } // Second call user scripts if (!format.empty()) { if (config_[format].isString()) @@ -180,40 +135,39 @@ bool AModule::handleUserEvent(GdkEventButton* const& e) { else format.clear(); } - if (!format.empty()) { - pid_.push_back(util::command::forkExec(format)); - } + if (!format.empty()) pid_.push_back(util::command::forkExec(format)); + dp.emit(); - return true; } -AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) { +const AModule::SCROLL_DIR AModule::getScrollDir(Glib::RefPtr e) { // only affects up/down - bool reverse = config_["reverse-scrolling"].asBool(); - bool reverse_mouse = config_["reverse-mouse-scrolling"].asBool(); + bool reverse{config_["reverse-scrolling"].asBool()}; + bool reverse_mouse{config_["reverse-mouse-scrolling"].asBool()}; // ignore reverse-scrolling if event comes from a mouse wheel - GdkDevice* device = gdk_event_get_source_device((GdkEvent*)e); - if (device != nullptr && gdk_device_get_source(device) == GDK_SOURCE_MOUSE) { - reverse = reverse_mouse; - } + const auto device{e->get_device()}; + if ((device) && device->get_source() == Gdk::InputSource::MOUSE) reverse = reverse_mouse; - switch (e->direction) { - case GDK_SCROLL_UP: + switch (e->get_direction()) { + case Gdk::ScrollDirection::UP: return reverse ? SCROLL_DIR::DOWN : SCROLL_DIR::UP; - case GDK_SCROLL_DOWN: + case Gdk::ScrollDirection::DOWN: return reverse ? SCROLL_DIR::UP : SCROLL_DIR::DOWN; - case GDK_SCROLL_LEFT: - return SCROLL_DIR::LEFT; - case GDK_SCROLL_RIGHT: - return SCROLL_DIR::RIGHT; - case GDK_SCROLL_SMOOTH: { + case Gdk::ScrollDirection::LEFT: + return reverse ? SCROLL_DIR::RIGHT : SCROLL_DIR::LEFT; + case Gdk::ScrollDirection::RIGHT: + return reverse ? SCROLL_DIR::LEFT : SCROLL_DIR::RIGHT; + case Gdk::ScrollDirection::SMOOTH: { SCROLL_DIR dir{SCROLL_DIR::NONE}; - distance_scrolled_y_ += e->delta_y; - distance_scrolled_x_ += e->delta_x; + double delta_x, delta_y; + e->get_deltas(delta_x, delta_y); - gdouble threshold = 0; + distance_scrolled_y_ += delta_y; + distance_scrolled_x_ += delta_x; + + double threshold{0.0}; if (config_["smooth-scrolling-threshold"].isNumeric()) { threshold = config_["smooth-scrolling-threshold"].asDouble(); } @@ -231,11 +185,11 @@ AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) { switch (dir) { case SCROLL_DIR::UP: case SCROLL_DIR::DOWN: - distance_scrolled_y_ = 0; + distance_scrolled_y_ = 0.0; break; case SCROLL_DIR::LEFT: case SCROLL_DIR::RIGHT: - distance_scrolled_x_ = 0; + distance_scrolled_x_ = 0.0; break; case SCROLL_DIR::NONE: break; @@ -249,31 +203,113 @@ AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) { } } -bool AModule::handleScroll(GdkEventScroll* e) { - auto dir = getScrollDir(e); - std::string eventName{}; - - if (dir == SCROLL_DIR::UP) - eventName = "on-scroll-up"; - else if (dir == SCROLL_DIR::DOWN) - eventName = "on-scroll-down"; - else if (dir == SCROLL_DIR::LEFT) - eventName = "on-scroll-left"; - else if (dir == SCROLL_DIR::RIGHT) - eventName = "on-scroll-right"; - - // First call module actions - this->AModule::doAction(eventName); - // Second call user scripts - if (config_[eventName].isString()) - pid_.push_back(util::command::forkExec(config_[eventName].asString())); +bool AModule::handleScroll(double dx, double dy) { + currEvent_ = controllScroll_->get_current_event(); + + if (currEvent_) { + std::string format{}; + const auto dir{getScrollDir(currEvent_)}; + + if (dir == SCROLL_DIR::UP) + format = "on-scroll-up"; + else if (dir == SCROLL_DIR::DOWN) + format = "on-scroll-down"; + else if (dir == SCROLL_DIR::LEFT) + format = "on-scroll-left"; + else if (dir == SCROLL_DIR::RIGHT) + format = "on-scroll-right"; + + // First call module action + this->AModule::doAction(format); + // Second call user scripts + if (config_[format].isString()) + pid_.push_back(util::command::forkExec(config_[format].asString())); + + dp.emit(); + } - dp.emit(); return true; } bool AModule::tooltipEnabled() const { return isTooltip; } -AModule::operator Gtk::Widget&() { return event_box_; } +AModule::operator Gtk::Widget&() { return this->operator Gtk::Widget&(); }; + +void AModule::bindEvents(Gtk::Widget& wg) { + wg.set_cursor(curDefault); + + if (!controllClick_) makeControllClick(); + if (!controllScroll_) makeControllScroll(); + if (!controllMotion_) makeControllMotion(); + + if (controllClick_) wg.add_controller(controllClick_); + if (controllScroll_) wg.add_controller(controllScroll_); + if (controllMotion_) wg.add_controller(controllMotion_); +} + +void AModule::unBindEvents() { + removeControllClick(); + removeControllScroll(); + removeControllMotion(); +} + +void AModule::makeControllClick() { + if (enableClick_ || hasPressEvents_ || hasReleaseEvents_) { + controllClick_ = Gtk::GestureClick::create(); + controllClick_->set_propagation_phase(Gtk::PropagationPhase::TARGET); + controllClick_->set_button(0u); + + if (enableClick_ || hasPressEvents_) + controllClick_->signal_pressed().connect(sigc::mem_fun(*this, &AModule::handleToggle), + isAfter); + if (hasReleaseEvents_) + controllClick_->signal_released().connect(sigc::mem_fun(*this, &AModule::handleRelease), + isAfter); + } +} + +void AModule::makeControllScroll() { + if (enableScroll_ || config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString() || + config_["on-scroll-left"].isString() || config_["on-scroll-right"].isString()) { + controllScroll_ = Gtk::EventControllerScroll::create(); + controllScroll_->set_propagation_phase(Gtk::PropagationPhase::TARGET); + controllScroll_->set_flags(Gtk::EventControllerScroll::Flags::BOTH_AXES); + controllScroll_->signal_scroll().connect(sigc::mem_fun(*this, &AModule::handleScroll), isAfter); + } +} + +void AModule::makeControllMotion() { + controllMotion_ = Gtk::EventControllerMotion::create(); + controllMotion_->signal_enter().connect(sigc::mem_fun(*this, &AModule::handleMouseEnter)); + controllMotion_->signal_leave().connect(sigc::mem_fun(*this, &AModule::handleMouseLeave)); +} + +static void removeControll(Glib::RefPtr controll) { + if (controll) { + Gtk::Widget* widget{controll->get_widget()}; + if (widget) widget->remove_controller(controll); + } +} + +void AModule::removeControllClick() { + if (controllClick_) { + removeControll(controllClick_); + controllClick_ = nullptr; + } +} + +void AModule::removeControllScroll() { + if (controllScroll_) { + removeControll(controllScroll_); + controllScroll_ = nullptr; + } +} + +void AModule::removeControllMotion() { + if (controllMotion_) { + removeControll(controllMotion_); + controllMotion_ = nullptr; + } +} } // namespace waybar diff --git a/src/ASlider.cpp b/src/ASlider.cpp index b434be301..322f7ac91 100644 --- a/src/ASlider.cpp +++ b/src/ASlider.cpp @@ -1,20 +1,18 @@ #include "ASlider.hpp" #include "gtkmm/adjustment.h" -#include "gtkmm/enums.h" namespace waybar { ASlider::ASlider(const Json::Value& config, const std::string& name, const std::string& id) : AModule(config, name, id, false, false), vertical_(config_["orientation"].asString() == "vertical"), - scale_(vertical_ ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL) { + scale_(vertical_ ? Gtk::Orientation::VERTICAL : Gtk::Orientation::HORIZONTAL) { scale_.set_name(name); if (!id.empty()) { scale_.get_style_context()->add_class(id); } scale_.get_style_context()->add_class(MODULE_CLASS); - event_box_.add(scale_); scale_.signal_value_changed().connect(sigc::mem_fun(*this, &ASlider::onValueChanged)); if (config_["min"].isUInt()) { @@ -28,8 +26,12 @@ ASlider::ASlider(const Json::Value& config, const std::string& name, const std:: scale_.set_inverted(vertical_); scale_.set_draw_value(false); scale_.set_adjustment(Gtk::Adjustment::create(curr_, min_, max_ + 1, 1, 1, 1)); + + AModule::bindEvents(scale_); } void ASlider::onValueChanged() {} -} // namespace waybar \ No newline at end of file +ASlider::operator Gtk::Widget&() { return scale_; }; + +} // namespace waybar diff --git a/src/bar.cpp b/src/bar.cpp index 5068e90d0..49579f7d8 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -1,13 +1,10 @@ #include "bar.hpp" -#include +#include #include -#include - #include "client.hpp" #include "factory.hpp" -#include "group.hpp" #ifdef HAVE_SWAY #include "modules/sway/bar.hpp" @@ -90,26 +87,28 @@ void from_json(const Json::Value& j, bar_mode& m) { /* Deserializer for enum Gtk::PositionType */ void from_json(const Json::Value& j, Gtk::PositionType& pos) { if (j == "left") { - pos = Gtk::POS_LEFT; + pos = Gtk::PositionType::LEFT; } else if (j == "right") { - pos = Gtk::POS_RIGHT; + pos = Gtk::PositionType::RIGHT; } else if (j == "top") { - pos = Gtk::POS_TOP; + pos = Gtk::PositionType::TOP; } else if (j == "bottom") { - pos = Gtk::POS_BOTTOM; + pos = Gtk::PositionType::BOTTOM; } } Glib::ustring to_string(Gtk::PositionType pos) { switch (pos) { - case Gtk::POS_LEFT: + case Gtk::PositionType::LEFT: return "left"; - case Gtk::POS_RIGHT: + case Gtk::PositionType::RIGHT: return "right"; - case Gtk::POS_TOP: + case Gtk::PositionType::TOP: return "top"; - case Gtk::POS_BOTTOM: + case Gtk::PositionType::BOTTOM: return "bottom"; + default: + return ""; } throw std::runtime_error("Invalid Gtk::PositionType"); } @@ -130,34 +129,35 @@ void from_json(const Json::Value& j, std::map& m) { }; // namespace waybar waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) - : output(w_output), - config(w_config), - surface(nullptr), - window{Gtk::WindowType::WINDOW_TOPLEVEL}, - x_global(0), - y_global(0), + : output{w_output}, + config{w_config}, + surface{nullptr}, + window{Gtk::Window()}, + x_global{0}, + y_global{0}, margins_{.top = 0, .right = 0, .bottom = 0, .left = 0}, - left_(Gtk::ORIENTATION_HORIZONTAL, 0), - center_(Gtk::ORIENTATION_HORIZONTAL, 0), - right_(Gtk::ORIENTATION_HORIZONTAL, 0), - box_(Gtk::ORIENTATION_HORIZONTAL, 0) { + left_{Gtk::Orientation::HORIZONTAL, 0}, + center_{Gtk::Orientation::HORIZONTAL, 0}, + right_{Gtk::Orientation::HORIZONTAL, 0}, + box_{} { window.set_title("waybar"); window.set_name("waybar"); window.set_decorated(false); + window.set_child(box_); window.get_style_context()->add_class(output->name); window.get_style_context()->add_class(config["name"].asString()); from_json(config["position"], position); - orientation = (position == Gtk::POS_LEFT || position == Gtk::POS_RIGHT) - ? Gtk::ORIENTATION_VERTICAL - : Gtk::ORIENTATION_HORIZONTAL; + orientation = (position == Gtk::PositionType::LEFT || position == Gtk::PositionType::RIGHT) + ? Gtk::Orientation::VERTICAL + : Gtk::Orientation::HORIZONTAL; window.get_style_context()->add_class(to_string(position)); - left_ = Gtk::Box(orientation, 0); - center_ = Gtk::Box(orientation, 0); - right_ = Gtk::Box(orientation, 0); - box_ = Gtk::Box(orientation, 0); + left_.set_orientation(orientation); + center_.set_orientation(orientation); + right_.set_orientation(orientation); + box_.set_orientation(orientation); left_.get_style_context()->add_class("modules-left"); center_.get_style_context()->add_class("modules-center"); @@ -218,12 +218,11 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) margins_ = {.top = gaps, .right = gaps, .bottom = gaps, .left = gaps}; } - window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigure)); output->monitor->property_geometry().signal_changed().connect( sigc::mem_fun(*this, &Bar::onOutputGeometryChanged)); // this has to be executed before GtkWindow.realize - auto* gtk_window = window.gobj(); + auto* gtk_window{window.gobj()}; gtk_layer_init_for_window(gtk_window); gtk_layer_set_keyboard_mode(gtk_window, GTK_LAYER_SHELL_KEYBOARD_MODE_NONE); gtk_layer_set_monitor(gtk_window, output->monitor->gobj()); @@ -258,7 +257,7 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) setVisible(false); } - window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap)); + window.signal_map().connect(sigc::mem_fun(*this, &Bar::onMap)); #if HAVE_SWAY if (auto ipc = config["ipc"]; ipc.isBool() && ipc.asBool()) { @@ -278,16 +277,12 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) #endif setupWidgets(); - window.show_all(); + window.show(); if (spdlog::should_log(spdlog::level::debug)) { - // Unfortunately, this function isn't in the C++ bindings, so we have to call the C version. - char* gtk_tree = gtk_style_context_to_string( - window.get_style_context()->gobj(), - (GtkStyleContextPrintFlags)(GTK_STYLE_CONTEXT_PRINT_RECURSE | - GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE)); - spdlog::debug("GTK widget tree:\n{}", gtk_tree); - g_free(gtk_tree); + auto gtk_tree{window.get_style_context()->to_string(Gtk::StyleContext::PrintFlags::RECURSE | + Gtk::StyleContext::PrintFlags::SHOW_STYLE)}; + spdlog::debug("GTK widget tree:\n{}", gtk_tree.c_str()); } } @@ -345,18 +340,13 @@ void waybar::Bar::setMode(const struct bar_mode& mode) { * gtk-layer-shell schedules a commit on the next frame event in GTK, but this could fail in * certain scenarios, such as fully occluded bar. */ - gtk_layer_try_force_commit(gtk_window); wl_display_flush(Client::inst()->wl_display); } void waybar::Bar::setPassThrough(bool passthrough) { - auto gdk_window = window.get_window(); - if (gdk_window) { - Cairo::RefPtr region; - if (passthrough) { - region = Cairo::Region::create(); - } - gdk_window->input_shape_combine_region(region, 0, 0); + if (passthrough && gdk_surface_) { + auto region{Cairo::Region::create()}; + gdk_surface_->set_input_region(region); } } @@ -364,18 +354,18 @@ void waybar::Bar::setPosition(Gtk::PositionType position) { std::array anchors; anchors.fill(TRUE); - auto orientation = (position == Gtk::POS_LEFT || position == Gtk::POS_RIGHT) - ? Gtk::ORIENTATION_VERTICAL - : Gtk::ORIENTATION_HORIZONTAL; + auto orientation = (position == Gtk::PositionType::LEFT || position == Gtk::PositionType::RIGHT) + ? Gtk::Orientation::VERTICAL + : Gtk::Orientation::HORIZONTAL; switch (position) { - case Gtk::POS_LEFT: + case Gtk::PositionType::LEFT: anchors[GTK_LAYER_SHELL_EDGE_RIGHT] = FALSE; break; - case Gtk::POS_RIGHT: + case Gtk::PositionType::RIGHT: anchors[GTK_LAYER_SHELL_EDGE_LEFT] = FALSE; break; - case Gtk::POS_BOTTOM: + case Gtk::PositionType::BOTTOM: anchors[GTK_LAYER_SHELL_EDGE_TOP] = FALSE; break; default: /* Gtk::POS_TOP */ @@ -387,10 +377,10 @@ void waybar::Bar::setPosition(Gtk::PositionType position) { // otherwise the bar will use all space uint32_t configured_width = config["width"].isUInt() ? config["width"].asUInt() : 0; uint32_t configured_height = config["height"].isUInt() ? config["height"].asUInt() : 0; - if (orientation == Gtk::ORIENTATION_VERTICAL && configured_height > 1) { + if (orientation == Gtk::Orientation::VERTICAL && configured_height > 1) { anchors[GTK_LAYER_SHELL_EDGE_TOP] = FALSE; anchors[GTK_LAYER_SHELL_EDGE_BOTTOM] = FALSE; - } else if (orientation == Gtk::ORIENTATION_HORIZONTAL && configured_width > 1) { + } else if (orientation == Gtk::Orientation::HORIZONTAL && configured_width > 1) { anchors[GTK_LAYER_SHELL_EDGE_LEFT] = FALSE; anchors[GTK_LAYER_SHELL_EDGE_RIGHT] = FALSE; } @@ -401,14 +391,14 @@ void waybar::Bar::setPosition(Gtk::PositionType position) { } } -void waybar::Bar::onMap(GdkEventAny* /*unused*/) { +void waybar::Bar::onMap() { /* * Obtain a pointer to the custom layer surface for modules that require it (idle_inhibitor). */ - auto* gdk_window = window.get_window()->gobj(); - surface = gdk_wayland_window_get_wl_surface(gdk_window); - configureGlobalOffset(gdk_window_get_width(gdk_window), gdk_window_get_height(gdk_window)); - + gdk_surface_ = window.get_surface(); + gdk_surface_->signal_layout().connect(sigc::mem_fun(*this, &Bar::onConfigure)); + surface = gdk_wayland_surface_get_wl_surface(gdk_surface_->gobj()); + configureGlobalOffset(gdk_surface_->get_width(), gdk_surface_->get_height()); setPassThrough(passthrough_); } @@ -493,8 +483,8 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos, auto id_name = ref.substr(6, hash_pos - 6); auto class_name = hash_pos != std::string::npos ? ref.substr(hash_pos + 1) : ""; - auto vertical = (group != nullptr ? group->getBox().get_orientation() - : box_.get_orientation()) == Gtk::ORIENTATION_VERTICAL; + auto vertical = (group ? group->getBox().get_orientation() : box_.get_orientation()) == + Gtk::Orientation::VERTICAL; auto* group_module = new waybar::Group(id_name, class_name, config[ref], vertical); getModules(factory, ref, group_module); @@ -533,15 +523,13 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos, } auto waybar::Bar::setupWidgets() -> void { - window.add(box_); - box_.pack_start(left_, false, false); + box_.set_start_widget(left_); if (config["fixed-center"].isBool() ? config["fixed-center"].asBool() : true) { box_.set_center_widget(center_); } else { - box_.pack_start(center_, true, false); + box_.set_start_widget(center_); } - box_.pack_end(right_, false, false); - + box_.set_end_widget(right_); // Convert to button code for every module that is used. setupAltFormatKeyForModuleList("modules-left"); setupAltFormatKeyForModuleList("modules-right"); @@ -552,18 +540,17 @@ auto waybar::Bar::setupWidgets() -> void { getModules(factory, "modules-center"); getModules(factory, "modules-right"); for (auto const& module : modules_left_) { - left_.pack_start(*module, false, false); + left_.append(*module); } for (auto const& module : modules_center_) { - center_.pack_start(*module, false, false); + center_.append(*module); } - std::reverse(modules_right_.begin(), modules_right_.end()); for (auto const& module : modules_right_) { - right_.pack_end(*module, false, false); + right_.append(*module); } } -void waybar::Bar::onConfigure(GdkEventConfigure* ev) { +void waybar::Bar::onConfigure(int width, int height) { /* * GTK wants new size for the window. * Actual resizing and management of the exclusve zone is handled within the gtk-layer-shell @@ -572,20 +559,20 @@ void waybar::Bar::onConfigure(GdkEventConfigure* ev) { * Note: forced resizing to a window smaller than required by GTK would not work with * gtk-layer-shell. */ - if (orientation == Gtk::ORIENTATION_VERTICAL) { - if (width_ > 1 && ev->width > static_cast(width_)) { - spdlog::warn(MIN_WIDTH_MSG, width_, ev->width); + if (orientation == Gtk::Orientation::VERTICAL) { + if (width_ > 1 && width > static_cast(width_)) { + spdlog::warn(MIN_WIDTH_MSG, width_, width); } } else { - if (height_ > 1 && ev->height > static_cast(height_)) { - spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height); + if (height_ > 1 && height > static_cast(height_)) { + spdlog::warn(MIN_HEIGHT_MSG, height_, height); } } - width_ = ev->width; - height_ = ev->height; + width_ = width; + height_ = height; - configureGlobalOffset(ev->width, ev->height); - spdlog::info(BAR_SIZE_MSG, ev->width, ev->height, output->name); + configureGlobalOffset(width, height); + spdlog::info(BAR_SIZE_MSG, width, height, output->name); } void waybar::Bar::configureGlobalOffset(int width, int height) { @@ -593,28 +580,28 @@ void waybar::Bar::configureGlobalOffset(int width, int height) { int x; int y; switch (position) { - case Gtk::POS_BOTTOM: + case Gtk::PositionType::BOTTOM: if (width + margins_.left + margins_.right >= monitor_geometry.width) x = margins_.left; else x = (monitor_geometry.width - width) / 2; y = monitor_geometry.height - height - margins_.bottom; break; - case Gtk::POS_LEFT: + case Gtk::PositionType::LEFT: x = margins_.left; if (height + margins_.top + margins_.bottom >= monitor_geometry.height) y = margins_.top; else y = (monitor_geometry.height - height) / 2; break; - case Gtk::POS_RIGHT: + case Gtk::PositionType::RIGHT: x = monitor_geometry.width - width - margins_.right; if (height + margins_.top + margins_.bottom >= monitor_geometry.height) y = margins_.top; else y = (monitor_geometry.height - height) / 2; break; - default: /* Gtk::POS_TOP */ + default: /* Gtk::PositionType::TOP */ if (width + margins_.left + margins_.right >= monitor_geometry.width) x = margins_.left; else diff --git a/src/client.cpp b/src/client.cpp index 63a9276a6..7f6a732fc 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1,12 +1,12 @@ #include "client.hpp" -#include +#include +#include +#include #include #include -#include -#include "gtkmm/icontheme.h" #include "idle-inhibit-unstable-v1-client-protocol.h" #include "util/clara.hpp" #include "util/format.hpp" @@ -178,15 +178,16 @@ const std::string waybar::Client::getStyle(const std::string &style, auto waybar::Client::setupCss(const std::string &css_file) -> void { css_provider_ = Gtk::CssProvider::create(); - style_context_ = Gtk::StyleContext::create(); // Load our css file, wherever that may be hiding - if (!css_provider_->load_from_path(css_file)) { - throw std::runtime_error("Can't open style file"); + try { + css_provider_->load_from_path(css_file); + } catch (const Glib::Error &e) { + spdlog::error("{}", e.what()); } // there's always only one screen - style_context_->add_provider_for_screen(Gdk::Screen::get_default(), css_provider_, - GTK_STYLE_PROVIDER_PRIORITY_USER); + Gtk::StyleContext::add_provider_for_display(Gdk::Display::get_default(), css_provider_, + GTK_STYLE_PROVIDER_PRIORITY_USER); } void waybar::Client::bindInterfaces() { @@ -206,13 +207,23 @@ void waybar::Client::bindInterfaces() { throw std::runtime_error("Failed to acquire required resources."); } // add existing outputs and subscribe to updates - for (auto i = 0; i < gdk_display->get_n_monitors(); ++i) { - auto monitor = gdk_display->get_monitor(i); - handleMonitorAdded(monitor); + // auto monitors{gdk_display->get_monitors()}; + for (guint i{0}; i < monitors_->get_n_items(); ++i) { + handleMonitorAdded(std::dynamic_pointer_cast(monitors_->get_object(i))); } - gdk_display->signal_monitor_added().connect(sigc::mem_fun(*this, &Client::handleMonitorAdded)); - gdk_display->signal_monitor_removed().connect( - sigc::mem_fun(*this, &Client::handleMonitorRemoved)); + + monitors_->signal_items_changed().connect( + [=, this](const guint &position, const guint &removed, const guint &added) { + for (auto i{removed}; i >= 0; --i) { + handleMonitorRemoved( + std::dynamic_pointer_cast(monitors_->get_object(position + i))); + } + + for (auto i{added}; i >= 0; --i) { + handleMonitorAdded( + std::dynamic_pointer_cast(monitors_->get_object(position + i))); + } + }); } int waybar::Client::main(int argc, char *argv[]) { @@ -245,13 +256,8 @@ int waybar::Client::main(int argc, char *argv[]) { if (!log_level.empty()) { spdlog::set_level(spdlog::level::from_str(log_level)); } - gtk_app = Gtk::Application::create(argc, argv, "fr.arouillard.waybar", - Gio::APPLICATION_HANDLES_COMMAND_LINE); - - // Initialize Waybars GTK resources with our custom icons - auto theme = Gtk::IconTheme::get_default(); - theme->add_resource_path("/fr/arouillard/waybar/icons"); - + gtk_app = Gtk::Application::create("fr.arouillard.waybar", + Gio::Application::Flags::HANDLES_COMMAND_LINE); gdk_display = Gdk::Display::get_default(); if (!gdk_display) { throw std::runtime_error("Can't find display"); @@ -259,7 +265,13 @@ int waybar::Client::main(int argc, char *argv[]) { if (!GDK_IS_WAYLAND_DISPLAY(gdk_display->gobj())) { throw std::runtime_error("Bar need to run under Wayland"); } + + // Initialize Waybars GTK resources with our custom icons + auto theme{Gtk::IconTheme::get_for_display(gdk_display)}; + theme->add_resource_path("/fr/arouillard/waybar/icons"); + wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj()); + monitors_ = gdk_display->get_monitors(); config.load(config_opt); if (!portal) { portal = std::make_unique(); @@ -289,6 +301,7 @@ int waybar::Client::main(int argc, char *argv[]) { gtk_app->run(); m_cssReloadHelper.reset(); // stop watching css file bars.clear(); + return 0; } diff --git a/src/factory.cpp b/src/factory.cpp index 6c2313e38..01ee926d6 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -59,7 +59,7 @@ #include "modules/sni/tray.hpp" #endif #ifdef HAVE_MPRIS -#include "modules/mpris/mpris.hpp" +#include "modules/mpris.hpp" #endif #ifdef HAVE_LIBNL #include "modules/network.hpp" @@ -113,9 +113,10 @@ #include "modules/custom.hpp" #include "modules/image.hpp" #include "modules/temperature.hpp" +#include "modules/ui.hpp" #include "modules/user.hpp" -waybar::Factory::Factory(const Bar& bar, const Json::Value& config) : bar_(bar), config_(config) {} +waybar::Factory::Factory(const Bar& bar, const Json::Value& config) : bar_{bar}, config_{config} {} waybar::AModule* waybar::Factory::makeModule(const std::string& name, const std::string& pos) const { @@ -125,7 +126,7 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name, auto id = hash_pos != std::string::npos ? name.substr(hash_pos + 1) : ""; #if defined(__FreeBSD__) || defined(__linux__) if (ref == "battery") { - return new waybar::modules::Battery(id, bar_, config_[name]); + return new waybar::modules::Battery(id, config_[name]); } #endif #ifdef HAVE_GAMEMODE @@ -258,6 +259,7 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name, if (ref == "image") { return new waybar::modules::Image(id, config_[name]); } + // gtk4 todo #ifdef HAVE_DBUSMENU if (ref == "tray") { return new waybar::modules::SNI::Tray(id, bar_, config_[name]); @@ -309,7 +311,7 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name, #endif #ifdef HAVE_LOGIND_INHIBITOR if (ref == "inhibitor") { - return new waybar::modules::Inhibitor(id, bar_, config_[name]); + return new waybar::modules::Inhibitor(id, config_[name]); } #endif #ifdef HAVE_LIBJACK @@ -341,6 +343,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name, if (ref.compare(0, 5, "cffi/") == 0 && ref.size() > 5) { return new waybar::modules::CFFI(ref.substr(5), id, config_[name]); } + if (ref.compare(0, 3, "ui/") == 0 && ref.size() > 3) { + return new waybar::modules::UI(ref.substr(3), id, config_[name]); + } } catch (const std::exception& e) { auto err = fmt::format("Disabling module \"{}\", {}", name, e.what()); throw std::runtime_error(err); diff --git a/src/group.cpp b/src/group.cpp index 50841efd6..609efd2d8 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -1,12 +1,5 @@ #include "group.hpp" -#include - -#include - -#include "gtkmm/enums.h" -#include "gtkmm/widget.h" - namespace waybar { Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical) { @@ -18,20 +11,20 @@ Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical) { */ if (is_vertical) { - return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_UP; + return Gtk::RevealerTransitionType::SLIDE_UP; } - return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_LEFT; + return Gtk::RevealerTransitionType::SLIDE_LEFT; } Group::Group(const std::string& name, const std::string& id, const Json::Value& config, bool vertical) : AModule(config, name, id, true, true), - box{vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0}, - revealer_box{vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0} { - box.set_name(name_); + box_{vertical ? Gtk::Orientation::VERTICAL : Gtk::Orientation::HORIZONTAL, 0}, + revealer_box_{vertical ? Gtk::Orientation::VERTICAL : Gtk::Orientation::HORIZONTAL, 0} { + box_.set_name(name_); if (!id.empty()) { - box.get_style_context()->add_class(id); + box_.get_style_context()->add_class(id); } // default orientation: orthogonal to parent @@ -40,102 +33,95 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value& if (orientation == "inherit") { // keep orientation passed } else if (orientation == "orthogonal") { - box.set_orientation(vertical ? Gtk::ORIENTATION_HORIZONTAL : Gtk::ORIENTATION_VERTICAL); + box_.set_orientation(vertical ? Gtk::Orientation::HORIZONTAL : Gtk::Orientation::VERTICAL); } else if (orientation == "vertical") { - box.set_orientation(Gtk::ORIENTATION_VERTICAL); + box_.set_orientation(Gtk::Orientation::VERTICAL); } else if (orientation == "horizontal") { - box.set_orientation(Gtk::ORIENTATION_HORIZONTAL); + box_.set_orientation(Gtk::Orientation::HORIZONTAL); } else { throw std::runtime_error("Invalid orientation value: " + orientation); } if (config_["drawer"].isObject()) { - is_drawer = true; + is_drawer_ = true; const auto& drawer_config = config_["drawer"]; const int transition_duration = (drawer_config["transition-duration"].isInt() ? drawer_config["transition-duration"].asInt() : 500); - add_class_to_drawer_children = + add_class_to_drawer_children_ = (drawer_config["children-class"].isString() ? drawer_config["children-class"].asString() : "drawer-child"); 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(); + click_to_reveal_ = drawer_config["click-to-reveal"].asBool(); auto transition_type = getPreferredTransitionType(vertical); - revealer.set_transition_type(transition_type); - revealer.set_transition_duration(transition_duration); - revealer.set_reveal_child(false); - - revealer.get_style_context()->add_class("drawer"); + revealer_.set_transition_type(transition_type); + revealer_.set_transition_duration(transition_duration); + revealer_.set_reveal_child(false); - revealer.add(revealer_box); + revealer_.get_style_context()->add_class("drawer"); - if (left_to_right) { - box.pack_end(revealer); - } else { - box.pack_start(revealer); - } + revealer_.set_child(revealer_box_); + if (left_to_right) + box_.append(revealer_); + else + box_.prepend(revealer_); } - event_box_.add(box); + AModule::bindEvents(box_); } void Group::show_group() { - box.set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); - revealer.set_reveal_child(true); + box_.set_state_flags(Gtk::StateFlags::PRELIGHT); + revealer_.set_reveal_child(true); } void Group::hide_group() { - box.unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); - revealer.set_reveal_child(false); + box_.unset_state_flags(Gtk::StateFlags::PRELIGHT); + revealer_.set_reveal_child(false); } -bool Group::handleMouseEnter(GdkEventCrossing* const& e) { - if (!click_to_reveal) { +void Group::handleMouseEnter(double x, double y) { + if (!click_to_reveal_) { show_group(); } - return false; } -bool Group::handleMouseLeave(GdkEventCrossing* const& e) { - if (!click_to_reveal && e->detail != GDK_NOTIFY_INFERIOR) { +void Group::handleMouseLeave() { + if (!click_to_reveal_ && AModule::controllScroll_->get_current_event()->get_crossing_detail() != + Gdk::NotifyType::INFERIOR) { 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) != 0U) { - hide_group(); - } else { - show_group(); +void Group::handleToggle(int n_press, double dx, double dy) { + if (click_to_reveal_ && AModule::controllClick_->get_current_button() == 1 /* left click */) { + if (box_.get_state_flags() == Gtk::StateFlags::PRELIGHT) { + hide_group(); + } else { + show_group(); + } } - return true; } auto Group::update() -> void { // noop } -Gtk::Box& Group::getBox() { return is_drawer ? (is_first_widget ? box : revealer_box) : box; } +Gtk::Box& Group::getBox() { return is_drawer_ ? (is_first_widget_ ? box_ : revealer_box_) : box_; } void Group::addWidget(Gtk::Widget& widget) { - getBox().pack_start(widget, false, false); + getBox().prepend(widget); - if (is_drawer && !is_first_widget) { - widget.get_style_context()->add_class(add_class_to_drawer_children); + if (is_drawer_ && !is_first_widget_) { + widget.get_style_context()->add_class(add_class_to_drawer_children_); } - is_first_widget = false; + is_first_widget_ = false; } -Group::operator Gtk::Widget&() { return event_box_; } - } // namespace waybar diff --git a/src/main.cpp b/src/main.cpp index 442c530cb..c51d66c2a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -109,15 +109,15 @@ int main(int argc, char* argv[]) { std::signal(SIGUSR1, SIG_IGN); std::signal(SIGUSR2, SIG_IGN); - std::signal(SIGINT, SIG_IGN); + std::signal(SIGINT, SIG_IGN); delete client; return ret; + } catch (const Glib::Error& e) { + spdlog::error("{}", static_cast(e.what())); + return 1; } catch (const std::exception& e) { spdlog::error("{}", e.what()); return 1; - } catch (const Glib::Exception& e) { - spdlog::error("{}", static_cast(e.what())); - return 1; } } diff --git a/src/modules/backlight.cpp b/src/modules/backlight.cpp index ff58951cd..9c477ef3a 100644 --- a/src/modules/backlight.cpp +++ b/src/modules/backlight.cpp @@ -1,27 +1,12 @@ #include "modules/backlight.hpp" #include -#include -#include -#include -#include - -#include -#include -#include - -#include "util/backend_common.hpp" -#include "util/backlight_backend.hpp" waybar::modules::Backlight::Backlight(const std::string &id, const Json::Value &config) - : ALabel(config, "backlight", id, "{percent}%", 2), + : ALabel(config, "backlight", id, "{percent}%", 2, false, false, true), preferred_device_(config["device"].isString() ? config["device"].asString() : ""), backend(interval_, [this] { dp.emit(); }) { dp.emit(); - - // Set up scroll handler - event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); - event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Backlight::handleScroll)); } auto waybar::modules::Backlight::update() -> void { @@ -35,7 +20,7 @@ auto waybar::modules::Backlight::update() -> void { } if (best->get_powered()) { - event_box_.show(); + label_.show(); const uint8_t percent = best->get_max() == 0 ? 100 : round(best->get_actual() * 100.0f / best->get_max()); std::string desc = fmt::format(fmt::runtime(format_), fmt::arg("percent", percent), @@ -56,7 +41,7 @@ auto waybar::modules::Backlight::update() -> void { } } } else { - event_box_.hide(); + label_.hide(); } } else { if (previous_best_device == nullptr) { @@ -69,10 +54,10 @@ auto waybar::modules::Backlight::update() -> void { ALabel::update(); } -bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) { +bool waybar::modules::Backlight::handleScroll(double dx, double dy) { // Check if the user has set a custom command for scrolling if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { - return AModule::handleScroll(e); + return AModule::handleScroll(dx, dy); } // Fail fast if the proxy could not be initialized @@ -81,7 +66,7 @@ bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) { } // Check scroll direction - auto dir = AModule::getScrollDir(e); + auto dir = AModule::getScrollDir(controllScroll_->get_current_event()); // No worries, it will always be set because of the switch below. This is purely to suppress a // warning diff --git a/src/modules/backlight_slider.cpp b/src/modules/backlight_slider.cpp index 6269dddbf..e44791e88 100644 --- a/src/modules/backlight_slider.cpp +++ b/src/modules/backlight_slider.cpp @@ -20,4 +20,4 @@ void BacklightSlider::onValueChanged() { backend.set_scaled_brightness(preferred_device_, brightness); } -} // namespace waybar::modules \ No newline at end of file +} // namespace waybar::modules diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index d87cc6129..0886c8dd6 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -1,14 +1,15 @@ #include "modules/battery.hpp" -#include +#include + +#include + #if defined(__FreeBSD__) #include #endif -#include -#include -waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const Json::Value& config) - : ALabel(config, "battery", id, "{capacity}%", 60), bar_(bar) { +waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config) + : ALabel(config, "battery", id, "{capacity}%", 60) { #if defined(__linux__) battery_watch_fd_ = inotify_init1(IN_CLOEXEC); if (battery_watch_fd_ == -1) { @@ -659,7 +660,7 @@ const std::string waybar::modules::Battery::formatTimeRemaining(float hoursRemai auto waybar::modules::Battery::update() -> void { #if defined(__linux__) if (batteries_.empty()) { - event_box_.hide(); + label_.hide(); return; } #endif @@ -712,9 +713,9 @@ auto waybar::modules::Battery::update() -> void { format = config_["format-" + state].asString(); } if (format.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); auto icons = std::vector{status + "-" + state, status, state}; label_.set_markup(fmt::format( fmt::runtime(format), fmt::arg("capacity", capacity), fmt::arg("power", power), @@ -726,10 +727,11 @@ auto waybar::modules::Battery::update() -> void { } void waybar::modules::Battery::setBarClass(std::string& state) { - auto classes = bar_.window.get_style_context()->list_classes(); - const std::string prefix = "battery-"; + // Drop style + auto classes = label_.get_css_classes(); + const Glib::ustring prefix{"battery-"}; - auto old_class_it = std::find_if(classes.begin(), classes.end(), [&prefix](auto classname) { + auto old_class_it = std::find_if(classes.cbegin(), classes.cend(), [&prefix](auto classname) { return classname.rfind(prefix, 0) == 0; }); @@ -738,7 +740,7 @@ void waybar::modules::Battery::setBarClass(std::string& state) { // If the bar doesn't have any `battery-` class if (old_class_it == classes.end()) { if (!state.empty()) { - bar_.window.get_style_context()->add_class(new_class); + label_.get_style_context()->add_class(new_class); } return; } @@ -748,14 +750,14 @@ void waybar::modules::Battery::setBarClass(std::string& state) { // If the bar has a `battery-` class, // but `state` is empty if (state.empty()) { - bar_.window.get_style_context()->remove_class(old_class); + label_.get_style_context()->remove_class(old_class); return; } // If the bar has a `battery-` class, // and `state` is NOT empty if (old_class != new_class) { - bar_.window.get_style_context()->remove_class(old_class); - bar_.window.get_style_context()->add_class(new_class); + label_.get_style_context()->remove_class(old_class); + label_.get_style_context()->add_class(new_class); } } diff --git a/src/modules/bluetooth.cpp b/src/modules/bluetooth.cpp index c8f1f9966..ec16d590a 100644 --- a/src/modules/bluetooth.cpp +++ b/src/modules/bluetooth.cpp @@ -1,11 +1,7 @@ #include "modules/bluetooth.hpp" -#include #include -#include -#include - #include "util/scope_guard.hpp" namespace { @@ -216,9 +212,9 @@ auto waybar::modules::Bluetooth::update() -> void { state_ = state; if (format_.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); label_.set_markup(fmt::format( fmt::runtime(format_), fmt::arg("status", state_), fmt::arg("num_connections", connected_devices_.size()), diff --git a/src/modules/cffi.cpp b/src/modules/cffi.cpp index e560659b8..0cea9a247 100644 --- a/src/modules/cffi.cpp +++ b/src/modules/cffi.cpp @@ -1,11 +1,8 @@ #include "modules/cffi.hpp" #include -#include -#include -#include -#include +#include namespace waybar::modules { @@ -76,7 +73,7 @@ CFFI::CFFI(const std::string& name, const std::string& id, const Json::Value& co .waybar_version = VERSION, .get_root_widget = [](ffi::wbcffi_module* obj) { - return dynamic_cast(&((CFFI*)obj)->event_box_)->gobj(); + return dynamic_cast(&((CFFI*)obj)->operator Gtk::Widget&())->gobj(); }, .queue_update = [](ffi::wbcffi_module* obj) { ((CFFI*)obj)->dp.emit(); }, }; diff --git a/src/modules/clock.cpp b/src/modules/clock.cpp index 7f5a4d558..8ff338227 100644 --- a/src/modules/clock.cpp +++ b/src/modules/clock.cpp @@ -3,10 +3,7 @@ #include #include -#include -#include #include -#include #include "util/ustring_clen.hpp" @@ -118,19 +115,17 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) } } else cldMonCols_ = 1; + if (config_[kCldPlaceholder]["on-scroll"].isInt()) { cldShift_ = config_[kCldPlaceholder]["on-scroll"].asInt(); - event_box_.add_events(Gdk::LEAVE_NOTIFY_MASK); - event_box_.signal_leave_notify_event().connect([this](GdkEventCrossing*) { - cldCurrShift_ = months{0}; - return false; - }); + AModule::controllMotion_->set_propagation_phase(Gtk::PropagationPhase::TARGET); + AModule::controllMotion_->signal_leave().connect([this]() { cldCurrShift_ = months{0}; }); } } if (tooltipEnabled()) { label_.set_has_tooltip(true); - label_.signal_query_tooltip().connect(sigc::mem_fun(*this, &Clock::query_tlp_cb)); + label_.signal_query_tooltip().connect(sigc::mem_fun(*this, &Clock::query_tlp_cb), false); } thread_ = [this] { diff --git a/src/modules/cpu.cpp b/src/modules/cpu.cpp index 0703eaf7c..93bad0c49 100644 --- a/src/modules/cpu.cpp +++ b/src/modules/cpu.cpp @@ -37,9 +37,9 @@ auto waybar::modules::Cpu::update() -> void { } if (format.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); auto icons = std::vector{state}; fmt::dynamic_format_arg_store store; store.push_back(fmt::arg("load", load1)); diff --git a/src/modules/cpu_frequency/common.cpp b/src/modules/cpu_frequency/common.cpp index e47364ba7..66c47bd22 100644 --- a/src/modules/cpu_frequency/common.cpp +++ b/src/modules/cpu_frequency/common.cpp @@ -1,3 +1,7 @@ +#include + +#include + #include "modules/cpu_frequency.hpp" // In the 80000 version of fmt library authors decided to optimize imports @@ -33,9 +37,9 @@ auto waybar::modules::CpuFrequency::update() -> void { } if (format.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); auto icons = std::vector{state}; fmt::dynamic_format_arg_store store; store.push_back(fmt::arg("icon", getIcon(avg_frequency, icons))); diff --git a/src/modules/cpu_frequency/linux.cpp b/src/modules/cpu_frequency/linux.cpp index 1f368789b..6e18d3ec6 100644 --- a/src/modules/cpu_frequency/linux.cpp +++ b/src/modules/cpu_frequency/linux.cpp @@ -1,4 +1,5 @@ #include +#include #include "modules/cpu_frequency.hpp" diff --git a/src/modules/cpu_usage/common.cpp b/src/modules/cpu_usage/common.cpp index e39479678..793f5b3bc 100644 --- a/src/modules/cpu_usage/common.cpp +++ b/src/modules/cpu_usage/common.cpp @@ -31,9 +31,9 @@ auto waybar::modules::CpuUsage::update() -> void { } if (format.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); auto icons = std::vector{state}; fmt::dynamic_format_arg_store store; store.push_back(fmt::arg("usage", total_usage)); diff --git a/src/modules/custom.cpp b/src/modules/custom.cpp index e023aaf6e..2ac2f1481 100644 --- a/src/modules/custom.cpp +++ b/src/modules/custom.cpp @@ -135,23 +135,22 @@ void waybar::modules::Custom::handleEvent() { } } -bool waybar::modules::Custom::handleScroll(GdkEventScroll* e) { - auto ret = ALabel::handleScroll(e); +bool waybar::modules::Custom::handleScroll(double dx, double dy) { + auto ret = ALabel::handleScroll(dx, dy); handleEvent(); return ret; } -bool waybar::modules::Custom::handleToggle(GdkEventButton* const& e) { - auto ret = ALabel::handleToggle(e); +void waybar::modules::Custom::handleToggle(int n_press, double dx, double dy) { + ALabel::handleToggle(n_press, dx, dy); handleEvent(); - return ret; } auto waybar::modules::Custom::update() -> void { // Hide label if output is empty if ((config_["exec"].isString() || config_["exec-if"].isString()) && (output_.out.empty() || output_.exit_code != 0)) { - event_box_.hide(); + label_.hide(); } else { if (config_["return-type"].asString() == "json") { parseOutputJson(); @@ -164,7 +163,7 @@ auto waybar::modules::Custom::update() -> void { fmt::arg("icon", getIcon(percentage_, alt_)), fmt::arg("percentage", percentage_)); if ((config_["hide-empty-text"].asBool() && text_.empty()) || str.empty()) { - event_box_.hide(); + label_.hide(); } else { label_.set_markup(str); if (tooltipEnabled()) { @@ -175,19 +174,19 @@ auto waybar::modules::Custom::update() -> void { fmt::arg("icon", getIcon(percentage_, alt_)), fmt::arg("percentage", percentage_)); label_.set_tooltip_markup(tooltip); } else if (text_ == tooltip_) { - if (label_.get_tooltip_markup() != str) { + if (label_.get_tooltip_markup().c_str() != str) { label_.set_tooltip_markup(str); } } else { - if (label_.get_tooltip_markup() != tooltip_) { + if (label_.get_tooltip_markup().c_str() != tooltip_) { label_.set_tooltip_markup(tooltip_); } } } auto style = label_.get_style_context(); - auto classes = style->list_classes(); + auto classes{label_.get_css_classes()}; for (auto const& c : classes) { - if (c == id_) continue; + if (c.c_str() == id_) continue; style->remove_class(c); } for (auto const& c : class_) { @@ -196,7 +195,7 @@ auto waybar::modules::Custom::update() -> void { style->add_class("flat"); style->add_class("text-button"); style->add_class(MODULE_CLASS); - event_box_.show(); + label_.show(); } } catch (const fmt::format_error& e) { if (std::strcmp(e.what(), "cannot switch from manual to automatic argument indexing") != 0) diff --git a/src/modules/disk.cpp b/src/modules/disk.cpp index ef257b721..360ec6ebe 100644 --- a/src/modules/disk.cpp +++ b/src/modules/disk.cpp @@ -1,5 +1,10 @@ #include "modules/disk.hpp" +#include +#include + +#include "util/format.hpp" + using namespace waybar::util; waybar::modules::Disk::Disk(const std::string& id, const Json::Value& config) @@ -42,7 +47,7 @@ auto waybar::modules::Disk::update() -> void { */ if (err != 0) { - event_box_.hide(); + label_.hide(); return; } @@ -65,9 +70,9 @@ auto waybar::modules::Disk::update() -> void { } if (format.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); label_.set_markup(fmt::format( fmt::runtime(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), @@ -112,4 +117,4 @@ float waybar::modules::Disk::calc_specific_divisor(std::string divisor) { } else { // default to Bytes if it is anything that we don't recongnise return 1.0; } -} \ No newline at end of file +} diff --git a/src/modules/dwl/tags.cpp b/src/modules/dwl/tags.cpp index f8b250c8c..a0d816a63 100644 --- a/src/modules/dwl/tags.cpp +++ b/src/modules/dwl/tags.cpp @@ -1,14 +1,8 @@ #include "modules/dwl/tags.hpp" -#include -#include #include -#include - -#include #include "client.hpp" -#include "dwl-ipc-unstable-v2-client-protocol.h" #define TAG_INACTIVE 0 #define TAG_ACTIVE 1 @@ -19,7 +13,7 @@ namespace waybar::modules::dwl { /* dwl stuff */ wl_array tags, layouts; -static uint num_tags = 0; +static uint num_tags{0}; static void toggle_visibility(void *data, zdwl_ipc_output_v2 *zdwl_output_v2) { // Intentionally empty @@ -95,8 +89,8 @@ Tags::Tags(const std::string &id, const waybar::Bar &bar, const Json::Value &con bar_(bar), box_{bar.orientation, 0}, output_status_{nullptr} { - struct wl_display *display = Client::inst()->wl_display; - struct wl_registry *registry = wl_display_get_registry(display); + struct wl_display *display{Client::inst()->wl_display}; + struct wl_registry *registry{wl_display_get_registry(display)}; wl_registry_add_listener(registry, ®istry_listener_impl, this); wl_display_roundtrip(display); @@ -115,39 +109,42 @@ Tags::Tags(const std::string &id, const waybar::Bar &bar, const Json::Value &con box_.get_style_context()->add_class(id); } box_.get_style_context()->add_class(MODULE_CLASS); - event_box_.add(box_); // Default to 9 tags, cap at 32 - const uint32_t num_tags = - config["num-tags"].isUInt() ? std::min(32, config_["num-tags"].asUInt()) : 9; + const uint32_t num_tags{ + config["num-tags"].isUInt() ? std::min(32, config_["num-tags"].asUInt()) : 9}; std::vector tag_labels(num_tags); - for (uint32_t tag = 0; tag < num_tags; ++tag) { + for (uint32_t tag{0}; tag < num_tags; ++tag) { tag_labels[tag] = std::to_string(tag + 1); } - const Json::Value custom_labels = config["tag-labels"]; + const Json::Value custom_labels{config["tag-labels"]}; if (custom_labels.isArray() && !custom_labels.empty()) { - for (uint32_t tag = 0; tag < std::min(num_tags, custom_labels.size()); ++tag) { + for (uint32_t tag{0}; tag < std::min(num_tags, custom_labels.size()); ++tag) { tag_labels[tag] = custom_labels[tag].asString(); } } - uint32_t i = 1; + uint32_t i{1}; for (const auto &tag_label : tag_labels) { - Gtk::Button &button = buttons_.emplace_back(tag_label); - button.set_relief(Gtk::RELIEF_NONE); - box_.pack_start(button, false, false, 0); + Gtk::Button &button{buttons_.emplace_back(tag_label)}; + auto controlClick{clickControls_.emplace_back(Gtk::GestureClick::create())}; + controlClick->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); + controlClick->set_button(1u); + button.add_controller(controlClick); + button.set_has_frame(false); + box_.prepend(button); if (!config_["disable-click"].asBool()) { - button.signal_clicked().connect( + controlClick->signal_pressed().connect( + sigc::bind(sigc::mem_fun(*this, &Tags::handle_button_press), i, controlClick)); + controlClick->signal_released().connect( sigc::bind(sigc::mem_fun(*this, &Tags::handle_primary_clicked), i)); - button.signal_button_press_event().connect( - sigc::bind(sigc::mem_fun(*this, &Tags::handle_button_press), i)); } button.show(); i <<= 1; } - struct wl_output *output = gdk_wayland_monitor_get_wl_output(bar_.output->monitor->gobj()); + struct wl_output *output{gdk_wayland_monitor_get_wl_output(bar_.output->monitor->gobj())}; output_status_ = zdwl_ipc_manager_v2_get_output(status_manager_, output); zdwl_ipc_output_v2_add_listener(output_status_, &output_status_listener_impl, this); @@ -164,23 +161,22 @@ Tags::~Tags() { } } -void Tags::handle_primary_clicked(uint32_t tag) { +void Tags::handle_primary_clicked(int n_press, double dx, double dy, uint32_t tag) { if (!output_status_) return; - zdwl_ipc_output_v2_set_tags(output_status_, tag, 1); } -bool Tags::handle_button_press(GdkEventButton *event_button, uint32_t tag) { - if (event_button->type == GDK_BUTTON_PRESS && event_button->button == 3) { - if (!output_status_) return true; +void Tags::handle_button_press(int n_press, double dx, double dy, uint32_t tag, + Glib::RefPtr controlClick) { + if (controlClick->get_current_button() == 3) { + if (!output_status_) return; zdwl_ipc_output_v2_set_tags(output_status_, num_tags ^ tag, 0); } - return true; } void Tags::handle_view_tags(uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused) { // First clear all occupied state - auto &button = buttons_[tag]; + auto &button{buttons_[tag]}; if (clients) { button.get_style_context()->add_class("occupied"); } else { @@ -200,4 +196,6 @@ void Tags::handle_view_tags(uint32_t tag, uint32_t state, uint32_t clients, uint } } +Tags::operator Gtk::Widget &() { return box_; }; + } /* namespace waybar::modules::dwl */ diff --git a/src/modules/dwl/window.cpp b/src/modules/dwl/window.cpp index 870d87e4e..bd90e23b9 100644 --- a/src/modules/dwl/window.cpp +++ b/src/modules/dwl/window.cpp @@ -72,8 +72,8 @@ static void handle_global_remove(void *data, struct wl_registry *registry, uint3 static const wl_registry_listener registry_listener_impl = {.global = handle_global, .global_remove = handle_global_remove}; -Window::Window(const std::string &id, const Bar &bar, const Json::Value &config) - : AAppIconLabel(config, "window", id, "{}", 0, true), bar_(bar) { +Window::Window(const std::string &id, const waybar::Bar &bar, const Json::Value &config) + : AAppIconLabel(config, "window", id, "{}", 0, true), bar_{bar} { struct wl_display *display = Client::inst()->wl_display; struct wl_registry *registry = wl_display_get_registry(display); diff --git a/src/modules/gamemode.cpp b/src/modules/gamemode.cpp index 811f13ca0..f803685fb 100644 --- a/src/modules/gamemode.cpp +++ b/src/modules/gamemode.cpp @@ -1,32 +1,22 @@ #include "modules/gamemode.hpp" -#include +#include #include -#include -#include -#include - #include "AModule.hpp" -#include "giomm/dbusconnection.h" -#include "giomm/dbusinterface.h" -#include "giomm/dbusproxy.h" -#include "giomm/dbuswatchname.h" -#include "glibmm/error.h" -#include "glibmm/ustring.h" -#include "glibmm/variant.h" -#include "glibmm/varianttype.h" -#include "gtkmm/label.h" -#include "gtkmm/tooltip.h" -#include "util/gtk_icon.hpp" namespace waybar::modules { Gamemode::Gamemode(const std::string& id, const Json::Value& config) - : AModule(config, "gamemode", id), box_(Gtk::ORIENTATION_HORIZONTAL, 0), icon_(), label_() { - box_.pack_start(icon_); - box_.pack_start(label_); + : ALabel(config, "gamemode", id, "{}"), + box_(Gtk::Orientation::HORIZONTAL, 0), + icon_(), + label_() { + box_.prepend(icon_); + box_.prepend(label_); box_.set_name(name_); - event_box_.add(box_); + + // Get current theme + gtkTheme_ = Gtk::IconTheme::get_for_display(label_.get_display()); // Tooltip if (config_["tooltip"].isBool()) { @@ -82,13 +72,12 @@ Gamemode::Gamemode(const std::string& id, const Json::Value& config) } gamemodeWatcher_id = Gio::DBus::watch_name( - Gio::DBus::BUS_TYPE_SESSION, dbus_name, sigc::mem_fun(*this, &Gamemode::appear), - sigc::mem_fun(*this, &Gamemode::disappear), - Gio::DBus::BusNameWatcherFlags::BUS_NAME_WATCHER_FLAGS_AUTO_START); + Gio::DBus::BusType::SESSION, dbus_name, sigc::mem_fun(*this, &Gamemode::appear), + sigc::mem_fun(*this, &Gamemode::disappear), Gio::DBus::BusNameWatcherFlags::AUTO_START); // Connect to gamemode - gamemode_proxy = Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BusType::BUS_TYPE_SESSION, - dbus_name, dbus_obj_path, dbus_interface); + gamemode_proxy = Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BusType::SESSION, dbus_name, + dbus_obj_path, dbus_interface); if (!gamemode_proxy) { throw std::runtime_error("Unable to connect to gamemode DBus!..."); } else { @@ -96,7 +85,7 @@ Gamemode::Gamemode(const std::string& id, const Json::Value& config) } // Connect to Login1 PrepareForSleep signal - system_connection = Gio::DBus::Connection::get_sync(Gio::DBus::BusType::BUS_TYPE_SYSTEM); + system_connection = Gio::DBus::Connection::get_sync(Gio::DBus::BusType::SYSTEM); if (!system_connection) { throw std::runtime_error("Unable to connect to the SYSTEM Bus!..."); } else { @@ -104,8 +93,6 @@ Gamemode::Gamemode(const std::string& id, const Json::Value& config) sigc::mem_fun(*this, &Gamemode::prepareForSleep_cb), "org.freedesktop.login1", "org.freedesktop.login1.Manager", "PrepareForSleep", "/org/freedesktop/login1"); } - - event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &Gamemode::handleToggle)); } Gamemode::~Gamemode() { @@ -137,7 +124,7 @@ void Gamemode::getData() { } } } catch (Glib::Error& e) { - spdlog::error("Gamemode Error {}", e.what().c_str()); + spdlog::error("Gamemode Error {}", e.what()); } } gameCount = 0; @@ -172,7 +159,7 @@ void Gamemode::prepareForSleep_cb(const Glib::RefPtr& con void Gamemode::appear(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& name_owner) { gamemodeRunning = true; - event_box_.set_visible(true); + label_.set_visible(true); getData(); dp.emit(); } @@ -180,24 +167,23 @@ void Gamemode::appear(const Glib::RefPtr& connection, void Gamemode::disappear(const Glib::RefPtr& connection, const Glib::ustring& name) { gamemodeRunning = false; - event_box_.set_visible(false); + label_.set_visible(false); } -bool Gamemode::handleToggle(GdkEventButton* const& event) { +void Gamemode::handleToggle(int n_press, double dx, double dy) { showAltText = !showAltText; dp.emit(); - return true; } auto Gamemode::update() -> void { // Don't update widget if the Gamemode service isn't running if (!gamemodeRunning || (gameCount <= 0 && hideNotRunning)) { - event_box_.set_visible(false); + label_.set_visible(false); return; } // Show the module - if (!event_box_.get_visible()) event_box_.set_visible(true); + if (!label_.get_visible()) label_.set_visible(true); // CSS status class const std::string status = gamemodeRunning && gameCount > 0 ? "running" : ""; @@ -224,10 +210,8 @@ auto Gamemode::update() -> void { label_.set_markup(str); if (useIcon) { - if (!DefaultGtkIconThemeWrapper::has_icon(iconName)) { - iconName = DEFAULT_ICON_NAME; - } - icon_.set_from_icon_name(iconName, Gtk::ICON_SIZE_INVALID); + if (!gtkTheme_->has_icon(iconName)) iconName = DEFAULT_ICON_NAME; + icon_.set_from_icon_name(iconName); } // Call parent update diff --git a/src/modules/idle_inhibitor.cpp b/src/modules/idle_inhibitor.cpp index a5fc9ac73..caa88dc69 100644 --- a/src/modules/idle_inhibitor.cpp +++ b/src/modules/idle_inhibitor.cpp @@ -1,13 +1,15 @@ #include "modules/idle_inhibitor.hpp" +#include + #include "idle-inhibit-unstable-v1-client-protocol.h" -#include "util/command.hpp" -std::list waybar::modules::IdleInhibitor::modules; -bool waybar::modules::IdleInhibitor::status = false; +namespace waybar::modules { + +std::list IdleInhibitor::modules; +bool IdleInhibitor::status = false; -waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, - const Json::Value& config) +IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, const Json::Value& config) : ALabel(config, "idle_inhibitor", id, "{status}", 0, false, true), bar_(bar), idle_inhibitor_(nullptr), @@ -16,29 +18,25 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& throw std::runtime_error("idle-inhibit not available"); } - if (waybar::modules::IdleInhibitor::modules.empty() && config_["start-activated"].isBool() && + if (IdleInhibitor::modules.empty() && config_["start-activated"].isBool() && config_["start-activated"].asBool() != status) { toggleStatus(); } - event_box_.add_events(Gdk::BUTTON_PRESS_MASK); - event_box_.signal_button_press_event().connect( - sigc::mem_fun(*this, &IdleInhibitor::handleToggle)); - // Add this to the modules list - waybar::modules::IdleInhibitor::modules.push_back(this); + IdleInhibitor::modules.push_back(this); dp.emit(); } -waybar::modules::IdleInhibitor::~IdleInhibitor() { +IdleInhibitor::~IdleInhibitor() { if (idle_inhibitor_ != nullptr) { zwp_idle_inhibitor_v1_destroy(idle_inhibitor_); idle_inhibitor_ = nullptr; } // Remove this from the modules list - waybar::modules::IdleInhibitor::modules.remove(this); + IdleInhibitor::modules.remove(this); if (pid_ != -1) { kill(-pid_, 9); @@ -46,7 +44,7 @@ waybar::modules::IdleInhibitor::~IdleInhibitor() { } } -auto waybar::modules::IdleInhibitor::update() -> void { +auto IdleInhibitor::update() -> void { // Check status if (status) { label_.get_style_context()->remove_class("deactivated"); @@ -77,7 +75,7 @@ auto waybar::modules::IdleInhibitor::update() -> void { ALabel::update(); } -void waybar::modules::IdleInhibitor::toggleStatus() { +void IdleInhibitor::toggleStatus() { status = !status; if (timeout_.connected()) { @@ -96,7 +94,7 @@ void waybar::modules::IdleInhibitor::toggleStatus() { */ spdlog::info("deactivating idle_inhibitor by timeout"); status = false; - for (auto const& module : waybar::modules::IdleInhibitor::modules) { + for (auto const& module : IdleInhibitor::modules) { module->update(); } /* disconnect */ @@ -106,18 +104,19 @@ void waybar::modules::IdleInhibitor::toggleStatus() { } } -bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) { - if (e->button == 1) { +void IdleInhibitor::handleToggle(int n_press, double dx, double dy) { + if (AModule::controllClick_->get_current_button() == 1) { toggleStatus(); // Make all other idle inhibitor modules update - for (auto const& module : waybar::modules::IdleInhibitor::modules) { + for (auto const& module : IdleInhibitor::modules) { if (module != this) { module->update(); } } } - ALabel::handleToggle(e); - return true; + ALabel::handleToggle(n_press, dx, dy); } + +} /* namespace waybar::modules */ diff --git a/src/modules/image.cpp b/src/modules/image.cpp index 71e93b946..6a67c2250 100644 --- a/src/modules/image.cpp +++ b/src/modules/image.cpp @@ -1,14 +1,16 @@ #include "modules/image.hpp" -waybar::modules::Image::Image(const std::string& id, const Json::Value& config) - : AModule(config, "image", id), box_(Gtk::ORIENTATION_HORIZONTAL, 0) { - box_.pack_start(image_); +namespace waybar::modules { + +Image::Image(const std::string& id, const Json::Value& config) + : AModule(config, "image", id), box_(Gtk::Orientation::HORIZONTAL, 0) { + box_.append(image_); box_.set_name("image"); if (!id.empty()) { box_.get_style_context()->add_class(id); } box_.get_style_context()->add_class(MODULE_CLASS); - event_box_.add(box_); + AModule::bindEvents(box_); dp.emit(); @@ -27,15 +29,15 @@ waybar::modules::Image::Image(const std::string& id, const Json::Value& config) delayWorker(); } -void waybar::modules::Image::delayWorker() { +void Image::delayWorker() { thread_ = [this] { dp.emit(); - auto interval = std::chrono::seconds(interval_); + auto interval{std::chrono::seconds(interval_)}; thread_.sleep_for(interval); }; } -void waybar::modules::Image::refresh(int sig) { +void Image::refresh(int sig) { if (sig == SIGRTMIN + config_["signal"].asInt()) { thread_.wake_up(); } @@ -51,15 +53,8 @@ auto waybar::modules::Image::update() -> void { path_ = ""; } - if (Glib::file_test(path_, Glib::FILE_TEST_EXISTS)) { - Glib::RefPtr pixbuf; - - int scaled_icon_size = size_ * image_.get_scale_factor(); - pixbuf = Gdk::Pixbuf::create_from_file(path_, scaled_icon_size, scaled_icon_size); - - auto surface = Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image_.get_scale_factor(), - image_.get_window()); - image_.set(surface); + if (Glib::file_test(path_, Glib::FileTest::EXISTS)) { + image_.set(path_); image_.show(); if (tooltipEnabled() && !tooltip_.empty()) { @@ -78,10 +73,10 @@ auto waybar::modules::Image::update() -> void { AModule::update(); } -void waybar::modules::Image::parseOutputRaw() { +void Image::parseOutputRaw() { std::istringstream output(output_.out); std::string line; - int i = 0; + int i{0}; while (getline(output, line)) { if (i == 0) { path_ = line; @@ -93,3 +88,7 @@ void waybar::modules::Image::parseOutputRaw() { i++; } } + +Image::operator Gtk::Widget&() { return box_; }; + +} // namespace waybar::modules diff --git a/src/modules/inhibitor.cpp b/src/modules/inhibitor.cpp index fe2a4be41..1ea0e38df 100644 --- a/src/modules/inhibitor.cpp +++ b/src/modules/inhibitor.cpp @@ -1,7 +1,5 @@ #include "modules/inhibitor.hpp" -#include -#include #include namespace { @@ -97,12 +95,10 @@ auto getInhibitors(const Json::Value& config) -> std::string { namespace waybar::modules { -Inhibitor::Inhibitor(const std::string& id, const Bar& bar, const Json::Value& config) +Inhibitor::Inhibitor(const std::string& id, const Json::Value& config) : ALabel(config, "inhibitor", id, "{status}", true), dbus_(::dbus()), inhibitors_(::getInhibitors(config)) { - event_box_.add_events(Gdk::BUTTON_PRESS_MASK); - event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &Inhibitor::handleToggle)); dp.emit(); } @@ -129,20 +125,21 @@ auto Inhibitor::update() -> void { return ALabel::update(); } -auto Inhibitor::handleToggle(GdkEventButton* const& e) -> bool { - if (e->button == 1) { - if (activated()) { - ::close(handle_); - handle_ = -1; - } else { - handle_ = ::getLocks(dbus_, inhibitors_); - if (handle_ == -1) { - spdlog::error("cannot get inhibitor locks"); - } - } - } +auto Inhibitor::doAction(const std::string& name) -> void { + if (actionMap_[name]) { + (this->*actionMap_[name])(); + } else + spdlog::info("Inhibitor. Unsupported action \"{0}\"", name); +} - return ALabel::handleToggle(e); +void Inhibitor::toggle() { + if (activated()) { + ::close(handle_); + handle_ = -1; + } else { + handle_ = ::getLocks(dbus_, inhibitors_); + if (handle_ == -1) spdlog::error("cannot get inhibitor locks"); + } } } // namespace waybar::modules diff --git a/src/modules/keyboard_state.cpp b/src/modules/keyboard_state.cpp index 18ce0a7c4..0b987d1dd 100644 --- a/src/modules/keyboard_state.cpp +++ b/src/modules/keyboard_state.cpp @@ -1,20 +1,12 @@ #include "modules/keyboard_state.hpp" -#include #include -#include - -#include extern "C" { #include -#include -#include +#include #include #include -#include -#include -#include } class errno_error : public std::runtime_error { @@ -32,12 +24,12 @@ class errno_error : public std::runtime_error { #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 32) // strerrorname_np gets the error code's name; it's nice to have, but it's a recent GNU // extension - const auto errno_name = strerrorname_np(err); + const auto errno_name{strerrorname_np(err)}; error_msg += errno_name; error_msg += " "; #endif - const auto errno_str = strerror(err); + const auto errno_str{strerror(err)}; error_msg += errno_str; return error_msg; @@ -45,7 +37,7 @@ class errno_error : public std::runtime_error { }; auto openFile(const std::string& path, int flags) -> int { - int fd = open(path.c_str(), flags); + int fd{open(path.c_str(), flags)}; if (fd < 0) { if (errno == EACCES) { throw errno_error(errno, "Can't open " + path + " (are you in the input group?)"); @@ -57,7 +49,7 @@ auto openFile(const std::string& path, int flags) -> int { } auto closeFile(int fd) -> void { - int res = close(fd); + int res{close(fd)}; if (res < 0) { throw errno_error(errno, "Can't close file"); } @@ -65,7 +57,7 @@ auto closeFile(int fd) -> void { auto openDevice(int fd) -> libevdev* { libevdev* dev; - int err = libevdev_new_from_fd(fd, &dev); + int err{libevdev_new_from_fd(fd, &dev)}; if (err < 0) { throw errno_error(-err, "Can't create libevdev device"); } @@ -78,38 +70,40 @@ auto supportsLockStates(const libevdev* dev) -> bool { libevdev_has_event_code(dev, EV_LED, LED_SCROLLL); } -waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar& bar, - const Json::Value& config) +namespace waybar::modules { + +KeyboardState::KeyboardState(const std::string& id, const Bar& bar, const Json::Value& config) : AModule(config, "keyboard-state", id, false, !config["disable-scroll"].asBool()), - box_(bar.orientation, 0), - numlock_label_(""), - capslock_label_(""), - numlock_format_(config_["format"].isString() ? config_["format"].asString() + box_{bar.orientation, 0}, + numlock_label_{""}, + capslock_label_{""}, + numlock_format_{config_["format"].isString() ? config_["format"].asString() : config_["format"]["numlock"].isString() ? config_["format"]["numlock"].asString() - : "{name} {icon}"), - capslock_format_(config_["format"].isString() ? config_["format"].asString() + : "{name} {icon}"}, + capslock_format_{config_["format"].isString() ? config_["format"].asString() : config_["format"]["capslock"].isString() ? config_["format"]["capslock"].asString() - : "{name} {icon}"), - scrolllock_format_(config_["format"].isString() ? config_["format"].asString() + : "{name} {icon}"}, + scrolllock_format_{config_["format"].isString() ? config_["format"].asString() : config_["format"]["scrolllock"].isString() ? config_["format"]["scrolllock"].asString() - : "{name} {icon}"), - interval_( - std::chrono::seconds(config_["interval"].isUInt() ? config_["interval"].asUInt() : 1)), - icon_locked_(config_["format-icons"]["locked"].isString() + : "{name} {icon}"}, + interval_{ + std::chrono::seconds(config_["interval"].isUInt() ? config_["interval"].asUInt() : 1)}, + icon_locked_{config_["format-icons"]["locked"].isString() ? config_["format-icons"]["locked"].asString() - : "locked"), - icon_unlocked_(config_["format-icons"]["unlocked"].isString() + : "locked"}, + icon_unlocked_{config_["format-icons"]["unlocked"].isString() ? config_["format-icons"]["unlocked"].asString() - : "unlocked"), - devices_path_("/dev/input/"), - libinput_(nullptr), - libinput_devices_({}) { - static struct libinput_interface interface = { - [](const char* path, int flags, void* user_data) { return open(path, flags); }, - [](int fd, void* user_data) { close(fd); }}; + : "unlocked"}, + devices_path_{"/dev/input/"}, + libinput_{nullptr}, + libinput_devices_{{}} { + static struct libinput_interface interface { + [](const char* path, int flags, void* user_data) { return open(path, flags); }, + [](int fd, void* user_data) { close(fd); } + }; if (config_["interval"].isUInt()) { spdlog::warn("keyboard-state: interval is deprecated"); } @@ -119,31 +113,32 @@ waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar& box_.set_name("keyboard-state"); if (config_["numlock"].asBool()) { numlock_label_.get_style_context()->add_class("numlock"); - box_.pack_end(numlock_label_, false, false, 0); + box_.append(numlock_label_); } if (config_["capslock"].asBool()) { capslock_label_.get_style_context()->add_class("capslock"); - box_.pack_end(capslock_label_, false, false, 0); + box_.append(capslock_label_); } if (config_["scrolllock"].asBool()) { scrolllock_label_.get_style_context()->add_class("scrolllock"); - box_.pack_end(scrolllock_label_, false, false, 0); + box_.append(scrolllock_label_); } if (!id.empty()) { box_.get_style_context()->add_class(id); } box_.get_style_context()->add_class(MODULE_CLASS); - event_box_.add(box_); if (config_["device-path"].isString()) { - std::string dev_path = config_["device-path"].asString(); + std::string dev_path{config_["device-path"].asString()}; tryAddDevice(dev_path); if (libinput_devices_.empty()) { spdlog::error("keyboard-state: Cannot find device {}", dev_path); } } - auto keys = config_["binding-keys"]; + AModule::bindEvents(box_); + + auto keys{config_["binding-keys"]}; if (keys.isArray()) { for (const auto& key : keys) { if (key.isInt()) { @@ -158,14 +153,14 @@ waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar& binding_keys.insert(KEY_SCROLLLOCK); } - DIR* dev_dir = opendir(devices_path_.c_str()); + DIR* dev_dir{opendir(devices_path_.c_str())}; if (dev_dir == nullptr) { throw errno_error(errno, "Failed to open " + devices_path_); } dirent* ep; while ((ep = readdir(dev_dir))) { if (ep->d_type == DT_DIR) continue; - std::string dev_path = devices_path_ + ep->d_name; + std::string dev_path{devices_path_ + ep->d_name}; tryAddDevice(dev_path); } @@ -176,17 +171,19 @@ waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar& libinput_thread_ = [this] { dp.emit(); while (1) { - struct pollfd fd = {libinput_get_fd(libinput_), POLLIN, 0}; + struct pollfd fd { + libinput_get_fd(libinput_), POLLIN, 0 + }; poll(&fd, 1, -1); libinput_dispatch(libinput_); struct libinput_event* event; while ((event = libinput_get_event(libinput_))) { - auto type = libinput_event_get_type(event); + auto type{libinput_event_get_type(event)}; if (type == LIBINPUT_EVENT_KEYBOARD_KEY) { - auto keyboard_event = libinput_event_get_keyboard_event(event); - auto state = libinput_event_keyboard_get_key_state(keyboard_event); + auto keyboard_event{libinput_event_get_keyboard_event(event)}; + auto state{libinput_event_keyboard_get_key_state(keyboard_event)}; if (state == LIBINPUT_KEY_STATE_RELEASED) { - uint32_t key = libinput_event_keyboard_get_key(keyboard_event); + uint32_t key{libinput_event_keyboard_get_key(keyboard_event)}; if (binding_keys.contains(key)) { dp.emit(); } @@ -206,22 +203,22 @@ waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar& } inotify_add_watch(fd, devices_path_.c_str(), IN_CREATE | IN_DELETE); while (1) { - int BUF_LEN = 1024 * (sizeof(struct inotify_event) + 16); + int BUF_LEN{1024 * (sizeof(struct inotify_event) + 16)}; char buf[BUF_LEN]; - int length = read(fd, buf, 1024); + int length{read(fd, buf, 1024)}; if (length < 0) { spdlog::error("Failed to read inotify: {}", strerror(errno)); return; } - for (int i = 0; i < length;) { - struct inotify_event* event = (struct inotify_event*)&buf[i]; - std::string dev_path = devices_path_ + event->name; + for (int i{0}; i < length;) { + struct inotify_event* event{(struct inotify_event*)&buf[i]}; + std::string dev_path{devices_path_ + event->name}; if (event->mask & IN_CREATE) { // Wait for device setup - int timeout = 10; + int timeout{10}; while (timeout--) { try { - int fd = openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY); + int fd{openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY)}; closeFile(fd); break; } catch (const errno_error& e) { @@ -232,7 +229,7 @@ waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar& } tryAddDevice(dev_path); } else if (event->mask & IN_DELETE) { - auto it = libinput_devices_.find(dev_path); + auto it{libinput_devices_.find(dev_path)}; if (it != libinput_devices_.end()) { spdlog::info("Keyboard {} has been removed.", dev_path); libinput_devices_.erase(it); @@ -244,15 +241,15 @@ waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar& }; } -waybar::modules::KeyboardState::~KeyboardState() { +KeyboardState::~KeyboardState() { for (const auto& [_, dev_ptr] : libinput_devices_) { libinput_path_remove_device(dev_ptr); } } -auto waybar::modules::KeyboardState::update() -> void { +auto KeyboardState::update() -> void { sleep(0); // Wait for keyboard status change - int numl = 0, capsl = 0, scrolll = 0; + int numl{0}, capsl{0}, scrolll{0}; try { std::string dev_path; @@ -262,8 +259,8 @@ auto waybar::modules::KeyboardState::update() -> void { } else { dev_path = libinput_devices_.begin()->first; } - int fd = openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY); - auto dev = openDevice(fd); + int fd{openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY)}; + auto dev{openDevice(fd)}; numl = libevdev_get_event_value(dev, EV_LED, LED_NUML); capsl = libevdev_get_event_value(dev, EV_LED, LED_CAPSL); scrolll = libevdev_get_event_value(dev, EV_LED, LED_SCROLLL); @@ -281,16 +278,16 @@ auto waybar::modules::KeyboardState::update() -> void { Gtk::Label& label; const std::string& format; const char* name; - } label_states[] = { + } label_states[]{ {(bool)numl, numlock_label_, numlock_format_, "Num"}, {(bool)capsl, capslock_label_, capslock_format_, "Caps"}, {(bool)scrolll, scrolllock_label_, scrolllock_format_, "Scroll"}, }; for (auto& label_state : label_states) { - std::string text; - text = fmt::format(fmt::runtime(label_state.format), - fmt::arg("icon", label_state.state ? icon_locked_ : icon_unlocked_), - fmt::arg("name", label_state.name)); + std::string text{ + fmt::format(fmt::runtime(label_state.format), + fmt::arg("icon", label_state.state ? icon_locked_ : icon_unlocked_), + fmt::arg("name", label_state.name))}; label_state.label.set_markup(text); if (label_state.state) { label_state.label.get_style_context()->add_class("locked"); @@ -302,14 +299,14 @@ auto waybar::modules::KeyboardState::update() -> void { AModule::update(); } -auto waybar::modules ::KeyboardState::tryAddDevice(const std::string& dev_path) -> void { +auto KeyboardState::tryAddDevice(const std::string& dev_path) -> void { try { - int fd = openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY); - auto dev = openDevice(fd); + int fd{openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY)}; + auto dev{openDevice(fd)}; if (supportsLockStates(dev)) { spdlog::info("Found device {} at '{}'", libevdev_get_name(dev), dev_path); if (libinput_devices_.find(dev_path) == libinput_devices_.end()) { - auto device = libinput_path_add_device(libinput_, dev_path.c_str()); + auto device{libinput_path_add_device(libinput_, dev_path.c_str())}; libinput_device_ref(device); libinput_devices_[dev_path] = device; } @@ -323,3 +320,7 @@ auto waybar::modules ::KeyboardState::tryAddDevice(const std::string& dev_path) } } } + +KeyboardState::operator Gtk::Widget&() { return box_; }; + +} // namespace waybar::modules diff --git a/src/modules/load.cpp b/src/modules/load.cpp index 69a37b4eb..dd25cc268 100644 --- a/src/modules/load.cpp +++ b/src/modules/load.cpp @@ -1,5 +1,7 @@ #include "modules/load.hpp" +#include + // In the 80000 version of fmt library authors decided to optimize imports // and moved declarations required for fmt::dynamic_format_arg_store in new // header fmt/args.h @@ -31,9 +33,9 @@ auto waybar::modules::Load::update() -> void { } if (format.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); auto icons = std::vector{state}; fmt::dynamic_format_arg_store store; store.push_back(fmt::arg("load1", load1)); diff --git a/src/modules/memory/common.cpp b/src/modules/memory/common.cpp index 544d78145..52d2f193f 100644 --- a/src/modules/memory/common.cpp +++ b/src/modules/memory/common.cpp @@ -1,3 +1,5 @@ +#include + #include "modules/memory.hpp" waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config) @@ -51,9 +53,9 @@ auto waybar::modules::Memory::update() -> void { } if (format.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); auto icons = std::vector{state}; label_.set_markup(fmt::format( fmt::runtime(format), used_ram_percentage, @@ -80,7 +82,7 @@ auto waybar::modules::Memory::update() -> void { } } } else { - event_box_.hide(); + label_.hide(); } // Call parent update ALabel::update(); diff --git a/src/modules/memory/linux.cpp b/src/modules/memory/linux.cpp index 50f50d6f1..7e7cc0203 100644 --- a/src/modules/memory/linux.cpp +++ b/src/modules/memory/linux.cpp @@ -1,3 +1,5 @@ +#include + #include "modules/memory.hpp" static unsigned zfsArcSize() { diff --git a/src/modules/mpd/mpd.cpp b/src/modules/mpd/mpd.cpp index 192e6c1ad..b12474d6f 100644 --- a/src/modules/mpd/mpd.cpp +++ b/src/modules/mpd/mpd.cpp @@ -40,8 +40,7 @@ waybar::modules::MPD::MPD(const std::string& id, const Json::Value& config) server_ = config["server"].asCString(); } - event_box_.add_events(Gdk::BUTTON_PRESS_MASK); - event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &MPD::handlePlayPause)); + controllClick_->signal_pressed().connect(sigc::mem_fun(*this, &MPD::handlePlayPause), false); } auto waybar::modules::MPD::update() -> void { @@ -354,19 +353,17 @@ void waybar::modules::MPD::fetchState() { checkErrors(conn); } -bool waybar::modules::MPD::handlePlayPause(GdkEventButton* const& e) { - if (e->type == GDK_2BUTTON_PRESS || e->type == GDK_3BUTTON_PRESS || connection_ == nullptr) { - return false; - } +void waybar::modules::MPD::handlePlayPause(int n_press, double dx, double dy) { + if (n_press != 1 || connection_ == nullptr) return; + + auto button{controllClick_->get_current_button()}; - if (e->button == 1) { + if (button == 1u) { if (state_ == MPD_STATE_PLAY) context_.pause(); else context_.play(); - } else if (e->button == 3) { + } else if (button == 3u) { context_.stop(); } - - return true; } diff --git a/src/modules/mpd/state.cpp b/src/modules/mpd/state.cpp index 3d7c8561e..7bc2b0e00 100644 --- a/src/modules/mpd/state.cpp +++ b/src/modules/mpd/state.cpp @@ -66,10 +66,11 @@ void Idle::entry() noexcept { spdlog::error("mpd: Idle: failed to register for IDLE events"); } else { spdlog::debug("mpd: Idle: watching FD"); - sigc::slot idle_slot = sigc::mem_fun(*this, &Idle::on_io); + sigc::slot idle_slot = sigc::mem_fun(*this, &Idle::on_io); idle_connection_ = Glib::signal_io().connect(idle_slot, mpd_connection_get_fd(conn), - Glib::IO_IN | Glib::IO_PRI | Glib::IO_ERR | Glib::IO_HUP); + Glib::IOCondition::IO_IN | Glib::IOCondition::IO_PRI | + Glib::IOCondition::IO_ERR | Glib::IOCondition::IO_HUP); } } @@ -118,7 +119,7 @@ bool Idle::on_io(Glib::IOCondition const&) { } void Playing::entry() noexcept { - sigc::slot timer_slot = sigc::mem_fun(*this, &Playing::on_timer); + sigc::slot timer_slot = sigc::mem_fun(*this, &Playing::on_timer); timer_connection_ = Glib::signal_timeout().connect_seconds(timer_slot, 1); spdlog::debug("mpd: Playing: enabled 1 second periodic timer."); } @@ -186,7 +187,7 @@ void Playing::pause() { void Playing::update() noexcept { ctx_->do_update(); } void Paused::entry() noexcept { - sigc::slot timer_slot = sigc::mem_fun(*this, &Paused::on_timer); + sigc::slot timer_slot = sigc::mem_fun(*this, &Paused::on_timer); timer_connection_ = Glib::signal_timeout().connect(timer_slot, /* milliseconds */ 200); spdlog::debug("mpd: Paused: enabled 200 ms periodic timer."); } @@ -257,7 +258,7 @@ void Paused::stop() { void Paused::update() noexcept { ctx_->do_update(); } void Stopped::entry() noexcept { - sigc::slot timer_slot = sigc::mem_fun(*this, &Stopped::on_timer); + sigc::slot timer_slot = sigc::mem_fun(*this, &Stopped::on_timer); timer_connection_ = Glib::signal_timeout().connect(timer_slot, /* milliseconds */ 200); spdlog::debug("mpd: Stopped: enabled 200 ms periodic timer."); } @@ -337,7 +338,7 @@ bool Disconnected::arm_timer(int interval) noexcept { // register timer last_interval_ = interval; - sigc::slot timer_slot = sigc::mem_fun(*this, &Disconnected::on_timer); + sigc::slot timer_slot = sigc::mem_fun(*this, &Disconnected::on_timer); timer_connection_ = Glib::signal_timeout().connect_seconds(timer_slot, interval); spdlog::debug("mpd: Disconnected: enabled {}s interval timer.", interval); return false; diff --git a/src/modules/mpris/mpris.cpp b/src/modules/mpris.cpp similarity index 98% rename from src/modules/mpris/mpris.cpp rename to src/modules/mpris.cpp index ed383b0ce..8495dc166 100644 --- a/src/modules/mpris/mpris.cpp +++ b/src/modules/mpris.cpp @@ -1,4 +1,4 @@ -#include "modules/mpris/mpris.hpp" +#include "modules/mpris.hpp" #include @@ -13,6 +13,7 @@ extern "C" { } #include +#include #include namespace waybar::modules::mpris { @@ -459,7 +460,7 @@ auto Mpris::onPlayerStop(PlayerctlPlayer* player, gpointer data) -> void { spdlog::debug("mpris: player-stop callback"); // hide widget - mpris->event_box_.set_visible(false); + mpris->label_.set_visible(false); // update widget mpris->dp.emit(); } @@ -583,7 +584,7 @@ auto Mpris::getPlayerInfo() -> std::optional { return std::nullopt; } -bool Mpris::handleToggle(GdkEventButton* const& e) { +void Mpris::handleToggle(int n_press, double dx, double dy) { GError* error = nullptr; waybar::util::ScopeGuard error_deleter([error]() { if (error) { @@ -592,36 +593,33 @@ bool Mpris::handleToggle(GdkEventButton* const& e) { }); auto info = getPlayerInfo(); - if (!info) return false; + if (!info) return; - if (e->type == GdkEventType::GDK_BUTTON_PRESS) { - switch (e->button) { + if (n_press == 1) { + switch (controllClick_->get_current_button()) { case 1: // left-click if (config_["on-click"].isString()) { - return ALabel::handleToggle(e); + return ALabel::handleToggle(n_press, dx, dy); } playerctl_player_play_pause(player, &error); break; case 2: // middle-click if (config_["on-click-middle"].isString()) { - return ALabel::handleToggle(e); + return ALabel::handleToggle(n_press, dx, dy); } playerctl_player_previous(player, &error); break; case 3: // right-click if (config_["on-click-right"].isString()) { - return ALabel::handleToggle(e); + return ALabel::handleToggle(n_press, dx, dy); } playerctl_player_next(player, &error); break; } } - if (error) { + if (error) spdlog::error("mpris[{}]: error running builtin on-click action: {}", (*info).name, error->message); - return false; - } - return true; } auto Mpris::update() -> void { @@ -631,7 +629,7 @@ auto Mpris::update() -> void { auto opt = getPlayerInfo(); if (!opt) { - event_box_.set_visible(false); + label_.set_visible(false); ALabel::update(); return; } @@ -729,7 +727,7 @@ auto Mpris::update() -> void { } } - event_box_.set_visible(true); + label_.set_visible(true); // call parent update ALabel::update(); } diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 0bbea6315..70bb2690d 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -1,29 +1,27 @@ #include "modules/network.hpp" +#include +#include #include +#include +#include #include #include -#include #include -#include -#include #include "util/format.hpp" -#ifdef WANT_RFKILL -#include "util/rfkill.hpp" -#endif namespace { using namespace waybar::util; -constexpr const char *DEFAULT_FORMAT = "{ifname}"; +constexpr const char *DEFAULT_FORMAT{"{ifname}"}; } // namespace -constexpr const char *NETDEV_FILE = - "/proc/net/dev"; // std::ifstream does not take std::string_view as param +constexpr const char *NETDEV_FILE{ + "/proc/net/dev"}; // std::ifstream does not take std::string_view as param std::optional> waybar::modules::Network::readBandwidthUsage() { - std::ifstream netdev(NETDEV_FILE); + std::ifstream netdev{NETDEV_FILE}; if (!netdev) { spdlog::warn("Failed to open netdev file {}", NETDEV_FILE); return {}; @@ -34,10 +32,10 @@ waybar::modules::Network::readBandwidthUsage() { std::getline(netdev, line); std::getline(netdev, line); - unsigned long long receivedBytes = 0ull; - unsigned long long transmittedBytes = 0ull; + unsigned long long receivedBytes{0ull}; + unsigned long long transmittedBytes{0ull}; while (std::getline(netdev, line)) { - std::istringstream iss(line); + std::istringstream iss{line}; std::string ifacename; iss >> ifacename; // ifacename contains "eth0:" @@ -52,12 +50,12 @@ waybar::modules::Network::readBandwidthUsage() { // // We only care about the bytes count, so we'll just ignore the 7 other // columns. - unsigned long long r = 0ull; - unsigned long long t = 0ull; + unsigned long long r{0ull}; + unsigned long long t{0ull}; // Read received bytes iss >> r; // Skip all the other columns in the received group - for (int colsToSkip = 7; colsToSkip > 0; colsToSkip--) { + for (int colsToSkip{7}; colsToSkip > 0; colsToSkip--) { // skip whitespace between columns while (iss.peek() == ' ') { iss.ignore(); @@ -79,22 +77,22 @@ waybar::modules::Network::readBandwidthUsage() { waybar::modules::Network::Network(const std::string &id, const Json::Value &config) : ALabel(config, "network", id, DEFAULT_FORMAT, 60), - ifid_(-1), - family_(config["family"] == "ipv6" ? AF_INET6 : AF_INET), - efd_(-1), - ev_fd_(-1), - want_route_dump_(false), - want_link_dump_(false), - want_addr_dump_(false), - dump_in_progress_(false), - is_p2p_(false), - cidr_(0), - signal_strength_dbm_(0), - signal_strength_(0), + ifid_{-1}, + family_{config["family"] == "ipv6" ? AF_INET6 : AF_INET}, + efd_{-1}, + ev_fd_{-1}, + want_route_dump_{false}, + want_link_dump_{false}, + want_addr_dump_{false}, + dump_in_progress_{false}, + is_p2p_{false}, + cidr_{0}, + signal_strength_dbm_{0}, + signal_strength_{0}, #ifdef WANT_RFKILL rfkill_{RFKILL_TYPE_WLAN}, #endif - frequency_(0.0) { + frequency_{0.0} { // Start with some "text" in the module's label_. update() will then // update it. Since the text should be different, update() will be able @@ -102,7 +100,7 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf // the module start with no text, but the event_box_ is shown. label_.set_markup(""); - auto bandwidth = readBandwidthUsage(); + auto bandwidth{readBandwidthUsage()}; if (bandwidth.has_value()) { bandwidth_down_total_ = (*bandwidth).first; bandwidth_up_total_ = (*bandwidth).second; @@ -161,7 +159,7 @@ void waybar::modules::Network::createEventSocket() { nl_socket_disable_seq_check(ev_sock_); nl_socket_modify_cb(ev_sock_, NL_CB_VALID, NL_CB_CUSTOM, handleEvents, this); nl_socket_modify_cb(ev_sock_, NL_CB_FINISH, NL_CB_CUSTOM, handleEventsDone, this); - auto groups = RTMGRP_LINK | (family_ == AF_INET ? RTMGRP_IPV4_IFADDR : RTMGRP_IPV6_IFADDR); + auto groups{RTMGRP_LINK | (family_ == AF_INET ? RTMGRP_IPV4_IFADDR : RTMGRP_IPV6_IFADDR)}; nl_join_groups(ev_sock_, groups); // Deprecated if (nl_connect(ev_sock_, NETLINK_ROUTE) != 0) { throw std::runtime_error("Can't connect network socket"); @@ -198,7 +196,7 @@ void waybar::modules::Network::createEventSocket() { } } { - auto fd = nl_socket_get_fd(ev_sock_); + auto fd{nl_socket_get_fd(ev_sock_)}; struct epoll_event event; memset(&event, 0, sizeof(event)); event.events = EPOLLIN | EPOLLET | EPOLLRDHUP; @@ -227,7 +225,7 @@ void waybar::modules::Network::worker() { // update via here not working thread_timer_ = [this] { { - std::lock_guard lock(mutex_); + std::lock_guard lock{mutex_}; if (ifid_ > 0) { getInfo(); dp.emit(); @@ -249,11 +247,11 @@ void waybar::modules::Network::worker() { thread_ = [this] { std::array events{}; - int ec = epoll_wait(efd_, events.data(), EPOLL_MAX, -1); + int ec{epoll_wait(efd_, events.data(), EPOLL_MAX, -1)}; if (ec > 0) { - for (auto i = 0; i < ec; i++) { + for (auto i{0}; i < ec; i++) { if (events[i].data.fd == nl_socket_get_fd(ev_sock_)) { - int rc = 0; + int rc{0}; // Read as many message as possible, until the socket blocks while (true) { errno = 0; @@ -291,15 +289,15 @@ const std::string waybar::modules::Network::getNetworkState() const { } auto waybar::modules::Network::update() -> void { - std::lock_guard lock(mutex_); + std::lock_guard lock{mutex_}; std::string tooltip_format; - auto bandwidth = readBandwidthUsage(); - auto bandwidth_down = 0ull; - auto bandwidth_up = 0ull; + auto bandwidth{readBandwidthUsage()}; + auto bandwidth_down{0ull}; + auto bandwidth_up{0ull}; if (bandwidth.has_value()) { - auto down_octets = (*bandwidth).first; - auto up_octets = (*bandwidth).second; + auto down_octets{(*bandwidth).first}; + auto up_octets{(*bandwidth).second}; bandwidth_down = down_octets - bandwidth_down_total_; bandwidth_down_total_ = down_octets; @@ -309,7 +307,7 @@ auto waybar::modules::Network::update() -> void { } if (!alt_) { - auto state = getNetworkState(); + auto state{getNetworkState()}; if (!state_.empty() && label_.get_style_context()->has_class(state_)) { label_.get_style_context()->remove_class(state_); } @@ -331,7 +329,7 @@ auto waybar::modules::Network::update() -> void { } getState(signal_strength_); - auto text = fmt::format( + const Glib::ustring text{fmt::format( 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_), @@ -349,13 +347,13 @@ auto waybar::modules::Network::update() -> void { fmt::arg("bandwidthDownBytes", pow_format(bandwidth_down / interval_.count(), "B/s")), fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / interval_.count(), "B/s")), fmt::arg("bandwidthTotalBytes", - pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s"))); + pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s")))}; if (text.compare(label_.get_label()) != 0) { label_.set_markup(text); if (text.empty()) { - event_box_.hide(); + label_.hide(); } else { - event_box_.show(); + label_.show(); } } if (tooltipEnabled()) { @@ -363,7 +361,7 @@ auto waybar::modules::Network::update() -> void { tooltip_format = config_["tooltip-format"].asString(); } if (!tooltip_format.empty()) { - auto tooltip_text = fmt::format( + const Glib::ustring tooltip_text{fmt::format( 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_), @@ -382,7 +380,7 @@ auto waybar::modules::Network::update() -> void { fmt::arg("bandwidthDownBytes", pow_format(bandwidth_down / interval_.count(), "B/s")), fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / interval_.count(), "B/s")), fmt::arg("bandwidthTotalBytes", - pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s"))); + pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s")))}; if (label_.get_tooltip_text() != tooltip_text) { label_.set_tooltip_markup(tooltip_text); } @@ -420,20 +418,20 @@ void waybar::modules::Network::clearIface() { } int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { - auto net = static_cast(data); - std::lock_guard lock(net->mutex_); - auto nh = nlmsg_hdr(msg); - bool is_del_event = false; + auto net{static_cast(data)}; + std::lock_guard lock{net->mutex_}; + auto nh{nlmsg_hdr(msg)}; + bool is_del_event{false}; switch (nh->nlmsg_type) { case RTM_DELLINK: is_del_event = true; case RTM_NEWLINK: { - struct ifinfomsg *ifi = static_cast(NLMSG_DATA(nh)); - ssize_t attrlen = IFLA_PAYLOAD(nh); - struct rtattr *ifla = IFLA_RTA(ifi); - const char *ifname = NULL; - size_t ifname_len = 0; + struct ifinfomsg *ifi{static_cast(NLMSG_DATA(nh))}; + ssize_t attrlen{IFLA_PAYLOAD(nh)}; + struct rtattr *ifla{IFLA_RTA(ifi)}; + const char *ifname{NULL}; + size_t ifname_len{0}; std::optional carrier; if (net->ifid_ != -1 && ifi->ifi_index != net->ifid_) { @@ -471,7 +469,7 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { if (!is_del_event && ifi->ifi_index == net->ifid_) { // Update interface information if (net->ifname_.empty() && ifname != NULL) { - std::string new_ifname(ifname, ifname_len); + std::string new_ifname{ifname, ifname_len}; net->ifname_ = new_ifname; } if (carrier.has_value()) { @@ -493,7 +491,7 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { } } else if (!is_del_event && net->ifid_ == -1) { // Checking if it's an interface we care about. - std::string new_ifname(ifname, ifname_len); + std::string new_ifname{ifname, ifname_len}; if (net->checkInterface(new_ifname)) { spdlog::debug("network: selecting new interface {}/{}", new_ifname, ifi->ifi_index); @@ -523,9 +521,9 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { case RTM_DELADDR: is_del_event = true; case RTM_NEWADDR: { - struct ifaddrmsg *ifa = static_cast(NLMSG_DATA(nh)); - ssize_t attrlen = IFA_PAYLOAD(nh); - struct rtattr *ifa_rta = IFA_RTA(ifa); + struct ifaddrmsg *ifa{static_cast(NLMSG_DATA(nh))}; + ssize_t attrlen{IFA_PAYLOAD(nh)}; + struct rtattr *ifa_rta{IFA_RTA(ifa)}; if ((int)ifa->ifa_index != net->ifid_) { return NL_OK; @@ -558,8 +556,8 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { } case AF_INET6: { struct in6_addr netmask; - for (int i = 0; i < 16; i++) { - int v = (i + 1) * 8 - ifa->ifa_prefixlen; + for (int i{0}; i < 16; i++) { + int v{(i + 1) * 8 - ifa->ifa_prefixlen}; if (v < 0) v = 0; if (v > 8) v = 8; netmask.s6_addr[i] = ~0 << v; @@ -590,13 +588,13 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { // Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698 // to find the interface used to reach the outside world - struct rtmsg *rtm = static_cast(NLMSG_DATA(nh)); - ssize_t attrlen = RTM_PAYLOAD(nh); - struct rtattr *attr = RTM_RTA(rtm); - bool has_gateway = false; - bool has_destination = false; - int temp_idx = -1; - uint32_t priority = 0; + struct rtmsg *rtm{static_cast(NLMSG_DATA(nh))}; + ssize_t attrlen{RTM_PAYLOAD(nh)}; + struct rtattr *attr{RTM_RTA(rtm)}; + bool has_gateway{false}; + bool has_destination{false}; + int temp_idx{-1}; + uint32_t priority{0}; /* Find the message(s) concerting the main routing table, each message * corresponds to a single routing table entry. @@ -625,13 +623,13 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { /* The destination address. * Should be either missing, or maybe all 0s. Accept both. */ - const uint32_t nr_zeroes = (net->family_ == AF_INET) ? 4 : 16; - unsigned char c = 0; - size_t dstlen = RTA_PAYLOAD(attr); + const uint32_t nr_zeroes{(net->family_ == AF_INET) ? 4 : 16}; + unsigned char c{0}; + size_t dstlen{RTA_PAYLOAD(attr)}; if (dstlen != nr_zeroes) { break; } - for (uint32_t i = 0; i < dstlen; i += 1) { + for (uint32_t i{0}; i < dstlen; i += 1) { c |= *((unsigned char *)RTA_DATA(attr) + i); } has_destination = (c == 0); @@ -668,9 +666,8 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { temp_idx, priority); /* Ask ifname associated with temp_idx as well as carrier status */ - struct ifinfomsg ifinfo_hdr = { - .ifi_family = AF_UNSPEC, - .ifi_index = temp_idx, + struct ifinfomsg ifinfo_hdr { + .ifi_family = AF_UNSPEC, .ifi_index = temp_idx, }; int err; err = nl_send_simple(net->ev_sock_, RTM_GETLINK, NLM_F_REQUEST, &ifinfo_hdr, @@ -712,8 +709,8 @@ void waybar::modules::Network::askForStateDump(void) { * messages. handleEventsDone() is called when a dump is done. */ if (dump_in_progress_) return; - struct rtgenmsg rt_hdr = { - .rtgen_family = AF_UNSPEC, + struct rtgenmsg rt_hdr { + .rtgen_family = AF_UNSPEC, }; if (want_route_dump_) { @@ -736,15 +733,15 @@ void waybar::modules::Network::askForStateDump(void) { } int waybar::modules::Network::handleEventsDone(struct nl_msg *msg, void *data) { - auto net = static_cast(data); + auto net{static_cast(data)}; net->dump_in_progress_ = false; net->askForStateDump(); return NL_OK; } int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) { - auto net = static_cast(data); - auto gnlh = static_cast(nlmsg_data(nlmsg_hdr(msg))); + auto net{static_cast(data)}; + auto gnlh{static_cast(nlmsg_data(nlmsg_hdr(msg)))}; struct nlattr *tb[NL80211_ATTR_MAX + 1]; struct nlattr *bss[NL80211_BSS_MAX + 1]; struct nla_policy bss_policy[NL80211_BSS_MAX + 1]{}; @@ -780,16 +777,16 @@ int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) { void waybar::modules::Network::parseEssid(struct nlattr **bss) { if (bss[NL80211_BSS_INFORMATION_ELEMENTS] != nullptr) { - auto ies = static_cast(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS])); - auto ies_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]); - const auto hdr_len = 2; + auto ies{static_cast(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]))}; + auto ies_len{nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS])}; + const auto hdr_len{2}; while (ies_len > hdr_len && ies[0] != 0) { ies_len -= ies[1] + hdr_len; ies += ies[1] + hdr_len; } if (ies_len > hdr_len && ies_len > ies[1] + hdr_len) { - auto essid_begin = ies + hdr_len; - auto essid_end = essid_begin + ies[1]; + auto essid_begin{ies + hdr_len}; + auto essid_end{essid_begin + ies[1]}; std::string essid_raw; std::copy(essid_begin, essid_end, std::back_inserter(essid_raw)); essid_ = Glib::Markup::escape_text(essid_raw); @@ -806,12 +803,11 @@ void waybar::modules::Network::parseSignal(struct nlattr **bss) { // If a signal is too strong, it can overwhelm receiving circuity that is designed // to pick up and process a certain signal level. The following percentage is scaled to // punish signals that are too strong (>= -45dBm) or too weak (<= -45 dBm). - const int hardwareOptimum = -45; - const int hardwareMin = -90; - const int strength = - 100 - - ((abs(signal_strength_dbm_ - hardwareOptimum) / double{hardwareOptimum - hardwareMin}) * - 100); + const int hardwareOptimum{-45}; + const int hardwareMin{-90}; + const int strength{100 - ((abs(signal_strength_dbm_ - hardwareOptimum) / + double{hardwareOptimum - hardwareMin}) * + 100)}; signal_strength_ = std::clamp(strength, 0, 100); if (signal_strength_dbm_ >= -50) { @@ -855,7 +851,7 @@ bool waybar::modules::Network::associatedOrJoined(struct nlattr **bss) { if (bss[NL80211_BSS_STATUS] == nullptr) { return false; } - auto status = nla_get_u32(bss[NL80211_BSS_STATUS]); + auto status{nla_get_u32(bss[NL80211_BSS_STATUS])}; switch (status) { case NL80211_BSS_STATUS_ASSOCIATED: case NL80211_BSS_STATUS_IBSS_JOINED: @@ -867,7 +863,7 @@ bool waybar::modules::Network::associatedOrJoined(struct nlattr **bss) { } auto waybar::modules::Network::getInfo() -> void { - struct nl_msg *nl_msg = nlmsg_alloc(); + struct nl_msg *nl_msg{nlmsg_alloc()}; if (nl_msg == nullptr) { return; } @@ -883,11 +879,11 @@ auto waybar::modules::Network::getInfo() -> void { // https://gist.github.com/rressi/92af77630faf055934c723ce93ae2495 bool waybar::modules::Network::wildcardMatch(const std::string &pattern, const std::string &text) const { - auto P = int(pattern.size()); - auto T = int(text.size()); + auto P{int(pattern.size())}; + auto T{int(text.size())}; - auto p = 0, fallback_p = -1; - auto t = 0, fallback_t = -1; + auto p{0}, fallback_p{-1}; + auto t{0}, fallback_t{-1}; while (t < T) { // Wildcard match: diff --git a/src/modules/power_profiles_daemon.cpp b/src/modules/power_profiles_daemon.cpp index 3ae3ae830..4ed8e7b8c 100644 --- a/src/modules/power_profiles_daemon.cpp +++ b/src/modules/power_profiles_daemon.cpp @@ -39,8 +39,7 @@ PowerProfilesDaemon::PowerProfilesDaemon(const std::string& id, const Json::Valu // adresses for compatibility sake. // // Revisit this in 2026, systems should be updated by then. - - Gio::DBus::Proxy::create_for_bus(Gio::DBus::BusType::BUS_TYPE_SYSTEM, "net.hadess.PowerProfiles", + Gio::DBus::Proxy::create_for_bus(Gio::DBus::BusType::SYSTEM, "net.hadess.PowerProfiles", "/net/hadess/PowerProfiles", "net.hadess.PowerProfiles", sigc::mem_fun(*this, &PowerProfilesDaemon::busConnectedCb)); // Schedule update to set the initial visibility @@ -166,17 +165,19 @@ auto PowerProfilesDaemon::update() -> void { } label_.get_style_context()->add_class(profile.name); currentStyle_ = profile.name; - event_box_.set_visible(true); + label_.set_visible(true); } else { - event_box_.set_visible(false); + label_.set_visible(false); } ALabel::update(); } -bool PowerProfilesDaemon::handleToggle(GdkEventButton* const& e) { - if (e->type == GdkEventType::GDK_BUTTON_PRESS && connected_) { - if (e->button == 1) /* left click */ { +void PowerProfilesDaemon::handleToggle(int n_press, double dx, double dy) { + if (Gdk::Event::Type::BUTTON_PRESS == + (AModule::controllClick_->get_current_event())->get_event_type() && + connected_) { + if (AModule::controllClick_->get_current_button() == 1 /* left click */) { activeProfile_++; if (activeProfile_ == availableProfiles_.end()) { activeProfile_ = availableProfiles_.begin(); @@ -196,7 +197,6 @@ bool PowerProfilesDaemon::handleToggle(GdkEventButton* const& e) { powerProfilesProxy_->call("org.freedesktop.DBus.Properties.Set", sigc::mem_fun(*this, &PowerProfilesDaemon::setPropCb), callArgs); } - return true; } void PowerProfilesDaemon::setPropCb(Glib::RefPtr& r) { diff --git a/src/modules/privacy/privacy.cpp b/src/modules/privacy/privacy.cpp index 97996c336..9be09b0af 100644 --- a/src/modules/privacy/privacy.cpp +++ b/src/modules/privacy/privacy.cpp @@ -1,11 +1,5 @@ #include "modules/privacy/privacy.hpp" -#include -#include - -#include - -#include "AModule.hpp" #include "modules/privacy/privacy_item.hpp" namespace waybar::modules::privacy { @@ -21,11 +15,9 @@ Privacy::Privacy(const std::string& id, const Json::Value& config, const std::st nodes_audio_in(), nodes_audio_out(), visibility_conn(), - box_(Gtk::ORIENTATION_HORIZONTAL, 0) { + box_(Gtk::Orientation::HORIZONTAL, 0) { box_.set_name(name_); - event_box_.add(box_); - // Icon Spacing if (config_["icon-spacing"].isUInt()) { iconSpacing = config_["icon-spacing"].asUInt(); @@ -69,10 +61,12 @@ Privacy::Privacy(const std::string& id, const Json::Value& config, const std::st auto& [nodePtr, nodeType] = iter->second; auto* item = Gtk::make_managed(module, nodeType, nodePtr, pos, iconSize, transition_duration); - box_.add(*item); + box_.append(*item); } } + AModule::bindEvents(*this); + backend = util::PipewireBackend::PipewireBackend::getInstance(); backend->privacy_nodes_changed_signal_event.connect( sigc::mem_fun(*this, &Privacy::onPrivacyNodesChanged)); @@ -124,9 +118,10 @@ auto Privacy::update() -> void { bool useAudioOut = false; mutex_.lock(); - for (Gtk::Widget* widget : box_.get_children()) { - auto* module = dynamic_cast(widget); - if (module == nullptr) continue; + auto children{box_.observe_children()}; // Inefficient + for (guint i{0u}; i < children->get_n_items(); ++i) { + auto module = dynamic_pointer_cast(children->get_object(i)); + if (!module) continue; switch (module->privacy_type) { case util::PipewireBackend::PRIVACY_NODE_TYPE_VIDEO_INPUT: setScreenshare = true; @@ -153,12 +148,12 @@ auto Privacy::update() -> void { bool isVisible = (setScreenshare && useScreenshare) || (setAudioIn && useAudioIn) || (setAudioOut && useAudioOut); - if (isVisible != event_box_.get_visible()) { + if (isVisible != box_.get_visible()) { // Disconnect any previous connection so that it doesn't get activated in // the future, hiding the module when it should be visible visibility_conn.disconnect(); if (isVisible) { - event_box_.set_visible(true); + box_.set_visible(true); } else { // Hides the widget when all of the privacy_item revealers animations // have finished animating @@ -171,7 +166,7 @@ auto Privacy::update() -> void { visible |= setAudioIn && !nodes_audio_in.empty(); visible |= setAudioOut && !nodes_audio_out.empty(); mutex_.unlock(); - event_box_.set_visible(visible); + box_.set_visible(visible); return false; }, *this), @@ -183,4 +178,6 @@ auto Privacy::update() -> void { AModule::update(); } +Privacy::operator Gtk::Widget&() { return box_; }; + } // namespace waybar::modules::privacy diff --git a/src/modules/privacy/privacy_item.cpp b/src/modules/privacy/privacy_item.cpp index a38b95a4a..570d9817e 100644 --- a/src/modules/privacy/privacy_item.cpp +++ b/src/modules/privacy/privacy_item.cpp @@ -1,12 +1,8 @@ #include "modules/privacy/privacy_item.hpp" -#include - -#include "glibmm/main.h" -#include "gtkmm/label.h" -#include "gtkmm/revealer.h" -#include "gtkmm/tooltip.h" -#include "util/pipewire/privacy_node_info.hpp" +#include +#include +#include namespace waybar::modules::privacy { @@ -17,8 +13,8 @@ PrivacyItem::PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privac privacy_type(privacy_type_), nodes(nodes_), signal_conn(), - tooltip_window(Gtk::ORIENTATION_VERTICAL, 0), - box_(Gtk::ORIENTATION_HORIZONTAL, 0), + tooltip_window(Gtk::Orientation::VERTICAL, 0), + box_(Gtk::Orientation::HORIZONTAL, 0), icon_() { switch (privacy_type) { case util::PipewireBackend::PRIVACY_NODE_TYPE_AUDIO_INPUT: @@ -40,24 +36,27 @@ PrivacyItem::PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privac // Set the reveal transition to not look weird when sliding in if (pos == "modules-left") { - set_transition_type(Gtk::REVEALER_TRANSITION_TYPE_SLIDE_RIGHT); + set_transition_type(Gtk::RevealerTransitionType::SLIDE_RIGHT); } else if (pos == "modules-center") { - set_transition_type(Gtk::REVEALER_TRANSITION_TYPE_CROSSFADE); + set_transition_type(Gtk::RevealerTransitionType::CROSSFADE); } else if (pos == "modules-right") { - set_transition_type(Gtk::REVEALER_TRANSITION_TYPE_SLIDE_LEFT); + set_transition_type(Gtk::RevealerTransitionType::SLIDE_LEFT); } set_transition_duration(transition_duration); box_.set_name("privacy-item"); - box_.add(icon_); + box_.append(icon_); icon_.set_pixel_size(icon_size); - add(box_); + set_child(box_); + + // Get current theme + gtkTheme_ = Gtk::IconTheme::get_for_display(box_.get_display()); // Icon Name if (config_["icon-name"].isString()) { iconName = config_["icon-name"].asString(); } - icon_.set_from_icon_name(iconName, Gtk::ICON_SIZE_INVALID); + icon_.set_from_icon_name(iconName); // Tooltip Icon Size if (config_["tooltip-icon-size"].isUInt()) { @@ -71,12 +70,14 @@ PrivacyItem::PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privac if (tooltip) { // Sets the window to use when showing the tooltip update_tooltip(); - this->signal_query_tooltip().connect(sigc::track_obj( - [this](int x, int y, bool keyboard_tooltip, const Glib::RefPtr &tooltip) { - tooltip->set_custom(tooltip_window); - return true; - }, - *this)); + this->signal_query_tooltip().connect( + sigc::track_obj( + [this](int x, int y, bool keyboard_tooltip, const Glib::RefPtr &tooltip) { + tooltip->set_custom(tooltip_window); + return true; + }, + *this), + false); } // Don't show by default @@ -86,27 +87,26 @@ PrivacyItem::PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privac void PrivacyItem::update_tooltip() { // Removes all old nodes - for (auto *child : tooltip_window.get_children()) { - delete child; - } + for (auto child{tooltip_window.get_last_child()}; child; child = tooltip_window.get_last_child()) + tooltip_window.remove(*child); for (auto *node : *nodes) { - Gtk::Box *box = new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 4); + Gtk::Box *box = new Gtk::Box(Gtk::Orientation::HORIZONTAL, 4); // Set device icon Gtk::Image *node_icon = new Gtk::Image(); node_icon->set_pixel_size(tooltipIconSize); - node_icon->set_from_icon_name(node->getIconName(), Gtk::ICON_SIZE_INVALID); - box->add(*node_icon); + node_icon->set_from_icon_name(node->getIconName(gtkTheme_)); + box->append(*node_icon); // Set model auto *nodeName = new Gtk::Label(node->getName()); - box->add(*nodeName); + box->append(*nodeName); - tooltip_window.add(*box); + tooltip_window.append(*box); } - tooltip_window.show_all(); + tooltip_window.show(); } void PrivacyItem::set_in_use(bool in_use) { diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index 255ca571f..cce4e763e 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -1,26 +1,27 @@ #include "modules/pulseaudio.hpp" -waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value &config) - : ALabel(config, "pulseaudio", id, "{volume}%") { - event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); - event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Pulseaudio::handleScroll)); +#include +namespace waybar::modules { + +Pulseaudio::Pulseaudio(const std::string &id, const Json::Value &config) + : ALabel(config, "pulseaudio", id, "{volume}%", 60, false, false, true) { backend = util::AudioBackend::getInstance([this] { this->dp.emit(); }); backend->setIgnoredSinks(config_["ignored-sinks"]); } -bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { +bool Pulseaudio::handleScroll(double dx, double dy) { // change the pulse volume only when no user provided // events are configured if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { - return AModule::handleScroll(e); + return AModule::handleScroll(dx, dy); } - auto dir = AModule::getScrollDir(e); + auto dir{AModule::getScrollDir(controllScroll_->get_current_event())}; if (dir == SCROLL_DIR::NONE) { return true; } - int max_volume = 100; - double step = 1; + int max_volume{100}; + double step{1}; // isDouble returns true for integers as well, just in case if (config_["scroll-step"].isDouble()) { step = config_["scroll-step"].asDouble(); @@ -29,15 +30,15 @@ bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { max_volume = config_["max-volume"].asInt(); } - auto change_type = (dir == SCROLL_DIR::UP || dir == SCROLL_DIR::RIGHT) - ? util::ChangeType::Increase - : util::ChangeType::Decrease; + auto change_type{(dir == SCROLL_DIR::UP || dir == SCROLL_DIR::RIGHT) + ? util::ChangeType::Increase + : util::ChangeType::Decrease}; backend->changeVolume(change_type, step, max_volume); return true; } -static const std::array ports = { +static const std::array ports{ "headphone", "speaker", "hdmi", "headset", "hands-free", "portable", "car", "hifi", "phone", }; @@ -66,12 +67,12 @@ const std::vector waybar::modules::Pulseaudio::getPulseIcon() const return res; } -auto waybar::modules::Pulseaudio::update() -> void { - auto format = format_; +auto Pulseaudio::update() -> void { + auto format{format_}; std::string tooltip_format; - auto sink_volume = backend->getSinkVolume(); + auto sink_volume{backend->getSinkVolume()}; if (!alt_) { - std::string format_name = "format"; + std::string format_name{"format"}; if (backend->isBluetooth()) { format_name = format_name + "-bluetooth"; label_.get_style_context()->add_class("bluetooth"); @@ -90,7 +91,7 @@ auto waybar::modules::Pulseaudio::update() -> void { label_.get_style_context()->remove_class("muted"); label_.get_style_context()->remove_class("sink-muted"); } - auto state = getState(sink_volume, true); + auto state{getState(sink_volume, true)}; if (!state.empty() && config_[format_name + "-" + state].isString()) { format = config_[format_name + "-" + state].asString(); } else if (config_[format_name].isString()) { @@ -98,7 +99,7 @@ auto waybar::modules::Pulseaudio::update() -> void { } } // TODO: find a better way to split source/sink - std::string format_source = "{volume}%"; + std::string format_source{"{volume}%"}; if (backend->getSourceMuted()) { label_.get_style_context()->add_class("source-muted"); if (config_["format-source-muted"].isString()) { @@ -111,15 +112,16 @@ auto waybar::modules::Pulseaudio::update() -> void { } } - auto source_volume = backend->getSourceVolume(); - auto sink_desc = backend->getSinkDesc(); - auto source_desc = backend->getSourceDesc(); + auto source_volume{backend->getSourceVolume()}; + auto sink_desc{backend->getSinkDesc()}; + auto source_desc{backend->getSourceDesc()}; format_source = fmt::format(fmt::runtime(format_source), fmt::arg("volume", source_volume)); - auto text = fmt::format( - fmt::runtime(format), fmt::arg("desc", sink_desc), fmt::arg("volume", sink_volume), - fmt::arg("format_source", format_source), fmt::arg("source_volume", source_volume), - fmt::arg("source_desc", source_desc), fmt::arg("icon", getIcon(sink_volume, getPulseIcon()))); + auto text{fmt::format(fmt::runtime(format), fmt::arg("desc", sink_desc), + fmt::arg("volume", sink_volume), fmt::arg("format_source", format_source), + fmt::arg("source_volume", source_volume), + fmt::arg("source_desc", source_desc), + fmt::arg("icon", getIcon(sink_volume, getPulseIcon())))}; if (text.empty()) { label_.hide(); } else { @@ -145,3 +147,5 @@ auto waybar::modules::Pulseaudio::update() -> void { // Call parent update ALabel::update(); } + +} // namespace waybar::modules diff --git a/src/modules/pulseaudio_slider.cpp b/src/modules/pulseaudio_slider.cpp index bf85584ed..64fe33d74 100644 --- a/src/modules/pulseaudio_slider.cpp +++ b/src/modules/pulseaudio_slider.cpp @@ -8,7 +8,7 @@ PulseaudioSlider::PulseaudioSlider(const std::string& id, const Json::Value& con backend->setIgnoredSinks(config_["ignored-sinks"]); if (config_["target"].isString()) { - std::string target = config_["target"].asString(); + std::string target{config_["target"].asString()}; if (target == "sink") { this->target = PulseaudioSliderTarget::Sink; } else if (target == "source") { @@ -38,7 +38,7 @@ void PulseaudioSlider::update() { } void PulseaudioSlider::onValueChanged() { - bool is_mute = false; + bool is_mute{false}; switch (target) { case PulseaudioSliderTarget::Sink: @@ -54,7 +54,7 @@ void PulseaudioSlider::onValueChanged() { break; } - uint16_t volume = scale_.get_value(); + uint16_t volume{scale_.get_value()}; if (is_mute) { // Avoid setting sink/source to volume 0 if the user muted if via another mean. @@ -79,4 +79,4 @@ void PulseaudioSlider::onValueChanged() { backend->changeVolume(volume, min_, max_); } -} // namespace waybar::modules \ No newline at end of file +} // namespace waybar::modules diff --git a/src/modules/sndio.cpp b/src/modules/sndio.cpp index 72e7207ce..81d0b509d 100644 --- a/src/modules/sndio.cpp +++ b/src/modules/sndio.cpp @@ -1,6 +1,5 @@ #include "modules/sndio.hpp" -#include #include #include @@ -10,7 +9,7 @@ namespace waybar::modules { void ondesc(void *arg, struct sioctl_desc *d, int curval) { - auto self = static_cast(arg); + auto self{static_cast(arg)}; if (d == NULL) { // d is NULL when the list is done return; @@ -19,7 +18,7 @@ void ondesc(void *arg, struct sioctl_desc *d, int curval) { } void onval(void *arg, unsigned int addr, unsigned int val) { - auto self = static_cast(arg); + auto self{static_cast(arg)}; self->put_val(addr, val); } @@ -41,26 +40,22 @@ auto Sndio::connect_to_sndio() -> void { } Sndio::Sndio(const std::string &id, const Json::Value &config) - : ALabel(config, "sndio", id, "{volume}%", 1, false, true), - hdl_(nullptr), - pfds_(0), - addr_(0), - volume_(0), - old_volume_(0), - maxval_(0), - muted_(false) { + : ALabel(config, "sndio", id, "{volume}%", 1, false, true, true), + hdl_{nullptr}, + pfds_{0}, + addr_{0}, + volume_{0}, + old_volume_{0}, + maxval_{0}, + muted_{false} { connect_to_sndio(); - event_box_.show(); - - event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK | Gdk::BUTTON_PRESS_MASK); - event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Sndio::handleScroll)); - event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &Sndio::handleToggle)); + label_.show(); thread_ = [this] { dp.emit(); - int nfds = sioctl_pollfd(hdl_, pfds_.data(), POLLIN); + int nfds{sioctl_pollfd(hdl_, pfds_.data(), POLLIN)}; if (nfds == 0) { throw std::runtime_error("sioctl_pollfd() failed."); } @@ -70,7 +65,7 @@ Sndio::Sndio(const std::string &id, const Json::Value &config) } } - int revents = sioctl_revents(hdl_, pfds_.data()); + int revents{sioctl_revents(hdl_, pfds_.data())}; if (revents & POLLHUP) { spdlog::warn("sndio disconnected!"); sioctl_close(hdl_); @@ -101,8 +96,8 @@ Sndio::Sndio(const std::string &id, const Json::Value &config) Sndio::~Sndio() { sioctl_close(hdl_); } auto Sndio::update() -> void { - auto format = format_; - unsigned int vol = 100. * static_cast(volume_) / static_cast(maxval_); + auto format{format_}; + unsigned int vol{100. * static_cast(volume_) / static_cast(maxval_)}; if (volume_ == 0) { label_.get_style_context()->add_class("muted"); @@ -110,8 +105,8 @@ auto Sndio::update() -> void { label_.get_style_context()->remove_class("muted"); } - auto text = - fmt::format(fmt::runtime(format), fmt::arg("volume", vol), fmt::arg("raw_value", volume_)); + auto text{ + fmt::format(fmt::runtime(format), fmt::arg("volume", vol), fmt::arg("raw_value", volume_))}; if (text.empty()) { label_.hide(); } else { @@ -140,27 +135,27 @@ auto Sndio::put_val(unsigned int addr, unsigned int val) -> void { } } -bool Sndio::handleScroll(GdkEventScroll *e) { +bool Sndio::handleScroll(double dx, double dy) { // change the volume only when no user provided // events are configured if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { - return AModule::handleScroll(e); + return AModule::handleScroll(dx, dy); } // only try to talk to sndio if connected if (hdl_ == nullptr) return true; - auto dir = AModule::getScrollDir(e); + auto dir{AModule::getScrollDir(controllScroll_->get_current_event())}; if (dir == SCROLL_DIR::NONE) { return true; } - int step = 5; + int step{5}; if (config_["scroll-step"].isInt()) { step = config_["scroll-step"].asInt(); } - int new_volume = volume_; + int new_volume{volume_}; if (muted_) { new_volume = old_volume_; } @@ -180,14 +175,14 @@ bool Sndio::handleScroll(GdkEventScroll *e) { return true; } -bool Sndio::handleToggle(GdkEventButton *const &e) { +void Sndio::handleToggle(int n_press, double dx, double dy) { // toggle mute only when no user provided events are configured if (config_["on-click"].isString()) { - return AModule::handleToggle(e); + AModule::handleToggle(n_press, dx, dy); } // only try to talk to sndio if connected - if (hdl_ == nullptr) return true; + if (hdl_ == nullptr) return; muted_ = !muted_; if (muted_) { @@ -197,8 +192,6 @@ bool Sndio::handleToggle(GdkEventButton *const &e) { } else { sioctl_setval(hdl_, addr_, old_volume_); } - - return true; } } /* namespace waybar::modules */ diff --git a/src/modules/sway/bar.cpp b/src/modules/sway/bar.cpp index f28b05025..f3d63f842 100644 --- a/src/modules/sway/bar.cpp +++ b/src/modules/sway/bar.cpp @@ -2,9 +2,6 @@ #include -#include -#include - #include "bar.hpp" #include "modules/sway/ipc/ipc.hpp" @@ -12,8 +9,8 @@ namespace waybar::modules::sway { BarIpcClient::BarIpcClient(waybar::Bar& bar) : bar_{bar} { { - sigc::connection handle = - ipc_.signal_cmd.connect(sigc::mem_fun(*this, &BarIpcClient::onInitialConfig)); + sigc::connection handle{ + ipc_.signal_cmd.connect(sigc::mem_fun(*this, &BarIpcClient::onInitialConfig))}; ipc_.sendCmd(IPC_GET_BAR_CONFIG, bar_.bar_id); handle.disconnect(); @@ -23,8 +20,8 @@ BarIpcClient::BarIpcClient(waybar::Bar& bar) : bar_{bar} { subscribe_events.append("bar_state_update"); subscribe_events.append("barconfig_update"); - bool has_mode = isModuleEnabled("sway/mode"); - bool has_workspaces = isModuleEnabled("sway/workspaces"); + bool has_mode{isModuleEnabled("sway/mode")}; + bool has_workspaces{isModuleEnabled("sway/workspaces")}; if (has_mode) { subscribe_events.append("mode"); @@ -62,7 +59,7 @@ BarIpcClient::BarIpcClient(waybar::Bar& bar) : bar_{bar} { bool BarIpcClient::isModuleEnabled(std::string name) { for (const auto& section : {"modules-left", "modules-center", "modules-right"}) { - if (const auto& modules = bar_.config.get(section, {}); modules.isArray()) { + if (const auto& modules{bar_.config.get(section, {})}; modules.isArray()) { for (const auto& module : modules) { if (module.asString().rfind(name, 0) == 0) { return true; @@ -75,38 +72,38 @@ bool BarIpcClient::isModuleEnabled(std::string name) { struct swaybar_config parseConfig(const Json::Value& payload) { swaybar_config conf; - if (auto id = payload["id"]; id.isString()) { + if (auto id{payload["id"]}; id.isString()) { conf.id = id.asString(); } - if (auto mode = payload["mode"]; mode.isString()) { + if (auto mode{payload["mode"]}; mode.isString()) { conf.mode = mode.asString(); } - if (auto hs = payload["hidden_state"]; hs.isString()) { + if (auto hs{payload["hidden_state"]}; hs.isString()) { conf.hidden_state = hs.asString(); } return conf; } void BarIpcClient::onInitialConfig(const struct Ipc::ipc_response& res) { - auto payload = parser_.parse(res.payload); - if (auto success = payload.get("success", true); !success.asBool()) { - auto err = payload.get("error", "Unknown error"); + auto payload{parser_.parse(res.payload)}; + if (auto success{payload.get("success", true)}; !success.asBool()) { + auto err{payload.get("error", "Unknown error")}; throw std::runtime_error(err.asString()); } - auto config = parseConfig(payload); + auto config{parseConfig(payload)}; onConfigUpdate(config); } void BarIpcClient::onIpcEvent(const struct Ipc::ipc_response& res) { try { - auto payload = parser_.parse(res.payload); + auto payload{parser_.parse(res.payload)}; switch (res.type) { case IPC_EVENT_WORKSPACE: if (payload.isMember("change")) { // only check and send signal if the workspace update reason was because of a urgent // change if (payload["change"] == "urgent") { - auto urgent = payload["current"]["urgent"]; + auto urgent{payload["current"]["urgent"]}; if (urgent.asBool()) { // Event for a new urgency, update the visibly signal_urgency_(true); @@ -139,7 +136,7 @@ void BarIpcClient::onIpcEvent(const struct Ipc::ipc_response& res) { signal_visible_(payload["visible_by_modifier"].asBool()); } else { // configuration update - auto config = parseConfig(payload); + auto config{parseConfig(payload)}; signal_config_(std::move(config)); } break; @@ -152,7 +149,7 @@ void BarIpcClient::onIpcEvent(const struct Ipc::ipc_response& res) { void BarIpcClient::onCmd(const struct Ipc::ipc_response& res) { if (res.type == IPC_GET_WORKSPACES) { try { - auto payload = parser_.parse(res.payload); + auto payload{parser_.parse(res.payload)}; for (auto& ws : payload) { if (ws["urgent"].asBool()) { spdlog::debug("Found workspace {} with urgency set. Stopping search.", ws["name"]); @@ -209,7 +206,7 @@ void BarIpcClient::onUrgencyUpdate(bool visible_by_urgency) { } void BarIpcClient::update() { - bool visible = visible_by_modifier_ || visible_by_mode_ || visible_by_urgency_; + bool visible{visible_by_modifier_ || visible_by_mode_ || visible_by_urgency_}; if (bar_config_.mode == "invisible") { visible = false; } else if (bar_config_.mode != "hide" || bar_config_.hidden_state != "hide") { diff --git a/src/modules/sway/ipc/client.cpp b/src/modules/sway/ipc/client.cpp index 4139a53b5..7bfdd5bee 100644 --- a/src/modules/sway/ipc/client.cpp +++ b/src/modules/sway/ipc/client.cpp @@ -3,12 +3,10 @@ #include #include -#include - namespace waybar::modules::sway { Ipc::Ipc() { - const std::string& socketPath = getSocketPath(); + const std::string& socketPath{getSocketPath()}; fd_ = open(socketPath); fd_event_ = open(socketPath); } @@ -36,7 +34,7 @@ Ipc::~Ipc() { void Ipc::setWorker(std::function&& func) { thread_ = func; } const std::string Ipc::getSocketPath() const { - const char* env = getenv("SWAYSOCK"); + const char* env{getenv("SWAYSOCK")}; if (env != nullptr) { return std::string(env); } @@ -64,7 +62,7 @@ const std::string Ipc::getSocketPath() const { } int Ipc::open(const std::string& socketPath) const { - int32_t fd = socket(AF_UNIX, SOCK_STREAM, 0); + int32_t fd{socket(AF_UNIX, SOCK_STREAM, 0)}; if (fd == -1) { throw std::runtime_error("Unable to open Unix socket"); } @@ -74,7 +72,7 @@ int Ipc::open(const std::string& socketPath) const { addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1); addr.sun_path[sizeof(addr.sun_path) - 1] = 0; - int l = sizeof(struct sockaddr_un); + int l{sizeof(struct sockaddr_un)}; if (::connect(fd, reinterpret_cast(&addr), l) == -1) { throw std::runtime_error("Unable to connect to Sway"); } @@ -84,11 +82,11 @@ int Ipc::open(const std::string& socketPath) const { struct Ipc::ipc_response Ipc::recv(int fd) { std::string header; header.resize(ipc_header_size_); - auto data32 = reinterpret_cast(header.data() + ipc_magic_.size()); - size_t total = 0; + auto data32{reinterpret_cast(header.data() + ipc_magic_.size())}; + size_t total{0}; while (total < ipc_header_size_) { - auto res = ::recv(fd, header.data() + total, ipc_header_size_ - total, 0); + auto res{::recv(fd, header.data() + total, ipc_header_size_ - total, 0)}; if (fd_event_ == -1 || fd_ == -1) { // IPC is closed so just return an empty response return {0, 0, ""}; @@ -98,7 +96,7 @@ struct Ipc::ipc_response Ipc::recv(int fd) { } total += res; } - auto magic = std::string(header.data(), header.data() + ipc_magic_.size()); + auto magic{std::string(header.data(), header.data() + ipc_magic_.size())}; if (magic != ipc_magic_) { throw std::runtime_error("Invalid IPC magic"); } @@ -107,7 +105,7 @@ struct Ipc::ipc_response Ipc::recv(int fd) { std::string payload; payload.resize(data32[0]); while (total < data32[0]) { - auto res = ::recv(fd, payload.data() + total, data32[0] - total, 0); + auto res{::recv(fd, payload.data() + total, data32[0] - total, 0)}; if (res < 0) { if (errno == EINTR || errno == EAGAIN) { continue; @@ -122,7 +120,7 @@ struct Ipc::ipc_response Ipc::recv(int fd) { struct Ipc::ipc_response Ipc::send(int fd, uint32_t type, const std::string& payload) { std::string header; header.resize(ipc_header_size_); - auto data32 = reinterpret_cast(header.data() + ipc_magic_.size()); + auto data32{reinterpret_cast(header.data() + ipc_magic_.size())}; memcpy(header.data(), ipc_magic_.c_str(), ipc_magic_.size()); data32[0] = payload.size(); data32[1] = type; @@ -137,20 +135,20 @@ struct Ipc::ipc_response Ipc::send(int fd, uint32_t type, const std::string& pay } void Ipc::sendCmd(uint32_t type, const std::string& payload) { - std::lock_guard lock(mutex_); - const auto res = Ipc::send(fd_, type, payload); + std::lock_guard lock{mutex_}; + const auto res{Ipc::send(fd_, type, payload)}; signal_cmd.emit(res); } void Ipc::subscribe(const std::string& payload) { - auto res = Ipc::send(fd_event_, IPC_SUBSCRIBE, payload); + auto res{Ipc::send(fd_event_, IPC_SUBSCRIBE, payload)}; if (res.payload != "{\"success\": true}") { throw std::runtime_error("Unable to subscribe ipc event"); } } void Ipc::handleEvent() { - const auto res = Ipc::recv(fd_event_); + const auto res{Ipc::recv(fd_event_)}; signal_event.emit(res); } diff --git a/src/modules/sway/language.cpp b/src/modules/sway/language.cpp index a005df17c..72cfbbaf9 100644 --- a/src/modules/sway/language.cpp +++ b/src/modules/sway/language.cpp @@ -1,21 +1,13 @@ #include "modules/sway/language.hpp" -#include -#include #include -#include -#include -#include -#include - -#include "modules/sway/ipc/ipc.hpp" #include "util/string.hpp" namespace waybar::modules::sway { -const std::string Language::XKB_LAYOUT_NAMES_KEY = "xkb_layout_names"; -const std::string Language::XKB_ACTIVE_LAYOUT_NAME_KEY = "xkb_active_layout_name"; +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) : ALabel(config, "language", id, "{}", 0, true) { @@ -51,14 +43,14 @@ void Language::onCmd(const struct Ipc::ipc_response& res) { } try { - std::lock_guard lock(mutex_); - auto payload = parser_.parse(res.payload); + std::lock_guard lock{mutex_}; + auto payload{parser_.parse(res.payload)}; std::vector used_layouts; // Display current layout of a device with a maximum count of layouts, expecting that all will // be OK - Json::ArrayIndex max_id = 0, max = 0; - for (Json::ArrayIndex i = 0; i < payload.size(); i++) { - auto size = payload[i][XKB_LAYOUT_NAMES_KEY].size(); + Json::ArrayIndex max_id{0}, max{0}; + for (Json::ArrayIndex i{0}; i < payload.size(); i++) { + auto size{payload[i][XKB_LAYOUT_NAMES_KEY].size()}; if (size > max) { max = size; max_id = i; @@ -83,8 +75,8 @@ void Language::onEvent(const struct Ipc::ipc_response& res) { } try { - std::lock_guard lock(mutex_); - auto payload = parser_.parse(res.payload)["input"]; + std::lock_guard lock{mutex_}; + auto payload{parser_.parse(res.payload)["input"]}; if (payload["type"].asString() == "keyboard") { set_current_layout(payload[XKB_ACTIVE_LAYOUT_NAME_KEY].asString()); } @@ -95,30 +87,30 @@ void Language::onEvent(const struct Ipc::ipc_response& res) { } auto Language::update() -> void { - std::lock_guard lock(mutex_); + std::lock_guard lock{mutex_}; if (hide_single_ && layouts_map_.size() <= 1) { - event_box_.hide(); + label_.hide(); return; } - auto display_layout = trim(fmt::format( + auto display_layout{trim(fmt::format( fmt::runtime(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()))); + fmt::arg("variant", layout_.variant), fmt::arg("flag", layout_.country_flag())))}; label_.set_markup(display_layout); if (tooltipEnabled()) { if (tooltip_format_ != "") { - auto tooltip_display_layout = trim( + auto tooltip_display_layout{trim( fmt::format(fmt::runtime(tooltip_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()))); + fmt::arg("flag", layout_.country_flag())))}; label_.set_tooltip_markup(tooltip_display_layout); } else { label_.set_tooltip_markup(display_layout); } } - event_box_.show(); + label_.show(); // Call parent update ALabel::update(); @@ -133,7 +125,7 @@ auto Language::set_current_layout(std::string current_layout) -> void { auto Language::init_layouts_map(const std::vector& used_layouts) -> void { std::map> found_by_short_names; XKBContext xkb_context; - auto layout = xkb_context.next_layout(); + auto layout{xkb_context.next_layout()}; for (; layout != nullptr; layout = xkb_context.next_layout()) { if (std::find(used_layouts.begin(), used_layouts.end(), layout->full_name) == used_layouts.end()) { @@ -141,7 +133,7 @@ auto Language::init_layouts_map(const std::vector& used_layouts) -> } if (!is_variant_displayed) { - auto short_name = layout->short_name; + auto short_name{layout->short_name}; if (found_by_short_names.count(short_name) > 0) { found_by_short_names[short_name].push_back(layout); } else { @@ -158,10 +150,10 @@ auto Language::init_layouts_map(const std::vector& used_layouts) -> std::map short_name_to_number_map; for (const auto& used_layout_name : used_layouts) { - auto found = layouts_map_.find(used_layout_name); + auto found{layouts_map_.find(used_layout_name)}; if (found == layouts_map_.end()) continue; - auto used_layout = &found->second; - auto layouts_with_same_name_list = found_by_short_names[used_layout->short_name]; + auto used_layout{&found->second}; + auto layouts_with_same_name_list{found_by_short_names[used_layout->short_name]}; if (layouts_with_same_name_list.size() < 2) { continue; } @@ -171,7 +163,7 @@ auto Language::init_layouts_map(const std::vector& used_layouts) -> } if (displayed_short_flag != static_cast(0)) { - int& number = short_name_to_number_map[used_layout->short_name]; + int& number{short_name_to_number_map[used_layout->short_name]}; used_layout->short_name = used_layout->short_name + std::to_string(number); used_layout->short_description = used_layout->short_description + std::to_string(number); ++number; @@ -195,17 +187,17 @@ auto Language::XKBContext::next_layout() -> Layout* { return nullptr; } - auto description = std::string(rxkb_layout_get_description(xkb_layout_)); - auto name = std::string(rxkb_layout_get_name(xkb_layout_)); - auto variant_ = rxkb_layout_get_variant(xkb_layout_); - std::string variant = variant_ == nullptr ? "" : std::string(variant_); - auto short_description_ = rxkb_layout_get_brief(xkb_layout_); + auto description{std::string(rxkb_layout_get_description(xkb_layout_))}; + auto name{std::string(rxkb_layout_get_name(xkb_layout_))}; + auto variant_{rxkb_layout_get_variant(xkb_layout_)}; + std::string variant{variant_ == nullptr ? "" : std::string(variant_)}; + auto short_description_{rxkb_layout_get_brief(xkb_layout_)}; std::string short_description; if (short_description_ != nullptr) { short_description = std::string(short_description_); base_layouts_by_name_.emplace(name, xkb_layout_); } else { - auto base_layout = base_layouts_by_name_[name]; + auto base_layout{base_layouts_by_name_[name]}; short_description = base_layout == nullptr ? "" : std::string(rxkb_layout_get_brief(base_layout)); } @@ -221,7 +213,7 @@ Language::XKBContext::~XKBContext() { std::string Language::Layout::country_flag() const { if (short_name.size() != 2) return ""; - unsigned char result[] = "\xf0\x9f\x87\x00\xf0\x9f\x87\x00"; + unsigned char result[]{"\xf0\x9f\x87\x00\xf0\x9f\x87\x00"}; result[3] = short_name[0] + 0x45; result[7] = short_name[1] + 0x45; // Check if both emojis are in A-Z symbol bounds diff --git a/src/modules/sway/mode.cpp b/src/modules/sway/mode.cpp index b81735e54..1da4ddcea 100644 --- a/src/modules/sway/mode.cpp +++ b/src/modules/sway/mode.cpp @@ -1,5 +1,6 @@ #include "modules/sway/mode.hpp" +#include #include namespace waybar::modules::sway { @@ -21,8 +22,8 @@ Mode::Mode(const std::string& id, const Json::Value& config) void Mode::onEvent(const struct Ipc::ipc_response& res) { try { - std::lock_guard lock(mutex_); - auto payload = parser_.parse(res.payload); + std::lock_guard lock{mutex_}; + auto payload{parser_.parse(res.payload)}; if (payload["change"] != "default") { if (payload["pango_markup"].asBool()) { mode_ = payload["change"].asString(); @@ -40,13 +41,13 @@ void Mode::onEvent(const struct Ipc::ipc_response& res) { auto Mode::update() -> void { if (mode_.empty()) { - event_box_.hide(); + label_.hide(); } else { label_.set_markup(fmt::format(fmt::runtime(format_), mode_)); if (tooltipEnabled()) { label_.set_tooltip_text(mode_); } - event_box_.show(); + label_.show(); } // Call parent update ALabel::update(); diff --git a/src/modules/sway/scratchpad.cpp b/src/modules/sway/scratchpad.cpp index 17dc27071..85bfa6e62 100644 --- a/src/modules/sway/scratchpad.cpp +++ b/src/modules/sway/scratchpad.cpp @@ -2,18 +2,16 @@ #include -#include - namespace waybar::modules::sway { Scratchpad::Scratchpad(const std::string& id, const Json::Value& config) : ALabel(config, "scratchpad", id, config["format"].isString() ? config["format"].asString() : "{icon} {count}"), - tooltip_format_(config_["tooltip-format"].isString() ? config_["tooltip-format"].asString() - : "{app}: {title}"), - show_empty_(config_["show-empty"].isBool() ? config_["show-empty"].asBool() : false), - tooltip_enabled_(config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true), - tooltip_text_(""), - count_(0) { + tooltip_format_{config_["tooltip-format"].isString() ? config_["tooltip-format"].asString() + : "{app}: {title}"}, + show_empty_{config_["show-empty"].isBool() ? config_["show-empty"].asBool() : false}, + tooltip_enabled_{config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true}, + tooltip_text_{""}, + count_{0} { ipc_.subscribe(R"(["window"])"); ipc_.signal_event.connect(sigc::mem_fun(*this, &Scratchpad::onEvent)); ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Scratchpad::onCmd)); @@ -30,7 +28,7 @@ Scratchpad::Scratchpad(const std::string& id, const Json::Value& config) } auto Scratchpad::update() -> void { if (count_ || show_empty_) { - event_box_.show(); + label_.show(); label_.set_markup( fmt::format(fmt::runtime(format_), fmt::arg("icon", getIcon(count_, "", config_["format-icons"].size())), @@ -39,7 +37,7 @@ auto Scratchpad::update() -> void { label_.set_tooltip_markup(tooltip_text_); } } else { - event_box_.hide(); + label_.hide(); } if (count_) { label_.get_style_context()->remove_class("empty"); @@ -59,8 +57,8 @@ auto Scratchpad::getTree() -> void { auto Scratchpad::onCmd(const struct Ipc::ipc_response& res) -> void { try { - std::lock_guard lock(mutex_); - auto tree = parser_.parse(res.payload); + std::lock_guard lock{mutex_}; + auto tree{parser_.parse(res.payload)}; count_ = tree["nodes"][0]["nodes"][0]["floating_nodes"].size(); if (tooltip_enabled_) { tooltip_text_.clear(); @@ -80,4 +78,4 @@ auto Scratchpad::onCmd(const struct Ipc::ipc_response& res) -> void { } auto Scratchpad::onEvent(const struct Ipc::ipc_response& res) -> void { getTree(); } -} // namespace waybar::modules::sway \ No newline at end of file +} // namespace waybar::modules::sway diff --git a/src/modules/sway/window.cpp b/src/modules/sway/window.cpp index 25e430a76..e36cc624e 100644 --- a/src/modules/sway/window.cpp +++ b/src/modules/sway/window.cpp @@ -1,23 +1,14 @@ #include "modules/sway/window.hpp" -#include -#include -#include -#include -#include +#include #include -#include -#include -#include - -#include "util/gtk_icon.hpp" #include "util/rewrite_string.hpp" namespace waybar::modules::sway { Window::Window(const std::string& id, const Bar& bar, const Json::Value& config) - : AAppIconLabel(config, "window", id, "{}", 0, true), bar_(bar), windowId_(-1) { + : AAppIconLabel(config, "window", id, "{}", 0, true), bar_{bar}, windowId_{-1} { ipc_.subscribe(R"(["window","workspace"])"); ipc_.signal_event.connect(sigc::mem_fun(*this, &Window::onEvent)); ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Window::onCmd)); @@ -38,9 +29,9 @@ void Window::onEvent(const struct Ipc::ipc_response& res) { getTree(); } void Window::onCmd(const struct Ipc::ipc_response& res) { try { - std::lock_guard lock(mutex_); - auto payload = parser_.parse(res.payload); - auto output = payload["output"].isString() ? payload["output"].asString() : ""; + std::lock_guard lock{mutex_}; + auto payload{parser_.parse(res.payload)}; + auto output{payload["output"].isString() ? payload["output"].asString() : ""}; std::tie(app_nb_, floating_count_, windowId_, window_, app_id_, app_class_, shell_, layout_) = getFocusedNode(payload["nodes"], output); updateAppIconName(app_id_, app_class_); @@ -55,7 +46,7 @@ auto Window::update() -> void { spdlog::trace("workspace layout {}, tiled count {}, floating count {}", layout_, app_nb_, floating_count_); - int mode = 0; + int mode{0}; if (app_nb_ == 0) { if (floating_count_ == 0) { mode += 1; @@ -75,9 +66,9 @@ auto Window::update() -> void { } if (!old_app_id_.empty() && ((mode & 2) == 0 || old_app_id_ != app_id_) && - bar_.window.get_style_context()->has_class(old_app_id_)) { + label_.get_style_context()->has_class(old_app_id_)) { spdlog::trace("Removing app_id class: {}", old_app_id_); - bar_.window.get_style_context()->remove_class(old_app_id_); + label_.get_style_context()->remove_class(old_app_id_); old_app_id_ = ""; } @@ -88,9 +79,9 @@ auto Window::update() -> void { setClass("stacked", ((mode & 16) > 0)); setClass("tiled", ((mode & 32) > 0)); - if ((mode & 2) > 0 && !app_id_.empty() && !bar_.window.get_style_context()->has_class(app_id_)) { + if ((mode & 2) > 0 && !app_id_.empty() && !label_.get_style_context()->has_class(app_id_)) { spdlog::trace("Adding app_id class: {}", app_id_); - bar_.window.get_style_context()->add_class(app_id_); + label_.get_style_context()->add_class(app_id_); old_app_id_ = app_id_; } @@ -110,17 +101,17 @@ auto Window::update() -> void { void Window::setClass(std::string classname, bool enable) { if (enable) { - if (!bar_.window.get_style_context()->has_class(classname)) { - bar_.window.get_style_context()->add_class(classname); + if (!label_.get_style_context()->has_class(classname)) { + label_.get_style_context()->add_class(classname); } } else { - bar_.window.get_style_context()->remove_class(classname); + label_.get_style_context()->remove_class(classname); } } std::pair leafNodesInWorkspace(const Json::Value& node) { - auto const& nodes = node["nodes"]; - auto const& floating_nodes = node["floating_nodes"]; + auto const& nodes{node["nodes"]}; + auto const& floating_nodes{node["floating_nodes"]}; if (nodes.empty() && floating_nodes.empty()) { if (node["type"].asString() == "workspace") return {0, 0}; @@ -130,8 +121,8 @@ std::pair leafNodesInWorkspace(const Json::Value& node) { return {1, 0}; } } - int sum = 0; - int floating_sum = 0; + int sum{0}; + int floating_sum{0}; for (auto const& node : nodes) { std::pair all_leaf_nodes = leafNodesInWorkspace(node); sum += all_leaf_nodes.first; @@ -147,7 +138,7 @@ std::pair leafNodesInWorkspace(const Json::Value& node) { std::optional> getSingleChildNode( const Json::Value& node) { - auto const& nodes = node["nodes"]; + auto const& nodes{node["nodes"]}; if (nodes.empty()) { if (node["type"].asString() == "workspace") return {}; @@ -157,11 +148,11 @@ std::optional> getSingleChildNode( return {std::cref(node)}; } } - auto it = std::cbegin(nodes); + auto it{std::cbegin(nodes)}; if (it == std::cend(nodes)) { return {}; } - auto const& child = *it; + auto const& child{*it}; ++it; if (it != std::cend(nodes)) { return {}; @@ -170,12 +161,12 @@ std::optional> getSingleChildNode( } std::tuple getWindowInfo(const Json::Value& node) { - const auto app_id = node["app_id"].isString() ? node["app_id"].asString() - : node["window_properties"]["instance"].asString(); - const auto app_class = node["window_properties"]["class"].isString() - ? node["window_properties"]["class"].asString() - : ""; - const auto shell = node["shell"].isString() ? node["shell"].asString() : ""; + const auto app_id{node["app_id"].isString() ? node["app_id"].asString() + : node["window_properties"]["instance"].asString()}; + const auto app_class{node["window_properties"]["class"].isString() + ? node["window_properties"]["class"].asString() + : ""}; + const auto shell{node["shell"].isString() ? node["shell"].asString() : ""}; return {app_id, app_class, shell}; } @@ -196,7 +187,7 @@ gfnWithWorkspace(const Json::Value& nodes, std::string& output, const Json::Valu continue; } if (node["focused"].asBool()) { - std::pair all_leaf_nodes = leafNodesInWorkspace(node); + std::pair all_leaf_nodes{leafNodesInWorkspace(node)}; return {all_leaf_nodes.first, all_leaf_nodes.second, node["id"].asInt(), @@ -215,12 +206,12 @@ gfnWithWorkspace(const Json::Value& nodes, std::string& output, const Json::Valu // found node spdlog::trace("actual output {}, output found {}, node (focused) found {}", bar_.output->name, output, node["name"].asString()); - const auto [app_id, app_class, shell] = getWindowInfo(node); - int nb = node.size(); - int floating_count = 0; - std::string workspace_layout = ""; + const auto [app_id, app_class, shell]{getWindowInfo(node)}; + int nb{node.size()}; + int floating_count{0}; + std::string workspace_layout{""}; if (!parentWorkspace.isNull()) { - std::pair all_leaf_nodes = leafNodesInWorkspace(parentWorkspace); + std::pair all_leaf_nodes{leafNodesInWorkspace(parentWorkspace)}; nb = all_leaf_nodes.first; floating_count = all_leaf_nodes.second; workspace_layout = parentWorkspace["layout"].asString(); @@ -236,10 +227,10 @@ gfnWithWorkspace(const Json::Value& nodes, std::string& output, const Json::Valu } // iterate - auto [nb, f, id, name, app_id, app_class, shell, workspace_layout] = - gfnWithWorkspace(node["nodes"], output, config_, bar_, parentWorkspace, node); - auto [nb2, f2, id2, name2, app_id2, app_class2, shell2, workspace_layout2] = - gfnWithWorkspace(node["floating_nodes"], output, config_, bar_, parentWorkspace, node); + auto [nb, f, id, name, app_id, app_class, shell, workspace_layout]{ + gfnWithWorkspace(node["nodes"], output, config_, bar_, parentWorkspace, node)}; + auto [nb2, f2, id2, name2, app_id2, app_class2, shell2, workspace_layout2]{ + gfnWithWorkspace(node["floating_nodes"], output, config_, bar_, parentWorkspace, node)}; // if ((id > 0 || ((id2 < 0 || name2.empty()) && id > -1)) && !name.empty()) { if ((id > 0) || (id2 < 0 && id > -1)) { @@ -252,14 +243,14 @@ gfnWithWorkspace(const Json::Value& nodes, std::string& output, const Json::Valu // this only comes into effect when no focused children are present if (config_["all-outputs"].asBool() && config_["offscreen-css"].asBool() && immediateParent["type"].asString() == "workspace") { - std::pair all_leaf_nodes = leafNodesInWorkspace(immediateParent); + std::pair all_leaf_nodes{leafNodesInWorkspace(immediateParent)}; // using an empty string as default ensures that no window depending styles are set due to the // checks above for !name.empty() - std::string app_id = ""; - std::string app_class = ""; - std::string workspace_layout = ""; + std::string app_id{""}; + std::string app_class{""}; + std::string workspace_layout{""}; if (all_leaf_nodes.first == 1) { - const auto single_child = getSingleChildNode(immediateParent); + const auto single_child{getSingleChildNode(immediateParent)}; if (single_child.has_value()) { std::tie(app_id, app_class, workspace_layout) = getWindowInfo(single_child.value()); } @@ -281,7 +272,7 @@ gfnWithWorkspace(const Json::Value& nodes, std::string& output, const Json::Valu std::tuple Window::getFocusedNode(const Json::Value& nodes, std::string& output) { - Json::Value placeholder = Json::Value::null; + Json::Value placeholder{Json::Value::null}; return gfnWithWorkspace(nodes, output, config_, bar_, placeholder, placeholder); } diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 8f273300e..33d425f98 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -2,10 +2,6 @@ #include -#include -#include -#include - namespace waybar::modules::sway { // Helper function to assign a number to a workspace, just like sway. In fact @@ -42,8 +38,9 @@ int Workspaces::windowRewritePriorityFunction(std::string const &window_rule) { } Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config) - : AModule(config, "workspaces", id, false, !config["disable-scroll"].asBool()), - bar_(bar), + : AModule(config, "workspaces", id, false, + !config["disable-scroll"].asBool() || config["enable-bar-scroll"].asBool()), + bar_{bar}, box_(bar.orientation, 0) { if (config["format-icons"]["high-priority-named"].isArray()) { for (const auto &it : config["format-icons"]["high-priority-named"]) { @@ -55,7 +52,12 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value box_.get_style_context()->add_class(id); } box_.get_style_context()->add_class(MODULE_CLASS); - event_box_.add(box_); + + if (!config["disable-scroll"].asBool() || config["enable-bar-scroll"].asBool()) { + controllScroll_->signal_scroll().connect(sigc::mem_fun(*this, &Workspaces::handleScroll), true); + controllScroll_->set_propagation_phase(Gtk::PropagationPhase::BUBBLE); + } + if (config_["format-window-separator"].isString()) { m_formatWindowSeperator = config_["format-window-separator"].asString(); } else { @@ -75,11 +77,6 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value ipc_.signal_event.connect(sigc::mem_fun(*this, &Workspaces::onEvent)); ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Workspaces::onCmd)); ipc_.sendCmd(IPC_GET_TREE); - if (config["enable-bar-scroll"].asBool()) { - auto &window = const_cast(bar_).window; - window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); - window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll)); - } // Launch worker ipc_.setWorker([this] { try { @@ -88,6 +85,8 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value spdlog::error("Workspaces: {}", e.what()); } }); + + AModule::bindEvents(*this); } void Workspaces::onEvent(const struct Ipc::ipc_response &res) { @@ -102,11 +101,11 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { if (res.type == IPC_GET_TREE) { try { { - std::lock_guard lock(mutex_); - auto payload = parser_.parse(res.payload); + std::lock_guard lock{mutex_}; + const auto payload{parser_.parse(res.payload)}; workspaces_.clear(); std::vector outputs; - bool alloutputs = config_["all-outputs"].asBool(); + const bool alloutputs{config_["all-outputs"].asBool()}; std::copy_if(payload["nodes"].begin(), payload["nodes"].end(), std::back_inserter(outputs), [&](const auto &output) { if (alloutputs && output["name"].asString() != "__i3") { @@ -127,15 +126,15 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { // adding persistent workspaces (as per the config file) if (config_["persistent-workspaces"].isObject()) { - const Json::Value &p_workspaces = config_["persistent-workspaces"]; - const std::vector p_workspaces_names = p_workspaces.getMemberNames(); + 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) { - const Json::Value &p_w = p_workspaces[p_w_name]; - auto it = std::find_if(workspaces_.begin(), workspaces_.end(), - [&p_w_name](const Json::Value &node) { - return node["name"].asString() == p_w_name; - }); + const Json::Value &p_w{p_workspaces[p_w_name]}; + auto it{std::find_if(workspaces_.begin(), workspaces_.end(), + [&p_w_name](const Json::Value &node) { + return node["name"].asString() == p_w_name; + })}; if (it != workspaces_.end()) { continue; // already displayed by some bar @@ -185,12 +184,12 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { // Note: if the 'alphabetical_sort' option is true, the user is in // agreement that the "workspace prev/next" commands may not follow // the order displayed in Waybar. - int max_num = -1; + int max_num{-1}; for (auto &workspace : workspaces_) { max_num = std::max(workspace["num"].asInt(), max_num); } for (auto &workspace : workspaces_) { - auto workspace_num = workspace["num"].asInt(); + auto workspace_num{workspace["num"].asInt()}; if (workspace_num > -1) { workspace["sort"] = workspace_num; } else { @@ -199,10 +198,10 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { } std::sort(workspaces_.begin(), workspaces_.end(), [this](const Json::Value &lhs, const Json::Value &rhs) { - auto lname = lhs["name"].asString(); - auto rname = rhs["name"].asString(); - int l = lhs["sort"].asInt(); - int r = rhs["sort"].asInt(); + auto lname{lhs["name"].asString()}; + auto rname{rhs["name"].asString()}; + int l{lhs["sort"].asInt()}; + int r{rhs["sort"].asInt()}; if (l == r || config_["alphabetical_sort"].asBool()) { // In case both integers are the same, lexicographical @@ -225,10 +224,10 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { } bool Workspaces::filterButtons() { - bool needReorder = false; - for (auto it = buttons_.begin(); it != buttons_.end();) { - auto ws = std::find_if(workspaces_.begin(), workspaces_.end(), - [it](const auto &node) { return node["name"].asString() == it->first; }); + bool needReorder{false}; + for (auto it{buttons_.begin()}; it != buttons_.end();) { + auto ws{std::find_if(workspaces_.begin(), workspaces_.end(), + [it](const auto &node) { return node["name"].asString() == it->first; })}; if (ws == workspaces_.end() || (!config_["all-outputs"].asBool() && (*ws)["output"].asString() != bar_.output->name)) { it = buttons_.erase(it); @@ -282,18 +281,25 @@ void Workspaces::updateWindows(const Json::Value &node, std::string &windows) { } auto Workspaces::update() -> void { - std::lock_guard lock(mutex_); - bool needReorder = filterButtons(); - for (auto it = workspaces_.begin(); it != workspaces_.end(); ++it) { - auto bit = buttons_.find((*it)["name"].asString()); + std::lock_guard lock{mutex_}; + bool needReorder{filterButtons()}; + for (auto it{workspaces_.begin()}; it != workspaces_.end(); ++it) { + auto bit{buttons_.find((*it)["name"].asString())}; if (bit == buttons_.end()) { needReorder = true; } - auto &button = bit == buttons_.end() ? addButton(*it) : bit->second; + auto &button{bit == buttons_.end() ? addButton(*it) : bit->second}; if (needReorder) { - box_.reorder_child(button, it - workspaces_.begin()); + std::unordered_map::const_iterator prevBit; + + if (it != workspaces_.begin()) prevBit = buttons_.find((*(it - 1))["name"].asString()); + + if (prevBit != buttons_.end()) + box_.reorder_child_after(button, prevBit->second); + else + box_.reorder_child_at_start(button); } - bool noNodes = (*it)["nodes"].empty() && (*it)["floating_nodes"].empty(); + bool noNodes{(*it)["nodes"].empty() && (*it)["floating_nodes"].empty()}; if (hasFlag((*it), "focused")) { button.get_style_context()->add_class("focused"); } else { @@ -328,13 +334,13 @@ auto Workspaces::update() -> void { } else { button.get_style_context()->remove_class("current_output"); } - std::string output = (*it)["name"].asString(); - std::string windows = ""; + std::string output{(*it)["name"].asString()}; + std::string windows{""}; if (config_["window-format"].isString()) { updateWindows((*it), windows); } if (config_["format"].isString()) { - auto format = config_["format"].asString(); + auto format{config_["format"].asString()}; output = fmt::format( fmt::runtime(format), fmt::arg("icon", getIcon(output, *it)), fmt::arg("value", output), fmt::arg("name", trimWorkspaceName(output)), fmt::arg("index", (*it)["num"].asString()), @@ -343,7 +349,7 @@ auto Workspaces::update() -> void { fmt::arg("output", (*it)["output"].asString())); } if (!config_["disable-markup"].asBool()) { - static_cast(button.get_children()[0])->set_markup(output); + static_cast(button.get_child())->set_markup(output); } else { button.set_label(output); } @@ -354,13 +360,15 @@ auto Workspaces::update() -> void { } Gtk::Button &Workspaces::addButton(const Json::Value &node) { - auto pair = buttons_.emplace(node["name"].asString(), node["name"].asString()); - auto &&button = pair.first->second; - box_.pack_start(button, false, false, 0); + auto pair{buttons_.emplace(node["name"].asString(), node["name"].asString())}; + auto &&button{pair.first->second}; + box_.append(button); button.set_name("sway-workspace-" + node["name"].asString()); - button.set_relief(Gtk::RELIEF_NONE); + button.set_has_frame(false); if (!config_["disable-click"].asBool()) { - button.signal_pressed().connect([this, node] { + auto controlClick{Gtk::GestureClick::create()}; + button.add_controller(controlClick); + controlClick->signal_pressed().connect([this, node](int n_press, double dx, double dy) { try { if (node["target_output"].isString()) { ipc_.sendCmd(IPC_COMMAND, @@ -378,16 +386,18 @@ Gtk::Button &Workspaces::addButton(const Json::Value &node) { spdlog::error("Workspaces: {}", e.what()); } }); + controlClick->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); + controlClick->set_button(1u); } return button; } std::string Workspaces::getIcon(const std::string &name, const Json::Value &node) { - std::vector keys = {"high-priority-named", "urgent", "focused", name, "default"}; + std::vector keys{"high-priority-named", "urgent", "focused", name, "default"}; for (auto const &key : keys) { if (key == "high-priority-named") { - auto it = std::find_if(high_priority_named_.begin(), high_priority_named_.end(), - [&](const std::string &member) { return member == name; }); + auto it{std::find_if(high_priority_named_.begin(), high_priority_named_.end(), + [&](const std::string &member) { return member == name; })}; if (it != high_priority_named_.end()) { return config_["format-icons"][name].asString(); } @@ -416,29 +426,30 @@ std::string Workspaces::getIcon(const std::string &name, const Json::Value &node return name; } -bool Workspaces::handleScroll(GdkEventScroll *e) { - if (gdk_event_get_pointer_emulated((GdkEvent *)e) != 0) { +bool Workspaces::handleScroll(double dx, double dy) { + auto currEvent{controllScroll_->get_current_event()}; + if (currEvent->get_pointer_emulated()) { /** * Ignore emulated scroll events on window */ return false; } - auto dir = AModule::getScrollDir(e); + auto dir{AModule::getScrollDir(currEvent)}; if (dir == SCROLL_DIR::NONE) { return true; } std::string name; { - bool alloutputs = config_["all-outputs"].asBool(); - std::lock_guard lock(mutex_); - auto it = + std::lock_guard lock{mutex_}; + const bool alloutputs{config_["all-outputs"].asBool()}; + auto it{ std::find_if(workspaces_.begin(), workspaces_.end(), [alloutputs](const auto &workspace) { if (alloutputs) { return hasFlag(workspace, "focused"); } - bool noNodes = workspace["nodes"].empty() && workspace["floating_nodes"].empty(); + const bool noNodes{workspace["nodes"].empty() && workspace["floating_nodes"].empty()}; return hasFlag(workspace, "visible") || (workspace["output"].isString() && noNodes); - }); + })}; if (it == workspaces_.end()) { return true; } @@ -486,7 +497,7 @@ std::string Workspaces::getCycleWorkspace(std::vector::iterator it, } std::string Workspaces::trimWorkspaceName(std::string name) { - std::size_t found = name.find(':'); + std::size_t found{name.find(':')}; if (found != std::string::npos) { return name.substr(found + 1); } @@ -512,4 +523,6 @@ void Workspaces::onButtonReady(const Json::Value &node, Gtk::Button &button) { } } +Workspaces::operator Gtk::Widget &() { return box_; }; + } // namespace waybar::modules::sway diff --git a/src/modules/systemd_failed_units.cpp b/src/modules/systemd_failed_units.cpp index 56e624cf2..7b33ff2db 100644 --- a/src/modules/systemd_failed_units.cpp +++ b/src/modules/systemd_failed_units.cpp @@ -1,7 +1,5 @@ #include "modules/systemd_failed_units.hpp" -#include -#include #include #include @@ -29,8 +27,8 @@ SystemdFailedUnits::SystemdFailedUnits(const std::string& id, const Json::Value& /* Default to enable both "system" and "user". */ if (!config["system"].isBool() || config["system"].asBool()) { system_proxy = Gio::DBus::Proxy::create_for_bus_sync( - Gio::DBus::BusType::BUS_TYPE_SYSTEM, "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", "org.freedesktop.DBus.Properties"); + Gio::DBus::BusType::SYSTEM, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties"); if (!system_proxy) { throw std::runtime_error("Unable to connect to systemwide systemd DBus!"); } @@ -38,8 +36,8 @@ SystemdFailedUnits::SystemdFailedUnits(const std::string& id, const Json::Value& } if (!config["user"].isBool() || config["user"].asBool()) { user_proxy = Gio::DBus::Proxy::create_for_bus_sync( - Gio::DBus::BusType::BUS_TYPE_SESSION, "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", "org.freedesktop.DBus.Properties"); + Gio::DBus::BusType::SESSION, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties"); if (!user_proxy) { throw std::runtime_error("Unable to connect to user systemd DBus!"); } @@ -85,7 +83,7 @@ void SystemdFailedUnits::updateData() { } } } catch (Glib::Error& e) { - spdlog::error("Failed to get {} failed units: {}", kind, e.what().c_str()); + spdlog::error("Failed to get {} failed units: {}", kind, e.what()); } return 0; }; @@ -104,11 +102,11 @@ auto SystemdFailedUnits::update() -> void { // Hide if needed. if (nr_failed == 0 && hide_on_ok) { - event_box_.set_visible(false); + label_.set_visible(false); return; } - if (!event_box_.get_visible()) { - event_box_.set_visible(true); + if (!label_.get_visible()) { + label_.set_visible(true); } // Set state class. diff --git a/src/modules/temperature.cpp b/src/modules/temperature.cpp index 302877639..cd4cd8992 100644 --- a/src/modules/temperature.cpp +++ b/src/modules/temperature.cpp @@ -1,6 +1,9 @@ #include "modules/temperature.hpp" +#include + #include +#include #include #if defined(__FreeBSD__) @@ -78,11 +81,11 @@ auto waybar::modules::Temperature::update() -> void { } if (format.empty()) { - event_box_.hide(); + label_.hide(); return; } - event_box_.show(); + label_.show(); auto max_temp = config_["critical-threshold"].isInt() ? config_["critical-threshold"].asInt() : 0; label_.set_markup(fmt::format(fmt::runtime(format), fmt::arg("temperatureC", temperature_c), diff --git a/src/modules/ui.cpp b/src/modules/ui.cpp new file mode 100644 index 000000000..c3c49a5b7 --- /dev/null +++ b/src/modules/ui.cpp @@ -0,0 +1,40 @@ +#include "modules/ui.hpp" + +#include +#include + +#include + +waybar::modules::UI::UI(const std::string& name, const std::string& id, const Json::Value& config) + : AModule(config, "ui-" + name, id, false, false) { + if (config_["file-path"].isString()) { + Glib::RefPtr builder{ + Gtk::Builder::create_from_file(config_["file-path"].asString())}; + uiWg_ = builder->get_object(name_); + + if (uiWg_) { + uiWg_->set_name(name_); + if (!id.empty()) { + uiWg_->get_style_context()->add_class(id); + } + uiWg_->get_style_context()->add_class(MODULE_CLASS); + + Glib::RefPtr actionGroup{Gio::SimpleActionGroup::create()}; + Glib::RefPtr action{actionGroup->add_action_with_parameter( + "doAction", Glib::VARIANT_TYPE_STRING, [this](const Glib::VariantBase& param) { + assert(param.is_of_type(Glib::VARIANT_TYPE_STRING)); + waybar::util::command::res res = + waybar::util::command::exec(param.get_dynamic(), "TLP"); + })}; + + uiWg_->insert_action_group(name_, actionGroup); + AModule::bindEvents(*uiWg_.get()); + } else { + spdlog::error("UI: object id \"{}\" is not found at \"{}\"", name_, + config_["file-path"].asString()); + exit(EXIT_FAILURE); + } + } +} + +waybar::modules::UI::operator Gtk::Widget&() { return *uiWg_.get(); }; diff --git a/src/modules/upower.cpp b/src/modules/upower.cpp index 5ee6d64c5..3d127ca2f 100644 --- a/src/modules/upower.cpp +++ b/src/modules/upower.cpp @@ -12,11 +12,11 @@ UPower::UPower(const std::string &id, const Json::Value &config) box_.set_spacing(0); box_.set_has_tooltip(AModule::tooltipEnabled()); // Tooltip box - contentBox_.set_orientation((box_.get_orientation() == Gtk::ORIENTATION_HORIZONTAL) - ? Gtk::ORIENTATION_VERTICAL - : Gtk::ORIENTATION_HORIZONTAL); + contentBox_.set_orientation((box_.get_orientation() == Gtk::Orientation::HORIZONTAL) + ? Gtk::Orientation::VERTICAL + : Gtk::Orientation::HORIZONTAL); // Get current theme - gtkTheme_ = Gtk::IconTheme::get_default(); + gtkTheme_ = Gtk::IconTheme::get_for_display(box_.get_display()); // Icon Size if (config_["icon-size"].isInt()) { @@ -41,10 +41,7 @@ UPower::UPower(const std::string &id, const Json::Value &config) // Tooltip Padding if (config_["tooltip-padding"].isInt()) { tooltip_padding_ = config_["tooltip-padding"].asInt(); - contentBox_.set_margin_top(tooltip_padding_); - contentBox_.set_margin_bottom(tooltip_padding_); - contentBox_.set_margin_left(tooltip_padding_); - contentBox_.set_margin_right(tooltip_padding_); + contentBox_.set_margin(tooltip_padding_); } // Tooltip Format @@ -52,12 +49,10 @@ UPower::UPower(const std::string &id, const Json::Value &config) // Start watching DBUS watcherID_ = Gio::DBus::watch_name( - Gio::DBus::BusType::BUS_TYPE_SYSTEM, "org.freedesktop.UPower", - sigc::mem_fun(*this, &UPower::onAppear), sigc::mem_fun(*this, &UPower::onVanished), - Gio::DBus::BusNameWatcherFlags::BUS_NAME_WATCHER_FLAGS_AUTO_START); + Gio::DBus::BusType::SYSTEM, "org.freedesktop.UPower", sigc::mem_fun(*this, &UPower::onAppear), + sigc::mem_fun(*this, &UPower::onVanished), Gio::DBus::BusNameWatcherFlags::AUTO_START); // Get DBus async connect - Gio::DBus::Connection::get(Gio::DBus::BusType::BUS_TYPE_SYSTEM, - sigc::mem_fun(*this, &UPower::getConn_cb)); + Gio::DBus::Connection::get(Gio::DBus::BusType::SYSTEM, sigc::mem_fun(*this, &UPower::getConn_cb)); // Make UPower client GError **gErr = NULL; @@ -91,6 +86,17 @@ UPower::~UPower() { removeDevices(); } +static const char *getDeviceWarningLevel(UpDeviceLevel level) { + switch (level) { + case UP_DEVICE_LEVEL_CRITICAL: + return "critical"; + case UP_DEVICE_LEVEL_LOW: + return "low"; + default: + return nullptr; + } +} + static const std::string getDeviceStatus(UpDeviceState &state) { switch (state) { case UP_DEVICE_STATE_CHARGING: @@ -211,6 +217,15 @@ auto UPower::update() -> void { if (!box_.get_style_context()->has_class(status)) box_.get_style_context()->add_class(status); lastStatus_ = status; + const char *warning_level = getDeviceWarningLevel(upDevice_.level); + if (lastWarningLevel_ && box_.get_style_context()->has_class(lastWarningLevel_)) { + box_.get_style_context()->remove_class(lastWarningLevel_); + } + if (warning_level && !box_.get_style_context()->has_class(warning_level)) { + box_.get_style_context()->add_class(warning_level); + } + lastWarningLevel_ = warning_level; + if (devices_.size() == 0 && !upDeviceValid && hideIfEmpty_) { box_.hide(); // Call parent update @@ -222,7 +237,7 @@ auto UPower::update() -> void { // Set icon if (upDevice_.icon_name == NULL || !gtkTheme_->has_icon(upDevice_.icon_name)) upDevice_.icon_name = (char *)NO_BATTERY.c_str(); - image_.set_from_icon_name(upDevice_.icon_name, Gtk::ICON_SIZE_INVALID); + image_.set_from_icon_name(upDevice_.icon_name); box_.show(); @@ -239,7 +254,7 @@ void UPower::getConn_cb(Glib::RefPtr &result) { "PrepareForSleep", "/org/freedesktop/login1"); } catch (const Glib::Error &e) { - spdlog::error("Upower. DBus connection error. {}", e.what().c_str()); + spdlog::error("Upower. DBus connection error. {}", e.what()); } } @@ -403,14 +418,14 @@ void UPower::getUpDeviceInfo(upDevice_output &upDevice_) { "percentage", &upDevice_.percentage, "icon-name", &upDevice_.icon_name, "time-to-empty", &upDevice_.time_empty, "time-to-full", &upDevice_.time_full, "temperature", &upDevice_.temperature, "native-path", &upDevice_.nativePath, - "model", &upDevice_.model, NULL); + "model", &upDevice_.model, "warning-level", &upDevice_.level, NULL); spdlog::debug( "UPower. getUpDeviceInfo. kind: \"{0}\". state: \"{1}\". percentage: \"{2}\". \ icon_name: \"{3}\". time-to-empty: \"{4}\". time-to-full: \"{5}\". temperature: \"{6}\". \ -native_path: \"{7}\". model: \"{8}\"", +native_path: \"{7}\". model: \"{8}\". level: \"{9}\"", fmt::format_int(upDevice_.kind).str(), fmt::format_int(upDevice_.state).str(), upDevice_.percentage, upDevice_.icon_name, upDevice_.time_empty, upDevice_.time_full, - upDevice_.temperature, upDevice_.nativePath, upDevice_.model); + upDevice_.temperature, upDevice_.nativePath, upDevice_.model, upDevice_.level); } } @@ -447,8 +462,8 @@ bool UPower::queryTooltipCb(int x, int y, bool keyboard_tooltip, std::lock_guard guard{mutex_}; // Clear content box - contentBox_.forall([this](Gtk::Widget &wg) { contentBox_.remove(wg); }); - + for (auto child{contentBox_.get_last_child()}; child; child = contentBox_.get_last_child()) + contentBox_.remove(*child); // Fill content box with the content for (auto pairDev : devices_) { // Get device info @@ -458,38 +473,37 @@ bool UPower::queryTooltipCb(int x, int y, bool keyboard_tooltip, pairDev.second.kind != UpDeviceKind::UP_DEVICE_KIND_LINE_POWER) { // Make box record Gtk::Box *boxRec{new Gtk::Box{box_.get_orientation(), tooltip_spacing_}}; - contentBox_.add(*boxRec); + contentBox_.append(*boxRec); Gtk::Box *boxDev{new Gtk::Box{box_.get_orientation()}}; Gtk::Box *boxUsr{new Gtk::Box{box_.get_orientation()}}; - boxRec->add(*boxDev); - boxRec->add(*boxUsr); + boxRec->append(*boxDev); + boxRec->append(*boxUsr); // Construct device box // Set icon from kind std::string iconNameDev{getDeviceIcon(pairDev.second.kind)}; if (!gtkTheme_->has_icon(iconNameDev)) iconNameDev = (char *)NO_BATTERY.c_str(); Gtk::Image *iconDev{new Gtk::Image{}}; - iconDev->set_from_icon_name(iconNameDev, Gtk::ICON_SIZE_INVALID); + iconDev->set_from_icon_name(iconNameDev); iconDev->set_pixel_size(iconSize_); - boxDev->add(*iconDev); + boxDev->append(*iconDev); // Set label from model Gtk::Label *labelDev{new Gtk::Label{pairDev.second.model}}; - boxDev->add(*labelDev); + boxDev->append(*labelDev); // Construct user box // Set icon from icon state if (pairDev.second.icon_name == NULL || !gtkTheme_->has_icon(pairDev.second.icon_name)) pairDev.second.icon_name = (char *)NO_BATTERY.c_str(); Gtk::Image *iconTooltip{new Gtk::Image{}}; - iconTooltip->set_from_icon_name(pairDev.second.icon_name, Gtk::ICON_SIZE_INVALID); + iconTooltip->set_from_icon_name(pairDev.second.icon_name); iconTooltip->set_pixel_size(iconSize_); - boxUsr->add(*iconTooltip); + boxUsr->append(*iconTooltip); // Set markup text Gtk::Label *labelTooltip{new Gtk::Label{}}; labelTooltip->set_markup(getText(pairDev.second, tooltipFormat_)); - boxUsr->add(*labelTooltip); + boxUsr->append(*labelTooltip); } } tooltip->set_custom(contentBox_); - contentBox_.show_all(); return true; } diff --git a/src/modules/user.cpp b/src/modules/user.cpp index 418fc5858..0acdcda55 100644 --- a/src/modules/user.cpp +++ b/src/modules/user.cpp @@ -1,18 +1,8 @@ #include "modules/user.hpp" #include +#include #include -#include - -#include -#include - -#include "gdkmm/cursor.h" -#include "gdkmm/event.h" -#include "gdkmm/types.h" -#include "glibmm/fileutils.h" -#include "sigc++/functors/mem_fun.h" -#include "sigc++/functors/ptr_fun.h" #if HAVE_CPU_LINUX #include @@ -34,9 +24,10 @@ User::User(const std::string& id, const Json::Value& config) this->init_update_worker(); } -bool User::handleToggle(GdkEventButton* const& e) { +void User::handleToggle(int n_press, double dx, double dy) { if (AIconLabel::config_["open-on-click"].isBool() && - AIconLabel::config_["open-on-click"].asBool() && e->button == LEFT_MOUSE_BUTTON_CODE) { + AIconLabel::config_["open-on-click"].asBool() && + controllClick_->get_current_button() == LEFT_MOUSE_BUTTON_CODE) { std::string openPath = this->get_user_home_dir(); if (AIconLabel::config_["open-path"].isString()) { std::string customPath = AIconLabel::config_["open-path"].asString(); @@ -47,7 +38,6 @@ bool User::handleToggle(GdkEventButton* const& e) { Gio::AppInfo::launch_default_for_uri("file:///" + openPath); } - return true; } long User::uptime_as_seconds() { @@ -108,7 +98,7 @@ void User::init_default_user_avatar(int width, int height) { } void User::init_user_avatar(const std::string& path, int width, int height) { - if (Glib::file_test(path, Glib::FILE_TEST_EXISTS)) { + if (Glib::file_test(path, Glib::FileTest::EXISTS)) { Glib::RefPtr pixbuf_ = Gdk::Pixbuf::create_from_file(path, width, height); AIconLabel::image_.set(pixbuf_); } else { diff --git a/src/modules/wireplumber.cpp b/src/modules/wireplumber.cpp index eddc3e6be..9113cded6 100644 --- a/src/modules/wireplumber.cpp +++ b/src/modules/wireplumber.cpp @@ -292,9 +292,6 @@ void waybar::modules::Wireplumber::onMixerApiLoaded(WpObject* p, GAsyncResult* r self->activatePlugins(); self->dp.emit(); - - self->event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); - self->event_box_.signal_scroll_event().connect(sigc::mem_fun(*self, &Wireplumber::handleScroll)); } void waybar::modules::Wireplumber::asyncLoadRequiredApiModules() { @@ -340,11 +337,11 @@ auto waybar::modules::Wireplumber::update() -> void { ALabel::update(); } -bool waybar::modules::Wireplumber::handleScroll(GdkEventScroll* e) { +bool waybar::modules::Wireplumber::handleScroll(double dx, double dy) { if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { - return AModule::handleScroll(e); + return AModule::handleScroll(dx, dy); } - auto dir = AModule::getScrollDir(e); + auto dir = AModule::getScrollDir(controllScroll_->get_current_event()); if (dir == SCROLL_DIR::NONE) { return true; } diff --git a/src/util/audio_backend.cpp b/src/util/audio_backend.cpp index 3d90b6d5a..dfba2578e 100644 --- a/src/util/audio_backend.cpp +++ b/src/util/audio_backend.cpp @@ -3,23 +3,19 @@ #include #include #include -#include -#include #include -#include -#include namespace waybar::util { AudioBackend::AudioBackend(std::function on_updated_cb, private_constructor_tag tag) - : mainloop_(nullptr), - mainloop_api_(nullptr), - context_(nullptr), - volume_(0), - muted_(false), - source_volume_(0), - source_muted_(false), + : mainloop_{nullptr}, + mainloop_api_{nullptr}, + context_{nullptr}, + volume_{0}, + muted_{false}, + source_volume_{0}, + source_muted_{false}, on_updated_cb_(std::move(on_updated_cb)) { mainloop_ = pa_threaded_mainloop_new(); if (mainloop_ == nullptr) { @@ -65,7 +61,7 @@ void AudioBackend::connectContext() { } void AudioBackend::contextStateCb(pa_context *c, void *data) { - auto *backend = static_cast(data); + auto *backend{static_cast(data)}; switch (pa_context_get_state(c)) { case PA_CONTEXT_TERMINATED: backend->mainloop_api_->quit(backend->mainloop_api_, 0); @@ -104,8 +100,8 @@ void AudioBackend::contextStateCb(pa_context *c, void *data) { */ void AudioBackend::subscribeCb(pa_context *context, pa_subscription_event_type_t type, uint32_t idx, void *data) { - unsigned facility = type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; - unsigned operation = type & PA_SUBSCRIPTION_EVENT_TYPE_MASK; + unsigned facility{type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK}; + unsigned operation{type & PA_SUBSCRIPTION_EVENT_TYPE_MASK}; if (operation != PA_SUBSCRIPTION_EVENT_CHANGE) { return; } @@ -126,7 +122,7 @@ void AudioBackend::subscribeCb(pa_context *context, pa_subscription_event_type_t * Called in response to a volume change request */ void AudioBackend::volumeModifyCb(pa_context *c, int success, void *data) { - auto *backend = static_cast(data); + auto *backend{static_cast(data)}; if (success != 0) { pa_context_get_sink_info_by_index(backend->context_, backend->sink_idx_, sinkInfoCb, data); } @@ -139,7 +135,7 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i void *data) { if (i == nullptr) return; - auto *backend = static_cast(data); + auto *backend{static_cast(data)}; if (!backend->ignored_sinks_.empty()) { for (const auto &ignored_sink : backend->ignored_sinks_) { @@ -166,15 +162,15 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i if (backend->current_sink_name_ == i->name) { backend->pa_volume_ = i->volume; - float volume = - static_cast(pa_cvolume_avg(&(backend->pa_volume_))) / float{PA_VOLUME_NORM}; + float volume{static_cast(pa_cvolume_avg(&(backend->pa_volume_))) / + float{PA_VOLUME_NORM}}; backend->sink_idx_ = i->index; backend->volume_ = std::round(volume * 100.0F); backend->muted_ = i->mute != 0; backend->desc_ = i->description; backend->monitor_ = i->monitor_source_name; backend->port_name_ = i->active_port != nullptr ? i->active_port->name : "Unknown"; - if (const auto *ff = pa_proplist_gets(i->proplist, PA_PROP_DEVICE_FORM_FACTOR)) { + if (const auto ff{pa_proplist_gets(i->proplist, PA_PROP_DEVICE_FORM_FACTOR)}) { backend->form_factor_ = ff; } else { backend->form_factor_ = ""; @@ -188,9 +184,9 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i */ void AudioBackend::sourceInfoCb(pa_context * /*context*/, const pa_source_info *i, int /*eol*/, void *data) { - auto *backend = static_cast(data); + auto *backend{static_cast(data)}; if (i != nullptr && backend->default_source_name_ == i->name) { - auto source_volume = static_cast(pa_cvolume_avg(&(i->volume))) / float{PA_VOLUME_NORM}; + auto source_volume{static_cast(pa_cvolume_avg(&(i->volume))) / float{PA_VOLUME_NORM}}; backend->source_volume_ = std::round(source_volume * 100.0F); backend->source_idx_ = i->index; backend->source_muted_ = i->mute != 0; @@ -205,7 +201,7 @@ void AudioBackend::sourceInfoCb(pa_context * /*context*/, const pa_source_info * * used to find the default PulseAudio sink. */ void AudioBackend::serverInfoCb(pa_context *context, const pa_server_info *i, void *data) { - auto *backend = static_cast(data); + auto *backend{static_cast(data)}; backend->current_sink_name_ = i->default_sink_name; backend->default_source_name_ = i->default_source_name; @@ -214,7 +210,7 @@ void AudioBackend::serverInfoCb(pa_context *context, const pa_server_info *i, vo } void AudioBackend::changeVolume(uint16_t volume, uint16_t min_volume, uint16_t max_volume) { - double volume_tick = static_cast(PA_VOLUME_NORM) / 100; + double volume_tick{static_cast(PA_VOLUME_NORM) / 100}; pa_cvolume pa_volume = pa_volume_; volume = std::clamp(volume, min_volume, max_volume); @@ -224,7 +220,7 @@ void AudioBackend::changeVolume(uint16_t volume, uint16_t min_volume, uint16_t m } void AudioBackend::changeVolume(ChangeType change_type, double step, uint16_t max_volume) { - double volume_tick = static_cast(PA_VOLUME_NORM) / 100; + double volume_tick{static_cast(PA_VOLUME_NORM) / 100}; pa_volume_t change = volume_tick; pa_cvolume pa_volume = pa_volume_; diff --git a/src/util/backlight_backend.cpp b/src/util/backlight_backend.cpp index bb102cd93..fb602a949 100644 --- a/src/util/backlight_backend.cpp +++ b/src/util/backlight_backend.cpp @@ -1,12 +1,9 @@ #include "util/backlight_backend.hpp" #include -#include #include #include -#include -#include namespace { class FileDescriptor { @@ -152,8 +149,8 @@ BacklightBackend::BacklightBackend(std::chrono::milliseconds interval, // Connect to the login interface login_proxy_ = Gio::DBus::Proxy::create_for_bus_sync( - Gio::DBus::BusType::BUS_TYPE_SYSTEM, "org.freedesktop.login1", - "/org/freedesktop/login1/session/self", "org.freedesktop.login1.Session"); + Gio::DBus::BusType::SYSTEM, "org.freedesktop.login1", "/org/freedesktop/login1/session/self", + "org.freedesktop.login1.Session"); udev_thread_ = [this] { std::unique_ptr udev{udev_new()}; @@ -255,7 +252,7 @@ void BacklightBackend::set_brightness(const std::string &preferred_device, Chang if (best != nullptr) { const auto max = best->get_max(); - const auto abs_step = static_cast(round(step * max / 100.0F)); + const auto abs_step = static_cast(std::round(step * max / 100.0F)); const int new_brightness = change_type == ChangeType::Increase ? best->get_actual() + abs_step : best->get_actual() - abs_step; diff --git a/src/util/css_reload_helper.cpp b/src/util/css_reload_helper.cpp index 274bdeedd..a0fd8dd72 100644 --- a/src/util/css_reload_helper.cpp +++ b/src/util/css_reload_helper.cpp @@ -84,10 +84,10 @@ void waybar::CssReloadHelper::monitorChanges() { void waybar::CssReloadHelper::handleFileChange(Glib::RefPtr const& file, Glib::RefPtr const& other_type, - Gio::FileMonitorEvent event_type) { + Gio::FileMonitor::Event event_type) { // Multiple events are fired on file changed (attributes, write, changes done hint, etc.), only // fire for one - if (event_type == Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) { + if (event_type == Gio::FileMonitor::Event::CHANGES_DONE_HINT) { spdlog::debug("Reloading style, file changed: {}", file->get_path()); m_callback(); } diff --git a/src/util/gtk_icon.cpp b/src/util/gtk_icon.cpp deleted file mode 100644 index 5dd741f9a..000000000 --- a/src/util/gtk_icon.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "util/gtk_icon.hpp" - -/* We need a global mutex for accessing the object returned by Gtk::IconTheme::get_default() - * because it always returns the same object across different threads, and concurrent - * access can cause data corruption and lead to invalid memory access and crashes. - * Even concurrent calls that seem read only such as has_icon can cause issues because - * the GTK lib may update the internal icon cache on this calls. - */ - -std::mutex DefaultGtkIconThemeWrapper::default_theme_mutex; - -bool DefaultGtkIconThemeWrapper::has_icon(const std::string& value) { - const std::lock_guard lock(default_theme_mutex); - - return Gtk::IconTheme::get_default()->has_icon(value); -} - -Glib::RefPtr DefaultGtkIconThemeWrapper::load_icon(const char* name, int tmp_size, - Gtk::IconLookupFlags flags) { - const std::lock_guard lock(default_theme_mutex); - - auto default_theme = Gtk::IconTheme::get_default(); - default_theme->rescan_if_needed(); - return default_theme->load_icon(name, tmp_size, flags); -} diff --git a/src/util/pipewire/pipewire_backend.cpp b/src/util/pipewire/pipewire_backend.cpp index 5bb7c19a1..e817a9a4e 100644 --- a/src/util/pipewire/pipewire_backend.cpp +++ b/src/util/pipewire/pipewire_backend.cpp @@ -1,7 +1,5 @@ #include "util/pipewire/pipewire_backend.hpp" -#include "util/pipewire/privacy_node_info.hpp" - namespace waybar::util::PipewireBackend { static void getNodeInfo(void *data_, const struct pw_node_info *info) { diff --git a/src/util/pipewire/privacy_node_info.cpp b/src/util/pipewire/privacy_node_info.cpp index 739dc528f..c4bce92b2 100644 --- a/src/util/pipewire/privacy_node_info.cpp +++ b/src/util/pipewire/privacy_node_info.cpp @@ -15,12 +15,12 @@ std::string PrivacyNodeInfo::getName() { return name; } -std::string PrivacyNodeInfo::getIconName() { +std::string PrivacyNodeInfo::getIconName(const Glib::RefPtr theme) { const std::vector names{&application_icon_name, &pipewire_access_portal_app_id, &application_name, &node_name}; std::string name = "application-x-executable-symbolic"; for (const auto &item : names) { - if (item != nullptr && !item->empty() && DefaultGtkIconThemeWrapper::has_icon(*item)) { + if (item != nullptr && !item->empty() && theme->has_icon(*item)) { return *item; } } diff --git a/src/util/portal.cpp b/src/util/portal.cpp index 5874871b9..ed4bb06c8 100644 --- a/src/util/portal.cpp +++ b/src/util/portal.cpp @@ -36,7 +36,7 @@ auto fmt::formatter::format(waybar::Appearance c, format_con } waybar::Portal::Portal() - : DBus::Proxy(DBus::Connection::get_sync(DBus::BusType::BUS_TYPE_SESSION), PORTAL_BUS_NAME, + : DBus::Proxy(DBus::Connection::get_sync(DBus::BusType::SESSION), PORTAL_BUS_NAME, PORTAL_OBJ_PATH, PORTAL_INTERFACE), currentMode(Appearance::UNKNOWN) { refreshAppearance(); diff --git a/src/util/regex_collection.cpp b/src/util/regex_collection.cpp index 929e67cd6..4cb37447a 100644 --- a/src/util/regex_collection.cpp +++ b/src/util/regex_collection.cpp @@ -3,8 +3,6 @@ #include #include -#include - namespace waybar::util { int default_priority_function(std::string& key) { return 0; } diff --git a/src/util/rfkill.cpp b/src/util/rfkill.cpp index 61be7c5f6..f6b1c13b5 100644 --- a/src/util/rfkill.cpp +++ b/src/util/rfkill.cpp @@ -20,11 +20,7 @@ #include #include -#include #include -#include - -#include waybar::util::Rfkill::Rfkill(const enum rfkill_type rfkill_type) : rfkill_type_(rfkill_type) { fd_ = open("/dev/rfkill", O_RDONLY); @@ -32,15 +28,16 @@ waybar::util::Rfkill::Rfkill(const enum rfkill_type rfkill_type) : rfkill_type_( spdlog::error("Can't open RFKILL control device"); return; } - int rc = fcntl(fd_, F_SETFL, O_NONBLOCK); + int rc{fcntl(fd_, F_SETFL, O_NONBLOCK)}; if (rc < 0) { spdlog::error("Can't set RFKILL control device to non-blocking: {}", errno); close(fd_); fd_ = -1; return; } - Glib::signal_io().connect(sigc::mem_fun(*this, &Rfkill::on_event), fd_, - Glib::IO_IN | Glib::IO_ERR | Glib::IO_HUP); + Glib::signal_io().connect( + sigc::mem_fun(*this, &Rfkill::on_event), fd_, + Glib::IOCondition::IO_IN | Glib::IOCondition::IO_ERR | Glib::IOCondition::IO_HUP); } waybar::util::Rfkill::~Rfkill() { @@ -50,7 +47,7 @@ waybar::util::Rfkill::~Rfkill() { } bool waybar::util::Rfkill::on_event(Glib::IOCondition cond) { - if (cond & Glib::IO_IN) { + if ((cond & Glib::IOCondition::IO_IN) == Glib::IOCondition::IO_IN) { struct rfkill_event event; ssize_t len; diff --git a/subprojects/gtk-layer-shell.wrap b/subprojects/gtk-layer-shell.wrap deleted file mode 100644 index fc0ddf743..000000000 --- a/subprojects/gtk-layer-shell.wrap +++ /dev/null @@ -1,5 +0,0 @@ -[wrap-file] -directory = gtk-layer-shell-0.9.0 -source_filename = gtk-layer-shell-0.9.0.tar.gz -source_hash = 3809e5565d9ed02e44bb73787ff218523e8760fef65830afe60ea7322e22da1c -source_url = https://github.com/wmww/gtk-layer-shell/archive/v0.9.0/gtk-layer-shell-0.9.0.tar.gz diff --git a/subprojects/gtk4-layer-shell.wrap b/subprojects/gtk4-layer-shell.wrap new file mode 100644 index 000000000..70c5a2f3a --- /dev/null +++ b/subprojects/gtk4-layer-shell.wrap @@ -0,0 +1,8 @@ +[wrap-file] +directory = gtk4-layer-shell-1.0.3 +source_filename = gtk4-layer-shell-1.0.3.tar.gz +source_hash = 4d669c30b3dbc68ad69ade9752e6ebbe7be132db21a5a4734d42bc09c5481c34 +source_url = https://github.com/wmww/gtk4-layer-shell/archive/v1.0.3/gtk4-layer-shell-1.0.3.tar.gz + +[provide] +gtk-layer-shell = gtk_layer_shell