mirror of
				https://github.com/rad4day/Waybar.git
				synced 2025-10-30 15:32:43 +01:00 
			
		
		
		
	| @@ -1,35 +1,35 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <json/json.h> |  | ||||||
| #include "IModule.hpp" |  | ||||||
| #include <glibmm/markup.h> | #include <glibmm/markup.h> | ||||||
| #include <gtkmm/eventbox.h> | #include <gtkmm/eventbox.h> | ||||||
| #include <gtkmm/label.h> | #include <gtkmm/label.h> | ||||||
|  | #include <json/json.h> | ||||||
|  | #include "IModule.hpp" | ||||||
|  |  | ||||||
| namespace waybar { | namespace waybar { | ||||||
|  |  | ||||||
| class ALabel : public IModule { | class ALabel : public IModule { | ||||||
| public: |  public: | ||||||
|   ALabel(const Json::Value &, const std::string format, uint16_t interval = 0); |   ALabel(const Json::Value &, const std::string format, uint16_t interval = 0); | ||||||
|   virtual ~ALabel() = default; |   virtual ~ALabel() = default; | ||||||
|   virtual auto update() -> void; |   virtual auto        update() -> void; | ||||||
|   virtual std::string getIcon(uint16_t, const std::string &alt = ""); |   virtual std::string getIcon(uint16_t, const std::string &alt = ""); | ||||||
|   virtual operator Gtk::Widget &(); |   virtual             operator Gtk::Widget &(); | ||||||
|  |  | ||||||
| protected: |  protected: | ||||||
|   bool tooltipEnabled(); |   bool tooltipEnabled(); | ||||||
|  |  | ||||||
|   Gtk::EventBox event_box_; |   Gtk::EventBox              event_box_; | ||||||
|   Gtk::Label label_; |   Gtk::Label                 label_; | ||||||
|   const Json::Value &config_; |   const Json::Value &        config_; | ||||||
|   std::string format_; |   std::string                format_; | ||||||
|   std::mutex mutex_; |   std::mutex                 mutex_; | ||||||
|   const std::chrono::seconds interval_; |   const std::chrono::seconds interval_; | ||||||
|   bool alt_ = false; |   bool                       alt_ = false; | ||||||
|   std::string default_format_; |   std::string                default_format_; | ||||||
|  |  | ||||||
|   virtual bool handleToggle(GdkEventButton *const &ev); |   virtual bool handleToggle(GdkEventButton *const &ev); | ||||||
|   virtual bool handleScroll(GdkEventScroll *); |   virtual bool handleScroll(GdkEventScroll *); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace waybar | }  // namespace waybar | ||||||
|   | |||||||
| @@ -7,11 +7,11 @@ | |||||||
| namespace waybar { | namespace waybar { | ||||||
|  |  | ||||||
| class IModule { | class IModule { | ||||||
|   public: |  public: | ||||||
|     virtual ~IModule() = default; |   virtual ~IModule() = default; | ||||||
|     virtual auto update() -> void = 0; |   virtual auto     update() -> void = 0; | ||||||
|     virtual operator Gtk::Widget &() = 0; |   virtual          operator Gtk::Widget &() = 0; | ||||||
|     Glib::Dispatcher dp; // Hmmm Maybe I should create an abstract class ? |   Glib::Dispatcher dp;  // Hmmm Maybe I should create an abstract class ? | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar | ||||||
|   | |||||||
							
								
								
									
										116
									
								
								include/bar.hpp
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								include/bar.hpp
									
									
									
									
									
								
							| @@ -1,73 +1,69 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <json/json.h> |  | ||||||
| #include <glibmm/refptr.h> | #include <glibmm/refptr.h> | ||||||
| #include <gtkmm/main.h> |  | ||||||
| #include <gtkmm/cssprovider.h> | #include <gtkmm/cssprovider.h> | ||||||
|  | #include <gtkmm/main.h> | ||||||
| #include <gtkmm/window.h> | #include <gtkmm/window.h> | ||||||
|  | #include <json/json.h> | ||||||
|  | #include "IModule.hpp" | ||||||
|  | #include "idle-inhibit-unstable-v1-client-protocol.h" | ||||||
| #include "wlr-layer-shell-unstable-v1-client-protocol.h" | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||||||
| #include "xdg-output-unstable-v1-client-protocol.h" | #include "xdg-output-unstable-v1-client-protocol.h" | ||||||
| #include "idle-inhibit-unstable-v1-client-protocol.h" |  | ||||||
| #include "IModule.hpp" |  | ||||||
|  |  | ||||||
| namespace waybar { | namespace waybar { | ||||||
|  |  | ||||||
| class Client; |  | ||||||
| class Factory; | class Factory; | ||||||
|  | struct waybar_output { | ||||||
| class Bar { |   struct wl_output *     output; | ||||||
|   public: |   std::string            name; | ||||||
|     Bar(const Client&, std::unique_ptr<struct wl_output *>&&, uint32_t); |   uint32_t               wl_name; | ||||||
|     Bar(const Bar&) = delete; |   struct zxdg_output_v1 *xdg_output; | ||||||
|     ~Bar() = default; |   Json::Value            config; | ||||||
|  |  | ||||||
|     auto toggle() -> void; |  | ||||||
|     void handleSignal(int); |  | ||||||
|  |  | ||||||
|     const Client& client; |  | ||||||
|     Gtk::Window window; |  | ||||||
|     struct wl_surface *surface; |  | ||||||
|     struct zwlr_layer_surface_v1 *layer_surface; |  | ||||||
|     std::unique_ptr<struct wl_output *> output; |  | ||||||
|     std::string output_name; |  | ||||||
|     uint32_t wl_name; |  | ||||||
|     bool visible = true; |  | ||||||
|     bool vertical = false; |  | ||||||
|   private: |  | ||||||
|     static void handleLogicalPosition(void *, struct zxdg_output_v1 *, int32_t, |  | ||||||
|       int32_t); |  | ||||||
|     static void handleLogicalSize(void *, struct zxdg_output_v1 *, int32_t, |  | ||||||
|       int32_t); |  | ||||||
|     static void handleDone(void *, struct zxdg_output_v1 *); |  | ||||||
|     static void handleName(void *, struct zxdg_output_v1 *, const char *); |  | ||||||
|     static void handleDescription(void *, struct zxdg_output_v1 *, |  | ||||||
|       const char *); |  | ||||||
|     static void layerSurfaceHandleConfigure(void *, |  | ||||||
|       struct zwlr_layer_surface_v1 *, uint32_t, uint32_t, uint32_t); |  | ||||||
|     static void layerSurfaceHandleClosed(void *, |  | ||||||
|       struct zwlr_layer_surface_v1 *); |  | ||||||
|  |  | ||||||
|     void initBar(); |  | ||||||
|     bool isValidOutput(const Json::Value &config); |  | ||||||
|     void destroyOutput(); |  | ||||||
|     auto setupConfig() -> void; |  | ||||||
|     auto setupWidgets() -> void; |  | ||||||
|     auto setupCss() -> void; |  | ||||||
|     void getModules(const Factory&, const std::string&); |  | ||||||
|  |  | ||||||
|     uint32_t width_ = 0; |  | ||||||
|     uint32_t height_ = 30; |  | ||||||
|     Json::Value config_; |  | ||||||
|     Glib::RefPtr<Gtk::StyleContext> style_context_; |  | ||||||
|     Glib::RefPtr<Gtk::CssProvider> css_provider_; |  | ||||||
|     struct zxdg_output_v1 *xdg_output_; |  | ||||||
|     Gtk::Box left_; |  | ||||||
|     Gtk::Box center_; |  | ||||||
|     Gtk::Box right_; |  | ||||||
|     Gtk::Box box_; |  | ||||||
|     std::vector<std::unique_ptr<waybar::IModule>> modules_left_; |  | ||||||
|     std::vector<std::unique_ptr<waybar::IModule>> modules_center_; |  | ||||||
|     std::vector<std::unique_ptr<waybar::IModule>> modules_right_; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | class Bar { | ||||||
|  |  public: | ||||||
|  |   Bar(struct waybar_output *w_output); | ||||||
|  |   Bar(const Bar &) = delete; | ||||||
|  |   ~Bar() = default; | ||||||
|  |  | ||||||
|  |   auto toggle() -> void; | ||||||
|  |   void handleSignal(int); | ||||||
|  |  | ||||||
|  |   struct waybar_output *        output; | ||||||
|  |   Gtk::Window                   window; | ||||||
|  |   struct wl_surface *           surface; | ||||||
|  |   struct zwlr_layer_surface_v1 *layer_surface; | ||||||
|  |   bool                          visible = true; | ||||||
|  |   bool                          vertical = false; | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   static inline const std::string MIN_HEIGHT_MSG = | ||||||
|  |       "Requested height: {} exceeds the minimum height: {} required by the modules"; | ||||||
|  |   static inline const std::string MIN_WIDTH_MSG = | ||||||
|  |       "Requested width: {} exceeds the minimum width: {} required by the modules"; | ||||||
|  |   static inline const std::string BAR_SIZE_MSG = | ||||||
|  |       "Bar configured (width: {}, height: {}) for output: {}"; | ||||||
|  |   static void layerSurfaceHandleConfigure(void *, struct zwlr_layer_surface_v1 *, uint32_t, | ||||||
|  |                                           uint32_t, uint32_t); | ||||||
|  |   static void layerSurfaceHandleClosed(void *, struct zwlr_layer_surface_v1 *); | ||||||
|  |  | ||||||
|  |   void destroyOutput(); | ||||||
|  |   void onWindowRealize(); | ||||||
|  |   auto setupWidgets() -> void; | ||||||
|  |   void getModules(const Factory &, const std::string &); | ||||||
|  |   void setupAltFormatKeyForModule(const std::string &module_name); | ||||||
|  |   void setupAltFormatKeyForModuleList(const char *module_list_name); | ||||||
|  |  | ||||||
|  |   uint32_t                                      width_ = 0; | ||||||
|  |   uint32_t                                      height_ = 30; | ||||||
|  |   Gtk::Box                                      left_; | ||||||
|  |   Gtk::Box                                      center_; | ||||||
|  |   Gtk::Box                                      right_; | ||||||
|  |   Gtk::Box                                      box_; | ||||||
|  |   std::vector<std::unique_ptr<waybar::IModule>> modules_left_; | ||||||
|  |   std::vector<std::unique_ptr<waybar::IModule>> modules_center_; | ||||||
|  |   std::vector<std::unique_ptr<waybar::IModule>> modules_right_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace waybar | ||||||
|   | |||||||
| @@ -1,41 +1,54 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <unistd.h> |  | ||||||
| #include <wordexp.h> |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <gdk/gdk.h> | #include <gdk/gdk.h> | ||||||
| #include <wayland-client.h> |  | ||||||
| #include <gdk/gdkwayland.h> | #include <gdk/gdkwayland.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <wayland-client.h> | ||||||
|  | #include <wordexp.h> | ||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
|  |  | ||||||
| namespace waybar { | namespace waybar { | ||||||
|  |  | ||||||
| class Client { | class Client { | ||||||
|   public: |  public: | ||||||
|     Client(int argc, char *argv[]); |   static Client *inst(); | ||||||
|     int main(int argc, char *argv[]); |   int            main(int argc, char *argv[]); | ||||||
|  |  | ||||||
|     Glib::RefPtr<Gtk::Application> gtk_app; |   Glib::RefPtr<Gtk::Application>      gtk_app; | ||||||
|     std::string css_file; |   Glib::RefPtr<Gdk::Display>          gdk_display; | ||||||
|     std::string config_file; |   struct wl_display *                 wl_display = nullptr; | ||||||
|     Glib::RefPtr<Gdk::Display> gdk_display; |   struct wl_registry *                registry = nullptr; | ||||||
|     struct wl_display *wl_display = nullptr; |   struct zwlr_layer_shell_v1 *        layer_shell = nullptr; | ||||||
|     struct wl_registry *registry = nullptr; |   struct zxdg_output_manager_v1 *     xdg_output_manager = nullptr; | ||||||
|     struct zwlr_layer_shell_v1 *layer_shell = nullptr; |   struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = nullptr; | ||||||
|     struct zxdg_output_manager_v1 *xdg_output_manager = nullptr; |   std::vector<std::unique_ptr<Bar>>   bars; | ||||||
|     struct wl_seat *seat = nullptr; |  | ||||||
|     struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = nullptr; |  | ||||||
|     std::vector<std::unique_ptr<Bar>> bars; |  | ||||||
|  |  | ||||||
|   private: |  private: | ||||||
|     void setupConfigs(const std::string& config, const std::string& style); |   Client(); | ||||||
|     void bindInterfaces(); |   void              setupConfigs(const std::string &config, const std::string &style); | ||||||
|     const std::string getValidPath(std::vector<std::string> paths); |   void              bindInterfaces(); | ||||||
|  |   const std::string getValidPath(std::vector<std::string> paths); | ||||||
|  |   void              handleOutput(std::unique_ptr<struct waybar_output> &output); | ||||||
|  |   bool isValidOutput(const Json::Value &config, std::unique_ptr<struct waybar_output> &output); | ||||||
|  |   auto setupConfig() -> void; | ||||||
|  |   auto setupCss() -> void; | ||||||
|  |  | ||||||
|     static void handleGlobal(void *data, struct wl_registry *registry, |   static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name, | ||||||
|       uint32_t name, const char *interface, uint32_t version); |                            const char *interface, uint32_t version); | ||||||
|     static void handleGlobalRemove(void *data, |   static void handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name); | ||||||
|       struct wl_registry *registry, uint32_t name); |   static void handleLogicalPosition(void *, struct zxdg_output_v1 *, int32_t, int32_t); | ||||||
|  |   static void handleLogicalSize(void *, struct zxdg_output_v1 *, int32_t, int32_t); | ||||||
|  |   static void handleDone(void *, struct zxdg_output_v1 *); | ||||||
|  |   static void handleName(void *, struct zxdg_output_v1 *, const char *); | ||||||
|  |   static void handleDescription(void *, struct zxdg_output_v1 *, const char *); | ||||||
|  |  | ||||||
|  |   Json::Value                                        config_; | ||||||
|  |   std::string                                        css_file_; | ||||||
|  |   std::string                                        config_file_; | ||||||
|  |   Glib::RefPtr<Gtk::StyleContext>                    style_context_; | ||||||
|  |   Glib::RefPtr<Gtk::CssProvider>                     css_provider_; | ||||||
|  |   std::vector<std::unique_ptr<struct waybar_output>> outputs_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar | ||||||
|   | |||||||
| @@ -4,13 +4,13 @@ | |||||||
| #include "modules/clock.hpp" | #include "modules/clock.hpp" | ||||||
| #ifdef HAVE_SWAY | #ifdef HAVE_SWAY | ||||||
| #include "modules/sway/mode.hpp" | #include "modules/sway/mode.hpp" | ||||||
| #include "modules/sway/workspaces.hpp" |  | ||||||
| #include "modules/sway/window.hpp" | #include "modules/sway/window.hpp" | ||||||
|  | #include "modules/sway/workspaces.hpp" | ||||||
| #endif | #endif | ||||||
| #include "modules/idle_inhibitor.hpp" |  | ||||||
| #include "modules/battery.hpp" | #include "modules/battery.hpp" | ||||||
| #include "modules/memory.hpp" |  | ||||||
| #include "modules/cpu.hpp" | #include "modules/cpu.hpp" | ||||||
|  | #include "modules/idle_inhibitor.hpp" | ||||||
|  | #include "modules/memory.hpp" | ||||||
| #ifdef HAVE_DBUSMENU | #ifdef HAVE_DBUSMENU | ||||||
| #include "modules/sni/tray.hpp" | #include "modules/sni/tray.hpp" | ||||||
| #endif | #endif | ||||||
| @@ -26,20 +26,20 @@ | |||||||
| #ifdef HAVE_LIBMPDCLIENT | #ifdef HAVE_LIBMPDCLIENT | ||||||
| #include "modules/mpd.hpp" | #include "modules/mpd.hpp" | ||||||
| #endif | #endif | ||||||
| #include "modules/temperature.hpp" | #include "bar.hpp" | ||||||
| #include "modules/custom.hpp" | #include "modules/custom.hpp" | ||||||
|  | #include "modules/temperature.hpp" | ||||||
|  |  | ||||||
| namespace waybar { | namespace waybar { | ||||||
|  |  | ||||||
| class Bar; |  | ||||||
|  |  | ||||||
| class Factory { | class Factory { | ||||||
|   public: |  public: | ||||||
|     Factory(const Bar& bar, const Json::Value& config); |   Factory(const Bar& bar, const Json::Value& config); | ||||||
|     IModule* makeModule(const std::string &name) const; |   IModule* makeModule(const std::string& name) const; | ||||||
|   private: |  | ||||||
|     const Bar& bar_; |  private: | ||||||
|     const Json::Value& config_; |   const Bar&         bar_; | ||||||
|  |   const Json::Value& config_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar | ||||||
|   | |||||||
| @@ -16,52 +16,47 @@ namespace waybar::modules { | |||||||
|  |  | ||||||
| class Backlight : public ALabel { | class Backlight : public ALabel { | ||||||
|   class BacklightDev { |   class BacklightDev { | ||||||
|   public: |    public: | ||||||
|     BacklightDev() = default; |     BacklightDev() = default; | ||||||
|     BacklightDev(std::string name, int actual, int max); |     BacklightDev(std::string name, int actual, int max); | ||||||
|     std::string_view name() const; |     std::string_view   name() const; | ||||||
|     int get_actual() const; |     int                get_actual() const; | ||||||
|     void set_actual(int actual); |     void               set_actual(int actual); | ||||||
|     int get_max() const; |     int                get_max() const; | ||||||
|     void set_max(int max); |     void               set_max(int max); | ||||||
|     friend inline bool operator==(const BacklightDev &lhs, |     friend inline bool operator==(const BacklightDev &lhs, const BacklightDev &rhs) { | ||||||
|                                   const BacklightDev &rhs) { |       return lhs.name_ == rhs.name_ && lhs.actual_ == rhs.actual_ && lhs.max_ == rhs.max_; | ||||||
|       return lhs.name_ == rhs.name_ && lhs.actual_ == rhs.actual_ && |  | ||||||
|              lhs.max_ == rhs.max_; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   private: |    private: | ||||||
|     std::string name_; |     std::string name_; | ||||||
|     int actual_ = 1; |     int         actual_ = 1; | ||||||
|     int max_ = 1; |     int         max_ = 1; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| public: |  public: | ||||||
|   Backlight(const std::string &, const Json::Value &); |   Backlight(const std::string &, const Json::Value &); | ||||||
|   ~Backlight(); |   ~Backlight(); | ||||||
|   auto update() -> void; |   auto update() -> void; | ||||||
|  |  | ||||||
| private: |  private: | ||||||
|   template <class ForwardIt> |   template <class ForwardIt> | ||||||
|   static const BacklightDev *best_device(ForwardIt first, ForwardIt last, |   static const BacklightDev *best_device(ForwardIt first, ForwardIt last, std::string_view); | ||||||
|                                          std::string_view); |  | ||||||
|   template <class ForwardIt, class Inserter> |   template <class ForwardIt, class Inserter> | ||||||
|   static void upsert_device(ForwardIt first, ForwardIt last, Inserter inserter, |   static void upsert_device(ForwardIt first, ForwardIt last, Inserter inserter, udev_device *dev); | ||||||
|                             udev_device *dev); |  | ||||||
|   template <class ForwardIt, class Inserter> |   template <class ForwardIt, class Inserter> | ||||||
|   static void enumerate_devices(ForwardIt first, ForwardIt last, |   static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev); | ||||||
|                                 Inserter inserter, udev *udev); |  | ||||||
|  |  | ||||||
|   const std::string name_; |   const std::string    name_; | ||||||
|   const std::string preferred_device_; |   const std::string    preferred_device_; | ||||||
|   static constexpr int EPOLL_MAX_EVENTS = 16; |   static constexpr int EPOLL_MAX_EVENTS = 16; | ||||||
|  |  | ||||||
|   std::optional<BacklightDev> previous_best_; |   std::optional<BacklightDev> previous_best_; | ||||||
|   std::string previous_format_; |   std::string                 previous_format_; | ||||||
|  |  | ||||||
|   std::mutex udev_thread_mutex_; |   std::mutex                udev_thread_mutex_; | ||||||
|   std::vector<BacklightDev> devices_; |   std::vector<BacklightDev> devices_; | ||||||
|   // thread must destruct before shared data |   // thread must destruct before shared data | ||||||
|   waybar::util::SleeperThread udev_thread_; |   waybar::util::SleeperThread udev_thread_; | ||||||
| }; | }; | ||||||
| } // namespace waybar::modules | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -5,13 +5,13 @@ | |||||||
| #else | #else | ||||||
| #include <filesystem> | #include <filesystem> | ||||||
| #endif | #endif | ||||||
| #include <fstream> |  | ||||||
| #include <iostream> |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <sys/inotify.h> | #include <sys/inotify.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include "util/sleeper_thread.hpp" | #include <fstream> | ||||||
|  | #include <iostream> | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  | #include "util/sleeper_thread.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| @@ -22,26 +22,27 @@ namespace fs = std::filesystem; | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| class Battery : public ALabel { | class Battery : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Battery(const std::string&, const Json::Value&); |   Battery(const std::string&, const Json::Value&); | ||||||
|     ~Battery(); |   ~Battery(); | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     static inline const fs::path data_dir_ = "/sys/class/power_supply/"; |  | ||||||
|  |  | ||||||
|     void getBatteries(); |  private: | ||||||
|     void worker(); |   static inline const fs::path data_dir_ = "/sys/class/power_supply/"; | ||||||
|     const std::string getAdapterStatus(uint8_t capacity) const; |  | ||||||
|     const std::tuple<uint8_t, std::string> getInfos() const; |  | ||||||
|     const std::string getState(uint8_t) const; |  | ||||||
|  |  | ||||||
|     util::SleeperThread thread_; |   void                                   getBatteries(); | ||||||
|     util::SleeperThread thread_timer_; |   void                                   worker(); | ||||||
|     std::vector<fs::path> batteries_; |   const std::string                      getAdapterStatus(uint8_t capacity) const; | ||||||
|     fs::path adapter_; |   const std::tuple<uint8_t, std::string> getInfos() const; | ||||||
|     int fd_; |   const std::string                      getState(uint8_t) const; | ||||||
|     std::vector<int> wds_; |  | ||||||
|     std::string old_status_; |   util::SleeperThread   thread_; | ||||||
|  |   util::SleeperThread   thread_timer_; | ||||||
|  |   std::vector<fs::path> batteries_; | ||||||
|  |   fs::path              adapter_; | ||||||
|  |   int                   fd_; | ||||||
|  |   std::vector<int>      wds_; | ||||||
|  |   std::string           old_status_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -1,19 +1,20 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
|  | #include "ALabel.hpp" | ||||||
| #include "fmt/time.h" | #include "fmt/time.h" | ||||||
| #include "util/sleeper_thread.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "ALabel.hpp" |  | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| class Clock : public ALabel { | class Clock : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Clock(const std::string&, const Json::Value&); |   Clock(const std::string&, const Json::Value&); | ||||||
|     ~Clock() = default; |   ~Clock() = default; | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     waybar::util::SleeperThread thread_; |  private: | ||||||
|  |   waybar::util::SleeperThread thread_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -3,27 +3,28 @@ | |||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <sys/sysinfo.h> | #include <sys/sysinfo.h> | ||||||
| #include <fstream> | #include <fstream> | ||||||
| #include <vector> |  | ||||||
| #include <numeric> |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include "util/sleeper_thread.hpp" | #include <numeric> | ||||||
|  | #include <vector> | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  | #include "util/sleeper_thread.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| class Cpu : public ALabel { | class Cpu : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Cpu(const std::string&, const Json::Value&); |   Cpu(const std::string&, const Json::Value&); | ||||||
|     ~Cpu() = default; |   ~Cpu() = default; | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     static inline const std::string data_dir_ = "/proc/stat"; |  | ||||||
|     uint16_t getCpuLoad(); |  | ||||||
|     std::tuple<uint16_t, std::string> getCpuUsage(); |  | ||||||
|     std::vector<std::tuple<size_t, size_t>> parseCpuinfo(); |  | ||||||
|  |  | ||||||
|     std::vector<std::tuple<size_t, size_t>> prev_times_; |  private: | ||||||
|     waybar::util::SleeperThread thread_; |   static inline const std::string         data_dir_ = "/proc/stat"; | ||||||
|  |   uint16_t                                getCpuLoad(); | ||||||
|  |   std::tuple<uint16_t, std::string>       getCpuUsage(); | ||||||
|  |   std::vector<std::tuple<size_t, size_t>> parseCpuinfo(); | ||||||
|  |  | ||||||
|  |   std::vector<std::tuple<size_t, size_t>> prev_times_; | ||||||
|  |   waybar::util::SleeperThread             thread_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -1,37 +1,38 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <iostream> |  | ||||||
| #include <csignal> | #include <csignal> | ||||||
| #include "util/sleeper_thread.hpp" | #include <iostream> | ||||||
|  | #include "ALabel.hpp" | ||||||
| #include "util/command.hpp" | #include "util/command.hpp" | ||||||
| #include "util/json.hpp" | #include "util/json.hpp" | ||||||
| #include "ALabel.hpp" | #include "util/sleeper_thread.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| class Custom : public ALabel { | class Custom : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Custom(const std::string&, const Json::Value&); |   Custom(const std::string&, const Json::Value&); | ||||||
|     ~Custom(); |   ~Custom(); | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|     void refresh(int /*signal*/); |   void refresh(int /*signal*/); | ||||||
|   private: |  | ||||||
|     void delayWorker(); |  | ||||||
|     void continuousWorker(); |  | ||||||
|     void parseOutputRaw(); |  | ||||||
|     void parseOutputJson(); |  | ||||||
|  |  | ||||||
|     const std::string name_; |  private: | ||||||
|     std::string text_; |   void delayWorker(); | ||||||
|     std::string alt_; |   void continuousWorker(); | ||||||
|     std::string tooltip_; |   void parseOutputRaw(); | ||||||
|     std::vector<std::string> class_; |   void parseOutputJson(); | ||||||
|     int percentage_; |  | ||||||
|     waybar::util::SleeperThread thread_; |   const std::string           name_; | ||||||
|     waybar::util::command::res output_; |   std::string                 text_; | ||||||
|     waybar::util::JsonParser parser_; |   std::string                 alt_; | ||||||
|     FILE* fp_; |   std::string                 tooltip_; | ||||||
|  |   std::vector<std::string>    class_; | ||||||
|  |   int                         percentage_; | ||||||
|  |   waybar::util::SleeperThread thread_; | ||||||
|  |   waybar::util::command::res  output_; | ||||||
|  |   waybar::util::JsonParser    parser_; | ||||||
|  |   FILE*                       fp_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -1,23 +1,24 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
|  | #include "ALabel.hpp" | ||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
| #include "ALabel.hpp" |  | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| class IdleInhibitor: public ALabel { | class IdleInhibitor : public ALabel { | ||||||
|   public: |  public: | ||||||
|     IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&); |   IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&); | ||||||
|     ~IdleInhibitor(); |   ~IdleInhibitor(); | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     bool handleToggle(GdkEventButton* const& e); |  | ||||||
|  |  | ||||||
|     const Bar& bar_; |  private: | ||||||
|     std::string status_; |   bool handleToggle(GdkEventButton* const& e); | ||||||
|     struct zwp_idle_inhibitor_v1 *idle_inhibitor_; |  | ||||||
|  |   const Bar&                    bar_; | ||||||
|  |   std::string                   status_; | ||||||
|  |   struct zwp_idle_inhibitor_v1* idle_inhibitor_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -2,22 +2,23 @@ | |||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <fstream> | #include <fstream> | ||||||
| #include "util/sleeper_thread.hpp" |  | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  | #include "util/sleeper_thread.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| class Memory : public ALabel { | class Memory : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Memory(const std::string&, const Json::Value&); |   Memory(const std::string&, const Json::Value&); | ||||||
|     ~Memory() = default; |   ~Memory() = default; | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     static inline const std::string data_dir_ = "/proc/meminfo"; |  private: | ||||||
|     unsigned long memtotal_; |   static inline const std::string data_dir_ = "/proc/meminfo"; | ||||||
|     unsigned long memfree_; |   unsigned long                   memtotal_; | ||||||
|     void parseMeminfo(); |   unsigned long                   memfree_; | ||||||
|     waybar::util::SleeperThread thread_; |   void                            parseMeminfo(); | ||||||
|  |   waybar::util::SleeperThread     thread_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -1,62 +1,63 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <net/if.h> |  | ||||||
| #include <arpa/inet.h> | #include <arpa/inet.h> | ||||||
| #include <ifaddrs.h> |  | ||||||
| #include <netlink/netlink.h> |  | ||||||
| #include <netlink/genl/genl.h> |  | ||||||
| #include <netlink/genl/ctrl.h> |  | ||||||
| #include <linux/nl80211.h> |  | ||||||
| #include <sys/epoll.h> |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "util/sleeper_thread.hpp" | #include <ifaddrs.h> | ||||||
|  | #include <linux/nl80211.h> | ||||||
|  | #include <net/if.h> | ||||||
|  | #include <netlink/genl/ctrl.h> | ||||||
|  | #include <netlink/genl/genl.h> | ||||||
|  | #include <netlink/netlink.h> | ||||||
|  | #include <sys/epoll.h> | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  | #include "util/sleeper_thread.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| class Network : public ALabel { | class Network : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Network(const std::string&, const Json::Value&); |   Network(const std::string&, const Json::Value&); | ||||||
|     ~Network(); |   ~Network(); | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     static const uint8_t MAX_RETRY = 5; |  | ||||||
|     static const uint8_t EPOLL_MAX = 255; |  | ||||||
|  |  | ||||||
|     static int handleEvents(struct nl_msg*, void*); |  private: | ||||||
|     static int handleScan(struct nl_msg*, void*); |   static const uint8_t MAX_RETRY = 5; | ||||||
|  |   static const uint8_t EPOLL_MAX = 200; | ||||||
|  |  | ||||||
|     void worker(); |   static int handleEvents(struct nl_msg*, void*); | ||||||
|     void disconnected(); |   static int handleScan(struct nl_msg*, void*); | ||||||
|     void createInfoSocket(); |  | ||||||
|     void createEventSocket(); |  | ||||||
|     int getExternalInterface(); |  | ||||||
|     void getInterfaceAddress(); |  | ||||||
|     int netlinkRequest(void*, uint32_t, uint32_t groups = 0); |  | ||||||
|     int netlinkResponse(void*, uint32_t, uint32_t groups = 0); |  | ||||||
|     void parseEssid(struct nlattr**); |  | ||||||
|     void parseSignal(struct nlattr**); |  | ||||||
|     bool associatedOrJoined(struct nlattr**); |  | ||||||
|     auto getInfo() -> void; |  | ||||||
|  |  | ||||||
|     waybar::util::SleeperThread thread_; |   void worker(); | ||||||
|     waybar::util::SleeperThread thread_timer_; |   void disconnected(); | ||||||
|     int ifid_; |   void createInfoSocket(); | ||||||
|     sa_family_t family_; |   void createEventSocket(); | ||||||
|     struct sockaddr_nl nladdr_ = {0}; |   int  getExternalInterface(); | ||||||
|     struct nl_sock* sk_ = nullptr; |   void getInterfaceAddress(); | ||||||
|     struct nl_sock* info_sock_ = nullptr; |   int  netlinkRequest(void*, uint32_t, uint32_t groups = 0); | ||||||
|     int efd_; |   int  netlinkResponse(void*, uint32_t, uint32_t groups = 0); | ||||||
|     int ev_fd_; |   void parseEssid(struct nlattr**); | ||||||
|     int nl80211_id_; |   void parseSignal(struct nlattr**); | ||||||
|  |   bool associatedOrJoined(struct nlattr**); | ||||||
|  |   auto getInfo() -> void; | ||||||
|  |  | ||||||
|     std::string essid_; |   waybar::util::SleeperThread thread_; | ||||||
|     std::string ifname_; |   waybar::util::SleeperThread thread_timer_; | ||||||
|     std::string ipaddr_; |   int                         ifid_; | ||||||
|     std::string netmask_; |   sa_family_t                 family_; | ||||||
|     int cidr_; |   struct sockaddr_nl          nladdr_ = {0}; | ||||||
|     int32_t signal_strength_dbm_; |   struct nl_sock*             sk_ = nullptr; | ||||||
|     uint8_t signal_strength_; |   struct nl_sock*             info_sock_ = nullptr; | ||||||
|  |   int                         efd_; | ||||||
|  |   int                         ev_fd_; | ||||||
|  |   int                         nl80211_id_; | ||||||
|  |  | ||||||
|  |   std::string essid_; | ||||||
|  |   std::string ifname_; | ||||||
|  |   std::string ipaddr_; | ||||||
|  |   std::string netmask_; | ||||||
|  |   int         cidr_; | ||||||
|  |   int32_t     signal_strength_dbm_; | ||||||
|  |   uint8_t     signal_strength_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -9,31 +9,31 @@ | |||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| class Pulseaudio : public ALabel { | class Pulseaudio : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Pulseaudio(const std::string&, const Json::Value&); |   Pulseaudio(const std::string&, const Json::Value&); | ||||||
|     ~Pulseaudio(); |   ~Pulseaudio(); | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     static void subscribeCb(pa_context*, pa_subscription_event_type_t, |  | ||||||
|       uint32_t, void*); |  | ||||||
|     static void contextStateCb(pa_context*, void*); |  | ||||||
|     static void sinkInfoCb(pa_context*, const pa_sink_info*, int, void*); |  | ||||||
|     static void serverInfoCb(pa_context*, const pa_server_info*, void*); |  | ||||||
|     static void volumeModifyCb(pa_context*, int, void*); |  | ||||||
|     bool handleScroll(GdkEventScroll* e); |  | ||||||
|  |  | ||||||
|     const std::string getPortIcon() const; |  private: | ||||||
|  |   static void subscribeCb(pa_context*, pa_subscription_event_type_t, uint32_t, void*); | ||||||
|  |   static void contextStateCb(pa_context*, void*); | ||||||
|  |   static void sinkInfoCb(pa_context*, const pa_sink_info*, int, void*); | ||||||
|  |   static void serverInfoCb(pa_context*, const pa_server_info*, void*); | ||||||
|  |   static void volumeModifyCb(pa_context*, int, void*); | ||||||
|  |   bool        handleScroll(GdkEventScroll* e); | ||||||
|  |  | ||||||
|     pa_threaded_mainloop* mainloop_; |   const std::string getPortIcon() const; | ||||||
|     pa_mainloop_api* mainloop_api_; |  | ||||||
|     pa_context* context_; |   pa_threaded_mainloop* mainloop_; | ||||||
|     uint32_t sink_idx_{0}; |   pa_mainloop_api*      mainloop_api_; | ||||||
|     uint16_t volume_; |   pa_context*           context_; | ||||||
|     pa_cvolume pa_volume_; |   uint32_t              sink_idx_{0}; | ||||||
|     bool muted_; |   uint16_t              volume_; | ||||||
|     std::string port_name_; |   pa_cvolume            pa_volume_; | ||||||
|     std::string desc_; |   bool                  muted_; | ||||||
|     bool scrolling_; |   std::string           port_name_; | ||||||
|  |   std::string           desc_; | ||||||
|  |   bool                  scrolling_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace waybar::modules | }  // namespace waybar::modules | ||||||
|   | |||||||
| @@ -16,26 +16,26 @@ class Host { | |||||||
|   ~Host(); |   ~Host(); | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   void busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring); |   void        busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring); | ||||||
|   void nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring, |   void        nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring, | ||||||
|                     const Glib::ustring&); |                            const Glib::ustring&); | ||||||
|   void nameVanished(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring); |   void        nameVanished(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring); | ||||||
|   static void proxyReady(GObject*, GAsyncResult*, gpointer); |   static void proxyReady(GObject*, GAsyncResult*, gpointer); | ||||||
|   static void registerHost(GObject*, GAsyncResult*, gpointer); |   static void registerHost(GObject*, GAsyncResult*, gpointer); | ||||||
|   static void itemRegistered(SnWatcher*, const gchar*, gpointer); |   static void itemRegistered(SnWatcher*, const gchar*, gpointer); | ||||||
|   static void itemUnregistered(SnWatcher*, const gchar*, gpointer); |   static void itemUnregistered(SnWatcher*, const gchar*, gpointer); | ||||||
|  |  | ||||||
|   std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string); |   std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string); | ||||||
|   void addRegisteredItem(std::string service); |   void                                 addRegisteredItem(std::string service); | ||||||
|  |  | ||||||
|   std::vector<std::unique_ptr<Item>> items_; |   std::vector<std::unique_ptr<Item>>                items_; | ||||||
|   const std::string bus_name_; |   const std::string                                 bus_name_; | ||||||
|   const std::string object_path_; |   const std::string                                 object_path_; | ||||||
|   std::size_t bus_name_id_; |   std::size_t                                       bus_name_id_; | ||||||
|   std::size_t watcher_id_; |   std::size_t                                       watcher_id_; | ||||||
|   GCancellable* cancellable_ = nullptr; |   GCancellable*                                     cancellable_ = nullptr; | ||||||
|   SnWatcher* watcher_ = nullptr; |   SnWatcher*                                        watcher_ = nullptr; | ||||||
|   const Json::Value& config_; |   const Json::Value&                                config_; | ||||||
|   const std::function<void(std::unique_ptr<Item>&)> on_add_; |   const std::function<void(std::unique_ptr<Item>&)> on_add_; | ||||||
|   const std::function<void(std::unique_ptr<Item>&)> on_remove_; |   const std::function<void(std::unique_ptr<Item>&)> on_remove_; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -26,27 +26,27 @@ class Item : public sigc::trackable { | |||||||
|   std::string bus_name; |   std::string bus_name; | ||||||
|   std::string object_path; |   std::string object_path; | ||||||
|  |  | ||||||
|   int icon_size; |   int           icon_size; | ||||||
|   int effective_icon_size; |   int           effective_icon_size; | ||||||
|   Gtk::Image image; |   Gtk::Image    image; | ||||||
|   Gtk::EventBox event_box; |   Gtk::EventBox event_box; | ||||||
|   std::string category; |   std::string   category; | ||||||
|   std::string id; |   std::string   id; | ||||||
|   std::string status; |   std::string   status; | ||||||
|  |  | ||||||
|   std::string title; |   std::string                  title; | ||||||
|   int32_t window_id; |   int32_t                      window_id; | ||||||
|   std::string icon_name; |   std::string                  icon_name; | ||||||
|   Glib::RefPtr<Gdk::Pixbuf> icon_pixmap; |   Glib::RefPtr<Gdk::Pixbuf>    icon_pixmap; | ||||||
|   Glib::RefPtr<Gtk::IconTheme> icon_theme; |   Glib::RefPtr<Gtk::IconTheme> icon_theme; | ||||||
|   std::string overlay_icon_name; |   std::string                  overlay_icon_name; | ||||||
|   std::string attention_icon_name; |   std::string                  attention_icon_name; | ||||||
|   std::string attention_movie_name; |   std::string                  attention_movie_name; | ||||||
|   std::string icon_theme_path; |   std::string                  icon_theme_path; | ||||||
|   std::string menu; |   std::string                  menu; | ||||||
|   DbusmenuGtkMenu* dbus_menu = nullptr; |   DbusmenuGtkMenu*             dbus_menu = nullptr; | ||||||
|   Gtk::Menu* gtk_menu = nullptr; |   Gtk::Menu*                   gtk_menu = nullptr; | ||||||
|   bool item_is_menu; |   bool                         item_is_menu; | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result); |   void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result); | ||||||
| @@ -56,16 +56,16 @@ class Item : public sigc::trackable { | |||||||
|   void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name, |   void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name, | ||||||
|                 const Glib::VariantContainerBase& arguments); |                 const Glib::VariantContainerBase& arguments); | ||||||
|  |  | ||||||
|   void updateImage(); |   void                      updateImage(); | ||||||
|   Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant); |   Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant); | ||||||
|   Glib::RefPtr<Gdk::Pixbuf> getIconByName(std::string name, int size); |   Glib::RefPtr<Gdk::Pixbuf> getIconByName(std::string name, int size); | ||||||
|   static void onMenuDestroyed(Item* self); |   static void               onMenuDestroyed(Item* self); | ||||||
|   bool makeMenu(GdkEventButton* const& ev); |   bool                      makeMenu(GdkEventButton* const& ev); | ||||||
|   bool handleClick(GdkEventButton* const& /*ev*/); |   bool                      handleClick(GdkEventButton* const& /*ev*/); | ||||||
|  |  | ||||||
|   Glib::RefPtr<Gio::Cancellable> cancellable_; |   Glib::RefPtr<Gio::Cancellable> cancellable_; | ||||||
|   Glib::RefPtr<Gio::DBus::Proxy> proxy_; |   Glib::RefPtr<Gio::DBus::Proxy> proxy_; | ||||||
|   bool update_pending_; |   bool                           update_pending_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace waybar::modules::SNI | }  // namespace waybar::modules::SNI | ||||||
|   | |||||||
| @@ -14,17 +14,17 @@ class Tray : public IModule { | |||||||
|   Tray(const std::string&, const Bar&, const Json::Value&); |   Tray(const std::string&, const Bar&, const Json::Value&); | ||||||
|   ~Tray() = default; |   ~Tray() = default; | ||||||
|   auto update() -> void; |   auto update() -> void; | ||||||
|   operator Gtk::Widget&(); |        operator Gtk::Widget&(); | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   void onAdd(std::unique_ptr<Item>& item); |   void onAdd(std::unique_ptr<Item>& item); | ||||||
|   void onRemove(std::unique_ptr<Item>& item); |   void onRemove(std::unique_ptr<Item>& item); | ||||||
|  |  | ||||||
|   static inline std::size_t nb_hosts_ = 0; |   static inline std::size_t nb_hosts_ = 0; | ||||||
|   const Json::Value& config_; |   const Json::Value&        config_; | ||||||
|   Gtk::Box box_; |   Gtk::Box                  box_; | ||||||
|   SNI::Watcher watcher_; |   SNI::Watcher              watcher_; | ||||||
|   SNI::Host host_; |   SNI::Host                 host_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace waybar::modules::SNI | }  // namespace waybar::modules::SNI | ||||||
|   | |||||||
| @@ -16,30 +16,28 @@ class Watcher { | |||||||
|  |  | ||||||
|   typedef struct { |   typedef struct { | ||||||
|     GfWatchType type; |     GfWatchType type; | ||||||
|     Watcher *watcher; |     Watcher *   watcher; | ||||||
|     gchar *service; |     gchar *     service; | ||||||
|     gchar *bus_name; |     gchar *     bus_name; | ||||||
|     gchar *object_path; |     gchar *     object_path; | ||||||
|     guint watch_id; |     guint       watch_id; | ||||||
|   } GfWatch; |   } GfWatch; | ||||||
|  |  | ||||||
|   void busAcquired(const Glib::RefPtr<Gio::DBus::Connection> &, Glib::ustring); |   void            busAcquired(const Glib::RefPtr<Gio::DBus::Connection> &, Glib::ustring); | ||||||
|   static gboolean handleRegisterHost(Watcher *, GDBusMethodInvocation *, const gchar *); |   static gboolean handleRegisterHost(Watcher *, GDBusMethodInvocation *, const gchar *); | ||||||
|   static gboolean handleRegisterItem(Watcher *, GDBusMethodInvocation *, const gchar *); |   static gboolean handleRegisterItem(Watcher *, GDBusMethodInvocation *, const gchar *); | ||||||
|   static GfWatch *gfWatchFind(GSList *list, const gchar *bus_name, const gchar *object_path); |   static GfWatch *gfWatchFind(GSList *list, const gchar *bus_name, const gchar *object_path); | ||||||
|   static GfWatch *gfWatchNew(GfWatchType, const gchar *, const gchar *, const gchar *, Watcher *); |   static GfWatch *gfWatchNew(GfWatchType, const gchar *, const gchar *, const gchar *, Watcher *); | ||||||
|   static void nameVanished(GDBusConnection *connection, const char *name, gpointer data); |   static void     nameVanished(GDBusConnection *connection, const char *name, gpointer data); | ||||||
|   static void gfWatchFree(gpointer data); |   static void     gfWatchFree(gpointer data); | ||||||
|  |  | ||||||
|   void updateRegisteredItems(SnWatcher *obj); |   void updateRegisteredItems(SnWatcher *obj); | ||||||
|  |  | ||||||
|   uint32_t bus_name_id_; |   uint32_t   bus_name_id_; | ||||||
|   uint32_t watcher_id_; |   uint32_t   watcher_id_; | ||||||
|   GSList *hosts_ = nullptr; |   GSList *   hosts_ = nullptr; | ||||||
|   GSList *items_ = nullptr; |   GSList *   items_ = nullptr; | ||||||
|   SnWatcher *watcher_ = nullptr; |   SnWatcher *watcher_ = nullptr; | ||||||
|   gulong handler_item_id_; |  | ||||||
|   gulong handler_host_id_; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace waybar::modules::SNI | }  // namespace waybar::modules::SNI | ||||||
|   | |||||||
| @@ -1,40 +1,47 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <iostream> | #include <sigc++/sigc++.h> | ||||||
| #include <cstring> |  | ||||||
| #include <unistd.h> |  | ||||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||||
| #include <sys/un.h> | #include <sys/un.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <cstring> | ||||||
|  | #include <iostream> | ||||||
|  | #include <mutex> | ||||||
| #include "ipc.hpp" | #include "ipc.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules::sway { | namespace waybar::modules::sway { | ||||||
|  |  | ||||||
| class Ipc { | class Ipc { | ||||||
| public: |  public: | ||||||
|   Ipc(); |   Ipc(); | ||||||
|   ~Ipc(); |   ~Ipc(); | ||||||
|  |  | ||||||
|   struct ipc_response { |   struct ipc_response { | ||||||
|     uint32_t size; |     uint32_t    size; | ||||||
|     uint32_t type; |     uint32_t    type; | ||||||
|     std::string payload; |     std::string payload; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   struct ipc_response sendCmd(uint32_t type, const std::string &payload = "") const; |   sigc::signal<void, const struct ipc_response> signal_event; | ||||||
|   void subscribe(const std::string &payload) const; |   sigc::signal<void, const struct ipc_response> signal_cmd; | ||||||
|   struct ipc_response handleEvent() const; |  | ||||||
|  |  | ||||||
| protected: |   void sendCmd(uint32_t type, const std::string &payload = ""); | ||||||
|  |   void subscribe(const std::string &payload); | ||||||
|  |   void handleEvent(); | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|   static inline const std::string ipc_magic_ = "i3-ipc"; |   static inline const std::string ipc_magic_ = "i3-ipc"; | ||||||
|   static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8; |   static inline const size_t      ipc_header_size_ = ipc_magic_.size() + 8; | ||||||
|  |  | ||||||
|   const std::string getSocketPath() const; |   const std::string   getSocketPath() const; | ||||||
|   int open(const std::string &) const; |   int                 open(const std::string &) const; | ||||||
|   struct ipc_response send(int fd, uint32_t type, const std::string &payload = "") const; |   struct ipc_response send(int fd, uint32_t type, const std::string &payload = ""); | ||||||
|   struct ipc_response recv(int fd) const; |   struct ipc_response recv(int fd); | ||||||
|  |  | ||||||
|   int fd_; |   int        fd_; | ||||||
|   int fd_event_; |   int        fd_event_; | ||||||
|  |   std::mutex mutex_; | ||||||
|  |   std::mutex mutex_event_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace waybar::modules::sway | }  // namespace waybar::modules::sway | ||||||
|   | |||||||
| @@ -1,28 +1,30 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
|  | #include "ALabel.hpp" | ||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
| #include "util/sleeper_thread.hpp" |  | ||||||
| #include "util/json.hpp" |  | ||||||
| #include "ALabel.hpp" |  | ||||||
| #include "modules/sway/ipc/client.hpp" | #include "modules/sway/ipc/client.hpp" | ||||||
|  | #include "util/json.hpp" | ||||||
|  | #include "util/sleeper_thread.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules::sway { | namespace waybar::modules::sway { | ||||||
|  |  | ||||||
| class Mode : public ALabel { | class Mode : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Mode(const std::string&, const waybar::Bar&, const Json::Value&); |   Mode(const std::string&, const waybar::Bar&, const Json::Value&); | ||||||
|     ~Mode() = default; |   ~Mode() = default; | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     void worker(); |  private: | ||||||
|      |   void onEvent(const struct Ipc::ipc_response); | ||||||
|     const Bar& bar_; |   void worker(); | ||||||
|     waybar::util::SleeperThread thread_; |  | ||||||
|     util::JsonParser parser_; |   const Bar&                  bar_; | ||||||
|     Ipc ipc_; |   waybar::util::SleeperThread thread_; | ||||||
|     std::string mode_; |   util::JsonParser            parser_; | ||||||
|  |   Ipc                         ipc_; | ||||||
|  |   std::string                 mode_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules::sway | ||||||
| @@ -2,31 +2,34 @@ | |||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <tuple> | #include <tuple> | ||||||
|  | #include "ALabel.hpp" | ||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
| #include "util/sleeper_thread.hpp" |  | ||||||
| #include "util/json.hpp" |  | ||||||
| #include "ALabel.hpp" |  | ||||||
| #include "modules/sway/ipc/client.hpp" | #include "modules/sway/ipc/client.hpp" | ||||||
|  | #include "util/json.hpp" | ||||||
|  | #include "util/sleeper_thread.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules::sway { | namespace waybar::modules::sway { | ||||||
|  |  | ||||||
| class Window : public ALabel { | class Window : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Window(const std::string&, const waybar::Bar&, const Json::Value&); |   Window(const std::string&, const waybar::Bar&, const Json::Value&); | ||||||
|     ~Window() = default; |   ~Window() = default; | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     void worker(); |  | ||||||
|     std::tuple<int, std::string> getFocusedNode(Json::Value nodes); |  | ||||||
|     void getFocusedWindow(); |  | ||||||
|  |  | ||||||
|     const Bar& bar_; |  private: | ||||||
|     waybar::util::SleeperThread thread_; |   void                         onEvent(const struct Ipc::ipc_response); | ||||||
|     util::JsonParser parser_; |   void                         onCmd(const struct Ipc::ipc_response); | ||||||
|     Ipc ipc_; |   void                         worker(); | ||||||
|     std::string window_; |   std::tuple<int, std::string> getFocusedNode(Json::Value nodes); | ||||||
|     int windowId_; |   void                         getFocusedWindow(); | ||||||
|  |  | ||||||
|  |   const Bar&                  bar_; | ||||||
|  |   waybar::util::SleeperThread thread_; | ||||||
|  |   util::JsonParser            parser_; | ||||||
|  |   Ipc                         ipc_; | ||||||
|  |   std::string                 window_; | ||||||
|  |   int                         windowId_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules::sway | ||||||
|   | |||||||
| @@ -1,43 +1,46 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "bar.hpp" |  | ||||||
| #include "client.hpp" |  | ||||||
| #include "util/sleeper_thread.hpp" |  | ||||||
| #include "util/json.hpp" |  | ||||||
| #include "IModule.hpp" |  | ||||||
| #include "modules/sway/ipc/client.hpp" |  | ||||||
| #include <gtkmm/button.h> | #include <gtkmm/button.h> | ||||||
| #include <gtkmm/label.h> | #include <gtkmm/label.h> | ||||||
|  | #include "IModule.hpp" | ||||||
|  | #include "bar.hpp" | ||||||
|  | #include "client.hpp" | ||||||
|  | #include "modules/sway/ipc/client.hpp" | ||||||
|  | #include "util/json.hpp" | ||||||
|  | #include "util/sleeper_thread.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules::sway { | namespace waybar::modules::sway { | ||||||
|  |  | ||||||
| class Workspaces : public IModule { | class Workspaces : public IModule { | ||||||
|   public: |  public: | ||||||
|     Workspaces(const std::string&, const waybar::Bar&, const Json::Value&); |   Workspaces(const std::string&, const waybar::Bar&, const Json::Value&); | ||||||
|     ~Workspaces() = default; |   ~Workspaces() = default; | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|     operator Gtk::Widget &(); |        operator Gtk::Widget&(); | ||||||
|   private: |  | ||||||
|     void worker(); |  | ||||||
|     void addWorkspace(const Json::Value&); |  | ||||||
| 		void onButtonReady(const Json::Value&, Gtk::Button&); |  | ||||||
|     std::string getIcon(const std::string&, const Json::Value&); |  | ||||||
|     bool handleScroll(GdkEventScroll*); |  | ||||||
|     const std::string getCycleWorkspace(uint8_t current, bool prev) const; |  | ||||||
|     uint16_t getWorkspaceIndex(const std::string &name) const; |  | ||||||
|     std::string trimWorkspaceName(std::string); |  | ||||||
|  |  | ||||||
|     const Bar& bar_; |  private: | ||||||
|     const Json::Value& config_; |   void              onCmd(const struct Ipc::ipc_response); | ||||||
|     Json::Value workspaces_; |   void              onEvent(const struct Ipc::ipc_response); | ||||||
|     waybar::util::SleeperThread thread_; |   void              worker(); | ||||||
|     Gtk::Box box_; |   bool              filterButtons(); | ||||||
|     util::JsonParser parser_; |   Gtk::Button&      addButton(const Json::Value&); | ||||||
|     Ipc ipc_; |   void              onButtonReady(const Json::Value&, Gtk::Button&); | ||||||
|     std::mutex mutex_; |   std::string       getIcon(const std::string&, const Json::Value&); | ||||||
|     bool scrolling_; |   bool              handleScroll(GdkEventScroll*); | ||||||
|     std::unordered_map<std::string, Gtk::Button> buttons_; |   const std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const; | ||||||
|  |   uint16_t          getWorkspaceIndex(const std::string& name) const; | ||||||
|  |   std::string       trimWorkspaceName(std::string); | ||||||
|  |  | ||||||
|  |   const Bar&                                   bar_; | ||||||
|  |   const Json::Value&                           config_; | ||||||
|  |   std::vector<Json::Value>                     workspaces_; | ||||||
|  |   waybar::util::SleeperThread                  thread_; | ||||||
|  |   Gtk::Box                                     box_; | ||||||
|  |   util::JsonParser                             parser_; | ||||||
|  |   Ipc                                          ipc_; | ||||||
|  |   bool                                         scrolling_; | ||||||
|  |   std::unordered_map<std::string, Gtk::Button> buttons_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules::sway | ||||||
|   | |||||||
| @@ -2,8 +2,8 @@ | |||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <fstream> | #include <fstream> | ||||||
| #include "util/sleeper_thread.hpp" |  | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  | #include "util/sleeper_thread.hpp" | ||||||
| #ifdef FILESYSTEM_EXPERIMENTAL | #ifdef FILESYSTEM_EXPERIMENTAL | ||||||
| #include <experimental/filesystem> | #include <experimental/filesystem> | ||||||
| #else | #else | ||||||
| @@ -13,16 +13,17 @@ | |||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|  |  | ||||||
| class Temperature : public ALabel { | class Temperature : public ALabel { | ||||||
|   public: |  public: | ||||||
|     Temperature(const std::string&, const Json::Value&); |   Temperature(const std::string&, const Json::Value&); | ||||||
|     ~Temperature() = default; |   ~Temperature() = default; | ||||||
|     auto update() -> void; |   auto update() -> void; | ||||||
|   private: |  | ||||||
|     std::tuple<uint16_t, uint16_t> getTemperature(); |  | ||||||
|     bool isCritical(uint16_t); |  | ||||||
|  |  | ||||||
|     std::string file_path_; |  private: | ||||||
|     waybar::util::SleeperThread thread_; |   std::tuple<uint16_t, uint16_t> getTemperature(); | ||||||
|  |   bool                           isCritical(uint16_t); | ||||||
|  |  | ||||||
|  |   std::string                 file_path_; | ||||||
|  |   waybar::util::SleeperThread thread_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::modules | ||||||
| @@ -1,25 +1,24 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <sys/wait.h> |  | ||||||
| #include <giomm.h> | #include <giomm.h> | ||||||
|  | #include <sys/wait.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  |  | ||||||
| namespace waybar::util::command { | namespace waybar::util::command { | ||||||
|  |  | ||||||
| struct res { | struct res { | ||||||
|   int exit_code; |   int         exit_code; | ||||||
|   std::string out; |   std::string out; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| inline struct res exec(const std::string cmd) | inline struct res exec(const std::string cmd) { | ||||||
| { |  | ||||||
|   FILE* fp(popen(cmd.c_str(), "r")); |   FILE* fp(popen(cmd.c_str(), "r")); | ||||||
|   if (!fp) { |   if (!fp) { | ||||||
|     return { -1, "" }; |     return {-1, ""}; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   std::array<char, 128> buffer = {0}; |   std::array<char, 128> buffer = {0}; | ||||||
|   std::string output; |   std::string           output; | ||||||
|   while (feof(fp) == 0) { |   while (feof(fp) == 0) { | ||||||
|     if (fgets(buffer.data(), 128, fp) != nullptr) { |     if (fgets(buffer.data(), 128, fp) != nullptr) { | ||||||
|       output += buffer.data(); |       output += buffer.data(); | ||||||
| @@ -27,8 +26,8 @@ inline struct res exec(const std::string cmd) | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Remove last newline |   // Remove last newline | ||||||
|   if (!output.empty() && output[output.length()-1] == '\n') { |   if (!output.empty() && output[output.length() - 1] == '\n') { | ||||||
|     output.erase(output.length()-1); |     output.erase(output.length() - 1); | ||||||
|   } |   } | ||||||
|   int exit_code = WEXITSTATUS(pclose(fp)); |   int exit_code = WEXITSTATUS(pclose(fp)); | ||||||
|   return {exit_code, output}; |   return {exit_code, output}; | ||||||
|   | |||||||
| @@ -5,27 +5,24 @@ | |||||||
| namespace waybar::util { | namespace waybar::util { | ||||||
|  |  | ||||||
| struct JsonParser { | struct JsonParser { | ||||||
|  |   JsonParser() : reader_(builder_.newCharReader()) {} | ||||||
|  |  | ||||||
|   JsonParser() |   const Json::Value parse(const std::string& data) const { | ||||||
|     : reader_(builder_.newCharReader()) |  | ||||||
|   {} |  | ||||||
|  |  | ||||||
|   const Json::Value parse(const std::string& data) const |  | ||||||
|   { |  | ||||||
|     Json::Value root; |     Json::Value root; | ||||||
|     std::string err; |     std::string err; | ||||||
|     bool res = |     if (data.empty()) { | ||||||
|       reader_->parse(data.c_str(), data.c_str() + data.size(), &root, &err); |       return root; | ||||||
|     if (!res) |     } | ||||||
|       throw std::runtime_error(err); |     bool res = reader_->parse(data.c_str(), data.c_str() + data.size(), &root, &err); | ||||||
|  |     if (!res) throw std::runtime_error(err); | ||||||
|     return root; |     return root; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ~JsonParser() = default; |   ~JsonParser() = default; | ||||||
|  |  | ||||||
| private: |  private: | ||||||
|   Json::CharReaderBuilder builder_; |   Json::CharReaderBuilder                 builder_; | ||||||
|   std::unique_ptr<Json::CharReader> const reader_; |   std::unique_ptr<Json::CharReader> const reader_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::util | ||||||
|   | |||||||
| @@ -1,25 +1,23 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <chrono> | #include <chrono> | ||||||
|  | #include <condition_variable> | ||||||
| #include <ctime> | #include <ctime> | ||||||
| #include <functional> | #include <functional> | ||||||
| #include <condition_variable> |  | ||||||
| #include <thread> | #include <thread> | ||||||
|  |  | ||||||
| namespace waybar::util { | namespace waybar::util { | ||||||
|  |  | ||||||
| class SleeperThread { | class SleeperThread { | ||||||
| public: |  public: | ||||||
|   SleeperThread() = default; |   SleeperThread() = default; | ||||||
|  |  | ||||||
|   SleeperThread(std::function<void()> func) |   SleeperThread(std::function<void()> func) | ||||||
|     : thread_{[this, func] { |       : thread_{[this, func] { | ||||||
|         while (do_run_) func(); |           while (do_run_) func(); | ||||||
|       }} |         }} {} | ||||||
|   {} |  | ||||||
|  |  | ||||||
|   SleeperThread& operator=(std::function<void()> func) |   SleeperThread& operator=(std::function<void()> func) { | ||||||
|   { |  | ||||||
|     thread_ = std::thread([this, func] { |     thread_ = std::thread([this, func] { | ||||||
|       while (do_run_) { |       while (do_run_) { | ||||||
|         signal_ = false; |         signal_ = false; | ||||||
| @@ -29,32 +27,26 @@ public: | |||||||
|     return *this; |     return *this; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   bool isRunning() const |   bool isRunning() const { return do_run_; } | ||||||
|   { |  | ||||||
|     return do_run_; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   auto sleep_for(std::chrono::system_clock::duration dur) |   auto sleep_for(std::chrono::system_clock::duration dur) { | ||||||
|   { |  | ||||||
|     std::unique_lock lk(mutex_); |     std::unique_lock lk(mutex_); | ||||||
|     return condvar_.wait_for(lk, dur, [this] { return signal_ || !do_run_; }); |     return condvar_.wait_for(lk, dur, [this] { return signal_ || !do_run_; }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   auto sleep_until(std::chrono::time_point<std::chrono::system_clock, |   auto sleep_until( | ||||||
|     std::chrono::system_clock::duration> time_point) |       std::chrono::time_point<std::chrono::system_clock, std::chrono::system_clock::duration> | ||||||
|   { |           time_point) { | ||||||
|     std::unique_lock lk(mutex_); |     std::unique_lock lk(mutex_); | ||||||
|     return condvar_.wait_until(lk, time_point, [this] { return signal_ || !do_run_; }); |     return condvar_.wait_until(lk, time_point, [this] { return signal_ || !do_run_; }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   auto wake_up() |   auto wake_up() { | ||||||
|   { |  | ||||||
|     signal_ = true; |     signal_ = true; | ||||||
|     condvar_.notify_all(); |     condvar_.notify_all(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   auto stop() |   auto stop() { | ||||||
|   { |  | ||||||
|     { |     { | ||||||
|       std::lock_guard<std::mutex> lck(mutex_); |       std::lock_guard<std::mutex> lck(mutex_); | ||||||
|       signal_ = true; |       signal_ = true; | ||||||
| @@ -63,20 +55,19 @@ public: | |||||||
|     condvar_.notify_all(); |     condvar_.notify_all(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ~SleeperThread() |   ~SleeperThread() { | ||||||
|   { |  | ||||||
|     stop(); |     stop(); | ||||||
|     if (thread_.joinable()) { |     if (thread_.joinable()) { | ||||||
|       thread_.join(); |       thread_.join(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| private: |  private: | ||||||
|   std::thread thread_; |   std::thread             thread_; | ||||||
|   std::condition_variable condvar_; |   std::condition_variable condvar_; | ||||||
|   std::mutex mutex_; |   std::mutex              mutex_; | ||||||
|   bool do_run_ = true; |   bool                    do_run_ = true; | ||||||
|   bool signal_ = false; |   bool                    signal_ = false; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | }  // namespace waybar::util | ||||||
|   | |||||||
| @@ -4,33 +4,31 @@ | |||||||
| #include <iostream> | #include <iostream> | ||||||
|  |  | ||||||
| waybar::ALabel::ALabel(const Json::Value& config, const std::string format, uint16_t interval) | waybar::ALabel::ALabel(const Json::Value& config, const std::string format, uint16_t interval) | ||||||
|   : config_(config), |     : config_(config), | ||||||
|     format_(config_["format"].isString() ? config_["format"].asString() : format), |       format_(config_["format"].isString() ? config_["format"].asString() : format), | ||||||
|     interval_(config_["interval"] == "once" ? std::chrono::seconds(100000000) : |       interval_(config_["interval"] == "once" | ||||||
|       std::chrono::seconds(config_["interval"].isUInt() ? |                     ? std::chrono::seconds(100000000) | ||||||
|       config_["interval"].asUInt() : interval)), default_format_(format_) |                     : std::chrono::seconds( | ||||||
| { |                           config_["interval"].isUInt() ? config_["interval"].asUInt() : interval)), | ||||||
|  |       default_format_(format_) { | ||||||
|   event_box_.add(label_); |   event_box_.add(label_); | ||||||
| 	if (config_["max-length"].isUInt()) { |   if (config_["max-length"].isUInt()) { | ||||||
|     label_.set_max_width_chars(config_["max-length"].asUInt()); |     label_.set_max_width_chars(config_["max-length"].asUInt()); | ||||||
|     label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); |     label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); | ||||||
|   } |   } | ||||||
|   if (config_["format-alt"].isString()) { |   if (config_["format-alt"].isString()) { | ||||||
|     event_box_.add_events(Gdk::BUTTON_PRESS_MASK); |     event_box_.add_events(Gdk::BUTTON_PRESS_MASK); | ||||||
|     event_box_.signal_button_press_event().connect( |     event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &ALabel::handleToggle)); | ||||||
|         sigc::mem_fun(*this, &ALabel::handleToggle)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // configure events' user commands |   // configure events' user commands | ||||||
|   if (config_["on-click"].isString() || config_["on-click-right"].isString()) { |   if (config_["on-click"].isString() || config_["on-click-right"].isString()) { | ||||||
|     event_box_.add_events(Gdk::BUTTON_PRESS_MASK); |     event_box_.add_events(Gdk::BUTTON_PRESS_MASK); | ||||||
|     event_box_.signal_button_press_event().connect( |     event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &ALabel::handleToggle)); | ||||||
|       sigc::mem_fun(*this, &ALabel::handleToggle)); |  | ||||||
|   } |   } | ||||||
|   if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { |   if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { | ||||||
|     event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); |     event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); | ||||||
|     event_box_.signal_scroll_event().connect( |     event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &ALabel::handleScroll)); | ||||||
|       sigc::mem_fun(*this, &ALabel::handleScroll)); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -49,8 +47,6 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) { | |||||||
|     waybar::util::command::forkExec(config_["on-click-backward"].asString()); |     waybar::util::command::forkExec(config_["on-click-backward"].asString()); | ||||||
|   } else if (config_["on-click-backward"].isString() && e->button == 9) { |   } else if (config_["on-click-backward"].isString() && e->button == 9) { | ||||||
|     waybar::util::command::forkExec(config_["on-click-forward"].asString()); |     waybar::util::command::forkExec(config_["on-click-forward"].asString()); | ||||||
|  |  | ||||||
|  |  | ||||||
|   } |   } | ||||||
|   if (config_["format-alt-click"].isUInt() && e->button == config_["format-alt-click"].asUInt()) { |   if (config_["format-alt-click"].isUInt() && e->button == config_["format-alt-click"].asUInt()) { | ||||||
|     alt_ = !alt_; |     alt_ = !alt_; | ||||||
| @@ -66,10 +62,9 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) { | |||||||
| } | } | ||||||
|  |  | ||||||
| bool waybar::ALabel::handleScroll(GdkEventScroll* e) { | bool waybar::ALabel::handleScroll(GdkEventScroll* e) { | ||||||
|  |  | ||||||
|   // Avoid concurrent scroll event |   // Avoid concurrent scroll event | ||||||
|   std::lock_guard<std::mutex> lock(mutex_); |   std::lock_guard<std::mutex> lock(mutex_); | ||||||
|   bool direction_up = false; |   bool                        direction_up = false; | ||||||
|  |  | ||||||
|   if (e->direction == GDK_SCROLL_UP) { |   if (e->direction == GDK_SCROLL_UP) { | ||||||
|     direction_up = true; |     direction_up = true; | ||||||
| @@ -79,8 +74,7 @@ bool waybar::ALabel::handleScroll(GdkEventScroll* e) { | |||||||
|   } |   } | ||||||
|   if (e->direction == GDK_SCROLL_SMOOTH) { |   if (e->direction == GDK_SCROLL_SMOOTH) { | ||||||
|     gdouble delta_x, delta_y; |     gdouble delta_x, delta_y; | ||||||
|     gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent*>(e), |     gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent*>(e), &delta_x, &delta_y); | ||||||
|                                 &delta_x, &delta_y); |  | ||||||
|     if (delta_y < 0) { |     if (delta_y < 0) { | ||||||
|       direction_up = true; |       direction_up = true; | ||||||
|     } else if (delta_y > 0) { |     } else if (delta_y > 0) { | ||||||
| @@ -96,8 +90,7 @@ bool waybar::ALabel::handleScroll(GdkEventScroll* e) { | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt) | std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt) { | ||||||
| { |  | ||||||
|   auto format_icons = config_["format-icons"]; |   auto format_icons = config_["format-icons"]; | ||||||
|   if (format_icons.isObject()) { |   if (format_icons.isObject()) { | ||||||
|     if (!alt.empty() && (format_icons[alt].isString() || format_icons[alt].isArray())) { |     if (!alt.empty() && (format_icons[alt].isString() || format_icons[alt].isArray())) { | ||||||
| @@ -117,8 +110,7 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt) | |||||||
|   return ""; |   return ""; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool waybar::ALabel::tooltipEnabled() | bool waybar::ALabel::tooltipEnabled() { | ||||||
| { |  | ||||||
|   return config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true; |   return config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										291
									
								
								src/bar.cpp
									
									
									
									
									
								
							
							
						
						
									
										291
									
								
								src/bar.cpp
									
									
									
									
									
								
							| @@ -1,32 +1,25 @@ | |||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
| #include "factory.hpp" | #include "factory.hpp" | ||||||
| #include "util/json.hpp" |  | ||||||
|  |  | ||||||
| waybar::Bar::Bar(const Client& client, | waybar::Bar::Bar(struct waybar_output* w_output) | ||||||
|   std::unique_ptr<struct wl_output *> &&p_output, uint32_t p_wl_name) |     : output(w_output), | ||||||
|   : client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL}, |       window{Gtk::WindowType::WINDOW_TOPLEVEL}, | ||||||
|     surface(nullptr), layer_surface(nullptr), |       surface(nullptr), | ||||||
|     output(std::move(p_output)), wl_name(p_wl_name), |       layer_surface(nullptr), | ||||||
|     left_(Gtk::ORIENTATION_HORIZONTAL, 0), center_(Gtk::ORIENTATION_HORIZONTAL, 0), |       left_(Gtk::ORIENTATION_HORIZONTAL, 0), | ||||||
|     right_(Gtk::ORIENTATION_HORIZONTAL, 0), box_(Gtk::ORIENTATION_HORIZONTAL, 0) |       center_(Gtk::ORIENTATION_HORIZONTAL, 0), | ||||||
| { |       right_(Gtk::ORIENTATION_HORIZONTAL, 0), | ||||||
|   static const struct zxdg_output_v1_listener xdgOutputListener = { |       box_(Gtk::ORIENTATION_HORIZONTAL, 0) { | ||||||
|     .logical_position = handleLogicalPosition, |  | ||||||
|     .logical_size = handleLogicalSize, |  | ||||||
|     .done = handleDone, |  | ||||||
|     .name = handleName, |  | ||||||
|     .description = handleDescription, |  | ||||||
|   }; |  | ||||||
|   xdg_output_ = |  | ||||||
|     zxdg_output_manager_v1_get_xdg_output(client.xdg_output_manager, *output); |  | ||||||
| 	zxdg_output_v1_add_listener(xdg_output_, &xdgOutputListener, this); |  | ||||||
|   window.set_title("waybar"); |   window.set_title("waybar"); | ||||||
|   window.set_name("waybar"); |   window.set_name("waybar"); | ||||||
|   window.set_decorated(false); |   window.set_decorated(false); | ||||||
|   window.set_resizable(false); |  | ||||||
|   setupConfig(); |   if (output->config["position"] == "right" || output->config["position"] == "left") { | ||||||
|   setupCss(); |     height_ = 0; | ||||||
|  |     width_ = 30; | ||||||
|  |   } | ||||||
|  |   window.set_size_request(width_, height_); | ||||||
|  |  | ||||||
|   auto gtk_window = window.gobj(); |   auto gtk_window = window.gobj(); | ||||||
|   auto gtk_widget = GTK_WIDGET(gtk_window); |   auto gtk_widget = GTK_WIDGET(gtk_window); | ||||||
| @@ -34,87 +27,33 @@ waybar::Bar::Bar(const Client& client, | |||||||
|   auto gdk_window = window.get_window()->gobj(); |   auto gdk_window = window.get_window()->gobj(); | ||||||
|   gdk_wayland_window_set_use_custom_surface(gdk_window); |   gdk_wayland_window_set_use_custom_surface(gdk_window); | ||||||
|   surface = gdk_wayland_window_get_wl_surface(gdk_window); |   surface = gdk_wayland_window_get_wl_surface(gdk_window); | ||||||
| } |  | ||||||
|  |  | ||||||
| void waybar::Bar::initBar() |   std::size_t layer = output->config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP | ||||||
| { |                                                        : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; | ||||||
|   // Converting string to button code rn as to avoid doing it later |   auto client = waybar::Client::inst(); | ||||||
|   auto setupAltFormatKeyForModule = [this](const std::string& module_name){ |  | ||||||
|   	if (config_.isMember(module_name)) { |  | ||||||
|       Json::Value& module = config_[module_name]; |  | ||||||
|       if (module.isMember("format-alt")) { |  | ||||||
|         if (module.isMember("format-alt-click")) { |  | ||||||
|           Json::Value& click = module["format-alt-click"]; |  | ||||||
|           if (click.isString()) { |  | ||||||
| 	        std::string str_click = click.asString(); |  | ||||||
|  |  | ||||||
| 	        if (str_click == "click-right") { |  | ||||||
| 		      module["format-alt-click"] = 3u; |  | ||||||
| 	        } else if (str_click == "click-middle") { |  | ||||||
| 		      module["format-alt-click"] = 2u; |  | ||||||
| 	        } else if (str_click == "click-backward") { |  | ||||||
| 		      module["format-alt-click"] = 8u; |  | ||||||
| 	        } else if (str_click == "click-forward") { |  | ||||||
| 		      module["format-alt-click"] = 9u; |  | ||||||
| 	        } else { |  | ||||||
| 		      module["format-alt-click"] = 1u; // default click-left |  | ||||||
| 	        } |  | ||||||
|           } else { |  | ||||||
|             module["format-alt-click"] = 1u; |  | ||||||
|           } |  | ||||||
|         } else { |  | ||||||
| 	      module["format-alt-click"] = 1u; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   auto setupAltFormatKeyForModuleList = [this, &setupAltFormatKeyForModule](const char* module_list_name) { |  | ||||||
|   	if (config_.isMember(module_list_name)) { |  | ||||||
|   		Json::Value& modules = config_[module_list_name]; |  | ||||||
| 	    for (const Json::Value& module_name : modules) { |  | ||||||
| 		    if (module_name.isString()) { |  | ||||||
| 			    setupAltFormatKeyForModule(module_name.asString()); |  | ||||||
| 		    } |  | ||||||
| 	    } |  | ||||||
|   	} |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   // Convert to button code for every module that is used. |  | ||||||
|   setupAltFormatKeyForModuleList("modules-left"); |  | ||||||
|   setupAltFormatKeyForModuleList("modules-right"); |  | ||||||
|   setupAltFormatKeyForModuleList("modules-center"); |  | ||||||
|   std::size_t layer = config_["layer"] == "top" |  | ||||||
|     ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; |  | ||||||
|   layer_surface = zwlr_layer_shell_v1_get_layer_surface( |   layer_surface = zwlr_layer_shell_v1_get_layer_surface( | ||||||
|     client.layer_shell, surface, *output, layer, "waybar"); |       client->layer_shell, surface, output->output, layer, "waybar"); | ||||||
|  |  | ||||||
|   static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { |   static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { | ||||||
|     .configure = layerSurfaceHandleConfigure, |       .configure = layerSurfaceHandleConfigure, | ||||||
|     .closed = layerSurfaceHandleClosed, |       .closed = layerSurfaceHandleClosed, | ||||||
|   }; |   }; | ||||||
|   zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, this); |   zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, this); | ||||||
|  |  | ||||||
|   if (config_["position"] == "right" || config_["position"] == "left") { |   auto height = output->config["height"].isUInt() ? output->config["height"].asUInt() : height_; | ||||||
|     height_ = 0; |   auto width = output->config["width"].isUInt() ? output->config["width"].asUInt() : width_; | ||||||
|     width_ = 30; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   auto height = config_["height"].isUInt() ? config_["height"].asUInt() : height_; |  | ||||||
|   auto width = config_["width"].isUInt() ? config_["width"].asUInt() : width_; |  | ||||||
|  |  | ||||||
|   std::size_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; |   std::size_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; | ||||||
|   if (config_["position"] == "bottom") { |   if (output->config["position"] == "bottom") { | ||||||
|     anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; |     anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; | ||||||
|   } else if (config_["position"] == "left") { |   } else if (output->config["position"] == "left") { | ||||||
|     anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; |     anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; | ||||||
|   } else if (config_["position"] == "right") { |   } else if (output->config["position"] == "right") { | ||||||
|     anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; |     anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ||||||
|   } |   } | ||||||
|   if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM || anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) { |   if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM || anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) { | ||||||
|     anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; |     anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ||||||
|   } else if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT || anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) { |   } else if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT || | ||||||
|  |              anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) { | ||||||
|     anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; |     anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; | ||||||
|     left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); |     left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); | ||||||
|     center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); |     center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); | ||||||
| @@ -128,103 +67,71 @@ void waybar::Bar::initBar() | |||||||
|   zwlr_layer_surface_v1_set_size(layer_surface, width, height); |   zwlr_layer_surface_v1_set_size(layer_surface, width, height); | ||||||
|  |  | ||||||
|   wl_surface_commit(surface); |   wl_surface_commit(surface); | ||||||
|  |   wl_display_roundtrip(client->wl_display); | ||||||
|  |  | ||||||
|   setupWidgets(); |   setupWidgets(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Bar::handleLogicalPosition(void* /*data*/, | // Converting string to button code rn as to avoid doing it later | ||||||
|   struct zxdg_output_v1* /*zxdg_output_v1*/, int32_t /*x*/, int32_t /*y*/) | void waybar::Bar::setupAltFormatKeyForModule(const std::string& module_name) { | ||||||
| { |   if (output->config.isMember(module_name)) { | ||||||
|   // Nothing here |     Json::Value& module = output->config[module_name]; | ||||||
| } |     if (module.isMember("format-alt")) { | ||||||
|  |       if (module.isMember("format-alt-click")) { | ||||||
|  |         Json::Value& click = module["format-alt-click"]; | ||||||
|  |         if (click.isString()) { | ||||||
|  |           std::string str_click = click.asString(); | ||||||
|  |  | ||||||
| void waybar::Bar::handleLogicalSize(void* /*data*/, |           if (str_click == "click-right") { | ||||||
|   struct zxdg_output_v1* /*zxdg_output_v1*/, int32_t /*width*/, |             module["format-alt-click"] = 3u; | ||||||
|   int32_t /*height*/) |           } else if (str_click == "click-middle") { | ||||||
| { |             module["format-alt-click"] = 2u; | ||||||
|   // Nothing here |           } else if (str_click == "click-backward") { | ||||||
| } |             module["format-alt-click"] = 8u; | ||||||
|  |           } else if (str_click == "click-forward") { | ||||||
| void waybar::Bar::handleDone(void* /*data*/, |             module["format-alt-click"] = 9u; | ||||||
|   struct zxdg_output_v1* /*zxdg_output_v1*/) |           } else { | ||||||
| { |             module["format-alt-click"] = 1u;  // default click-left | ||||||
|   // Nothing here |           } | ||||||
| } |         } else { | ||||||
|  |           module["format-alt-click"] = 1u; | ||||||
| bool waybar::Bar::isValidOutput(const Json::Value &config) |         } | ||||||
| { |       } else { | ||||||
|   bool found = true; |         module["format-alt-click"] = 1u; | ||||||
|   if (config["output"].isArray()) { |  | ||||||
|     bool in_array = false; |  | ||||||
|     for (auto const &output : config["output"]) { |  | ||||||
|       if (output.isString() && output.asString() == output_name) { |  | ||||||
|         in_array = true; |  | ||||||
|         break; |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     found = in_array; |  | ||||||
|   } |   } | ||||||
|   if (config["output"].isString() && config["output"].asString() != output_name) { |  | ||||||
|     found = false; |  | ||||||
|   } |  | ||||||
|   return found; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Bar::handleName(void* data, struct zxdg_output_v1* /*xdg_output*/, | void waybar::Bar::setupAltFormatKeyForModuleList(const char* module_list_name) { | ||||||
|   const char* name) |   if (output->config.isMember(module_list_name)) { | ||||||
| { |     Json::Value& modules = output->config[module_list_name]; | ||||||
| 	auto o = static_cast<waybar::Bar *>(data); |     for (const Json::Value& module_name : modules) { | ||||||
|   o->output_name = name; |       if (module_name.isString()) { | ||||||
|   bool found = true; |         setupAltFormatKeyForModule(module_name.asString()); | ||||||
|   if (o->config_.isArray()) { |  | ||||||
|     bool in_array = false; |  | ||||||
|     for (auto const &config : o->config_) { |  | ||||||
|       if (config.isObject() && o->isValidOutput(config)) { |  | ||||||
|         in_array = true; |  | ||||||
|         o->config_ = config; |  | ||||||
|         break; |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     found = in_array; |  | ||||||
|   } else { |  | ||||||
|     found = o->isValidOutput(o->config_); |  | ||||||
|   } |  | ||||||
|   if (!found) { |  | ||||||
|     wl_output_destroy(*o->output); |  | ||||||
|     zxdg_output_v1_destroy(o->xdg_output_); |  | ||||||
|   } else { |  | ||||||
|     o->initBar(); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Bar::handleDescription(void* /*data*/, | void waybar::Bar::handleSignal(int signal) { | ||||||
|   struct zxdg_output_v1* /*zxdg_output_v1*/, const char* /*description*/) |  | ||||||
| { |  | ||||||
|   // Nothing here |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void waybar::Bar::handleSignal(int signal) |  | ||||||
| { |  | ||||||
|   for (auto& module : modules_left_) { |   for (auto& module : modules_left_) { | ||||||
|     auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get()); |     auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get()); | ||||||
|     if(custom) custom->refresh(signal); |     if (custom) custom->refresh(signal); | ||||||
|   } |   } | ||||||
|   for (auto& module : modules_center_) { |   for (auto& module : modules_center_) { | ||||||
|     auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get()); |     auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get()); | ||||||
|     if(custom) custom->refresh(signal); |     if (custom) custom->refresh(signal); | ||||||
|   } |   } | ||||||
|   for (auto& module : modules_right_) { |   for (auto& module : modules_right_) { | ||||||
|     auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get()); |     auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get()); | ||||||
|     if(custom) custom->refresh(signal); |     if (custom) custom->refresh(signal); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Bar::layerSurfaceHandleConfigure(void* data, | void waybar::Bar::layerSurfaceHandleConfigure(void* data, struct zwlr_layer_surface_v1* surface, | ||||||
|   struct zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width, |                                               uint32_t serial, uint32_t width, uint32_t height) { | ||||||
|   uint32_t height) |   auto o = static_cast<waybar::Bar*>(data); | ||||||
| { |  | ||||||
|   auto o = static_cast<waybar::Bar *>(data); |  | ||||||
|   zwlr_layer_surface_v1_ack_configure(surface, serial); |  | ||||||
|   if (width != o->width_ || height != o->height_) { |   if (width != o->width_ || height != o->height_) { | ||||||
|     o->width_ = width; |     o->width_ = width; | ||||||
|     o->height_ = height; |     o->height_ = height; | ||||||
| @@ -234,37 +141,29 @@ void waybar::Bar::layerSurfaceHandleConfigure(void* data, | |||||||
|     int min_width, min_height; |     int min_width, min_height; | ||||||
|     o->window.get_size(min_width, min_height); |     o->window.get_size(min_width, min_height); | ||||||
|     if (o->height_ < static_cast<uint32_t>(min_height)) { |     if (o->height_ < static_cast<uint32_t>(min_height)) { | ||||||
|       std::cout << fmt::format("Requested height: {} exceeds the minimum \ |       std::cout << fmt::format(MIN_HEIGHT_MSG, o->height_, min_height) << std::endl; | ||||||
| height: {} required by the modules", o->height_, min_height) << std::endl; |  | ||||||
|       o->height_ = min_height; |       o->height_ = min_height; | ||||||
|     } |     } | ||||||
|     if (o->width_ < static_cast<uint32_t>(min_width)) { |     if (o->width_ < static_cast<uint32_t>(min_width)) { | ||||||
|       std::cout << fmt::format("Requested width: {} exceeds the minimum \ |       std::cout << fmt::format(MIN_WIDTH_MSG, o->height_, min_width) << std::endl; | ||||||
| width: {} required by the modules", o->height_, min_width) << std::endl; |  | ||||||
|       o->width_ = min_width; |       o->width_ = min_width; | ||||||
|     } |     } | ||||||
|     std::cout << fmt::format( |     std::cout << fmt::format(BAR_SIZE_MSG, o->width_, o->height_, o->output->name) << std::endl; | ||||||
|       "Bar configured (width: {}, height: {}) for output: {}", |  | ||||||
|       o->width_, o->height_, o->output_name) << std::endl; |  | ||||||
|  |  | ||||||
|     wl_surface_commit(o->surface); |     wl_surface_commit(o->surface); | ||||||
|   } |   } | ||||||
|  |   zwlr_layer_surface_v1_ack_configure(surface, serial); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Bar::layerSurfaceHandleClosed(void* data, | void waybar::Bar::layerSurfaceHandleClosed(void* data, struct zwlr_layer_surface_v1* /*surface*/) { | ||||||
|   struct zwlr_layer_surface_v1* /*surface*/) |   auto o = static_cast<waybar::Bar*>(data); | ||||||
| { |  | ||||||
|   auto o = static_cast<waybar::Bar *>(data); |  | ||||||
|   zwlr_layer_surface_v1_destroy(o->layer_surface); |   zwlr_layer_surface_v1_destroy(o->layer_surface); | ||||||
|   wl_output_destroy(*o->output); |  | ||||||
|   zxdg_output_v1_destroy(o->xdg_output_); |  | ||||||
|   o->modules_left_.clear(); |   o->modules_left_.clear(); | ||||||
|   o->modules_center_.clear(); |   o->modules_center_.clear(); | ||||||
|   o->modules_right_.clear(); |   o->modules_right_.clear(); | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::Bar::toggle() -> void | auto waybar::Bar::toggle() -> void { | ||||||
| { |  | ||||||
|   visible = !visible; |   visible = !visible; | ||||||
|   auto zone = visible ? height_ : 0; |   auto zone = visible ? height_ : 0; | ||||||
|   if (!visible) { |   if (!visible) { | ||||||
| @@ -276,35 +175,9 @@ auto waybar::Bar::toggle() -> void | |||||||
|   wl_surface_commit(surface); |   wl_surface_commit(surface); | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::Bar::setupConfig() -> void | void waybar::Bar::getModules(const Factory& factory, const std::string& pos) { | ||||||
| { |   if (output->config[pos].isArray()) { | ||||||
|   std::ifstream file(client.config_file); |     for (const auto& name : output->config[pos]) { | ||||||
|   if (!file.is_open()) { |  | ||||||
|     throw std::runtime_error("Can't open config file"); |  | ||||||
|   } |  | ||||||
|   std::string str((std::istreambuf_iterator<char>(file)), |  | ||||||
|     std::istreambuf_iterator<char>()); |  | ||||||
|   util::JsonParser parser; |  | ||||||
|   config_ = parser.parse(str); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| auto waybar::Bar::setupCss() -> 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(client.css_file)) { |  | ||||||
|     Glib::RefPtr<Gdk::Screen> screen = window.get_screen(); |  | ||||||
|     style_context_->add_provider_for_screen(screen, css_provider_, |  | ||||||
|       GTK_STYLE_PROVIDER_PRIORITY_USER); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void waybar::Bar::getModules(const Factory& factory, const std::string& pos) |  | ||||||
| { |  | ||||||
|   if (config_[pos].isArray()) { |  | ||||||
|     for (const auto &name : config_[pos]) { |  | ||||||
|       try { |       try { | ||||||
|         auto module = factory.makeModule(name.asString()); |         auto module = factory.makeModule(name.asString()); | ||||||
|         if (pos == "modules-left") { |         if (pos == "modules-left") { | ||||||
| @@ -330,14 +203,18 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos) | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::Bar::setupWidgets() -> void | auto waybar::Bar::setupWidgets() -> void { | ||||||
| { |  | ||||||
|   window.add(box_); |   window.add(box_); | ||||||
|   box_.pack_start(left_, true, true); |   box_.pack_start(left_, true, true); | ||||||
|   box_.set_center_widget(center_); |   box_.set_center_widget(center_); | ||||||
|   box_.pack_end(right_, true, true); |   box_.pack_end(right_, true, true); | ||||||
|  |  | ||||||
|   Factory factory(*this, config_); |   // Convert to button code for every module that is used. | ||||||
|  |   setupAltFormatKeyForModuleList("modules-left"); | ||||||
|  |   setupAltFormatKeyForModuleList("modules-right"); | ||||||
|  |   setupAltFormatKeyForModuleList("modules-center"); | ||||||
|  |  | ||||||
|  |   Factory factory(*this, output->config); | ||||||
|   getModules(factory, "modules-left"); |   getModules(factory, "modules-left"); | ||||||
|   getModules(factory, "modules-center"); |   getModules(factory, "modules-center"); | ||||||
|   getModules(factory, "modules-right"); |   getModules(factory, "modules-right"); | ||||||
|   | |||||||
							
								
								
									
										275
									
								
								src/client.cpp
									
									
									
									
									
								
							
							
						
						
									
										275
									
								
								src/client.cpp
									
									
									
									
									
								
							| @@ -1,25 +1,20 @@ | |||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
| #include "util/clara.hpp" | #include <fstream> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | #include "util/clara.hpp" | ||||||
|  | #include "util/json.hpp" | ||||||
|  |  | ||||||
| waybar::Client::Client(int argc, char* argv[]) | waybar::Client::Client() {} | ||||||
|   : gtk_app(Gtk::Application::create(argc, argv, "fr.arouillard.waybar")), |  | ||||||
|     gdk_display(Gdk::Display::get_default()) | waybar::Client *waybar::Client::inst() { | ||||||
| { |   static Client *c = new Client(); | ||||||
|   if (!gdk_display) { |   return c; | ||||||
|     throw std::runtime_error("Can't find display"); |  | ||||||
|   } |  | ||||||
|   if (!GDK_IS_WAYLAND_DISPLAY(gdk_display->gobj())) { |  | ||||||
|     throw std::runtime_error("Bar need to run under Wayland"); |  | ||||||
|   } |  | ||||||
|   wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj()); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| const std::string waybar::Client::getValidPath(std::vector<std::string> paths) | const std::string waybar::Client::getValidPath(std::vector<std::string> paths) { | ||||||
| { |  | ||||||
|   wordexp_t p; |   wordexp_t p; | ||||||
|  |  | ||||||
|   for (const std::string &path: paths) { |   for (const std::string &path : paths) { | ||||||
|     if (wordexp(path.c_str(), &p, 0) == 0) { |     if (wordexp(path.c_str(), &p, 0) == 0) { | ||||||
|       if (access(*p.we_wordv, F_OK) == 0) { |       if (access(*p.we_wordv, F_OK) == 0) { | ||||||
|         std::string result = *p.we_wordv; |         std::string result = *p.we_wordv; | ||||||
| @@ -33,98 +28,215 @@ const std::string waybar::Client::getValidPath(std::vector<std::string> paths) | |||||||
|   return std::string(); |   return std::string(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, | void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, uint32_t name, | ||||||
|   uint32_t name, const char *interface, uint32_t version) |                                   const char *interface, uint32_t version) { | ||||||
| { |   auto client = static_cast<Client *>(data); | ||||||
|   auto o = static_cast<waybar::Client *>(data); |  | ||||||
|   if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { |   if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { | ||||||
|     o->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>( |     client->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>( | ||||||
|       wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version)); |         wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version)); | ||||||
|   } else if (strcmp(interface, wl_output_interface.name) == 0) { |   } else if (strcmp(interface, wl_output_interface.name) == 0) { | ||||||
|     auto output = std::make_unique<struct wl_output *>(); |     auto wl_output = static_cast<struct wl_output *>( | ||||||
|     *output = static_cast<struct wl_output *>(wl_registry_bind(registry, name, |         wl_registry_bind(registry, name, &wl_output_interface, version)); | ||||||
|       &wl_output_interface, version)); |     client->outputs_.emplace_back(new struct waybar_output({wl_output, "", name, nullptr})); | ||||||
|     if (o->xdg_output_manager != nullptr) { |     client->handleOutput(client->outputs_.back()); | ||||||
|       o->bars.emplace_back(std::make_unique<Bar>(*o, std::move(output), name)); |   } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 && | ||||||
|     } |              version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) { | ||||||
|   } else if (strcmp(interface, wl_seat_interface.name) == 0) { |     client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind( | ||||||
|     o->seat = static_cast<struct wl_seat *>(wl_registry_bind(registry, name, |         registry, name, &zxdg_output_manager_v1_interface, ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)); | ||||||
|       &wl_seat_interface, version)); |  | ||||||
|   } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 |  | ||||||
|     && version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) { |  | ||||||
|       o->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>( |  | ||||||
|         wl_registry_bind(registry, name, |  | ||||||
|         &zxdg_output_manager_v1_interface, ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)); |  | ||||||
|   } else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) { |   } else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) { | ||||||
|     o->idle_inhibit_manager = static_cast<struct zwp_idle_inhibit_manager_v1 *>( |     client->idle_inhibit_manager = static_cast<struct zwp_idle_inhibit_manager_v1 *>( | ||||||
|         wl_registry_bind(registry, name, |         wl_registry_bind(registry, name, &zwp_idle_inhibit_manager_v1_interface, 1)); | ||||||
|         &zwp_idle_inhibit_manager_v1_interface, 1)); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Client::handleGlobalRemove(void* data, | void waybar::Client::handleGlobalRemove(void *   data, struct wl_registry * /*registry*/, | ||||||
|   struct wl_registry* /*registry*/, uint32_t name) |                                         uint32_t name) { | ||||||
| { |   auto client = static_cast<Client *>(data); | ||||||
|   auto o = static_cast<waybar::Client *>(data); |   for (auto it = client->bars.begin(); it != client->bars.end();) { | ||||||
|   for (auto it = o->bars.begin(); it != o->bars.end(); ++it) { |     if ((*it)->output->wl_name == name) { | ||||||
|     if ((*it)->wl_name == name) { |       auto output_name = (*it)->output->name; | ||||||
|       auto output_name = (*it)->output_name; |       (*it)->window.close(); | ||||||
|       o->bars.erase(it); |       it = client->bars.erase(it); | ||||||
|       std::cout << "Bar removed from output: " + output_name << std::endl; |       std::cout << "Bar removed from output: " + output_name << std::endl; | ||||||
|       break; |     } else { | ||||||
|  |       ++it; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |   auto it = std::find_if(client->outputs_.begin(), | ||||||
|  |                          client->outputs_.end(), | ||||||
|  |                          [&name](const auto &output) { return output->wl_name == name; }); | ||||||
|  |   if (it != client->outputs_.end()) { | ||||||
|  |     zxdg_output_v1_destroy((*it)->xdg_output); | ||||||
|  |     wl_output_destroy((*it)->output); | ||||||
|  |     client->outputs_.erase(it); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Client::setupConfigs(const std::string& config, const std::string& style) | void waybar::Client::handleOutput(std::unique_ptr<struct waybar_output> &output) { | ||||||
| { |   static const struct zxdg_output_v1_listener xdgOutputListener = { | ||||||
|   config_file = config.empty() ? getValidPath({ |       .logical_position = handleLogicalPosition, | ||||||
|     "$XDG_CONFIG_HOME/waybar/config", |       .logical_size = handleLogicalSize, | ||||||
|     "$HOME/.config/waybar/config", |       .done = handleDone, | ||||||
|     "$HOME/waybar/config", |       .name = handleName, | ||||||
|     "/etc/xdg/waybar/config", |       .description = handleDescription, | ||||||
|     "./resources/config", |   }; | ||||||
|   }) : config; |   output->xdg_output = zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, output->output); | ||||||
|   css_file = style.empty() ? getValidPath({ |   zxdg_output_v1_add_listener(output->xdg_output, &xdgOutputListener, &output->wl_name); | ||||||
|     "$XDG_CONFIG_HOME/waybar/style.css", | } | ||||||
|     "$HOME/.config/waybar/style.css", |  | ||||||
|     "$HOME/waybar/style.css", | void waybar::Client::handleLogicalPosition(void * /*data*/, | ||||||
|     "/etc/xdg/waybar/style.css", |                                            struct zxdg_output_v1 * /*zxdg_output_v1*/, | ||||||
|     "./resources/style.css", |                                            int32_t /*x*/, int32_t /*y*/) { | ||||||
|   }) : style; |   // Nothing here | ||||||
|   if (css_file.empty() || config_file.empty()) { | } | ||||||
|  |  | ||||||
|  | void waybar::Client::handleLogicalSize(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/, | ||||||
|  |                                        int32_t /*width*/, int32_t /*height*/) { | ||||||
|  |   // Nothing here | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void waybar::Client::handleDone(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/) { | ||||||
|  |   // Nothing here | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool waybar::Client::isValidOutput(const Json::Value &                    config, | ||||||
|  |                                    std::unique_ptr<struct waybar_output> &output) { | ||||||
|  |   bool found = true; | ||||||
|  |   if (config["output"].isArray()) { | ||||||
|  |     bool in_array = false; | ||||||
|  |     for (auto const &output_conf : config["output"]) { | ||||||
|  |       if (output_conf.isString() && output_conf.asString() == output->name) { | ||||||
|  |         in_array = true; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     found = in_array; | ||||||
|  |   } | ||||||
|  |   if (config["output"].isString() && config["output"].asString() != output->name) { | ||||||
|  |     found = false; | ||||||
|  |   } | ||||||
|  |   return found; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void waybar::Client::handleName(void *      data, struct zxdg_output_v1 * /*xdg_output*/, | ||||||
|  |                                 const char *name) { | ||||||
|  |   auto wl_name = *static_cast<uint32_t *>(data); | ||||||
|  |   auto client = waybar::Client::inst(); | ||||||
|  |   auto it = std::find_if(client->outputs_.begin(), | ||||||
|  |                          client->outputs_.end(), | ||||||
|  |                          [&wl_name](const auto &output) { return output->wl_name == wl_name; }); | ||||||
|  |   if (it == client->outputs_.end()) { | ||||||
|  |     std::cerr << "Unable to find valid output" << std::endl; | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   (*it)->name = name; | ||||||
|  |   bool found = true; | ||||||
|  |   if (client->config_.isArray()) { | ||||||
|  |     bool in_array = false; | ||||||
|  |     for (auto const &config : client->config_) { | ||||||
|  |       if (config.isObject() && client->isValidOutput(config, *it)) { | ||||||
|  |         in_array = true; | ||||||
|  |         (*it)->config = config; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     found = in_array; | ||||||
|  |   } else { | ||||||
|  |     (*it)->config = client->config_; | ||||||
|  |     found = client->isValidOutput((*it)->config, *it); | ||||||
|  |   } | ||||||
|  |   if (!found) { | ||||||
|  |     wl_output_destroy((*it)->output); | ||||||
|  |     zxdg_output_v1_destroy((*it)->xdg_output); | ||||||
|  |   } else { | ||||||
|  |     client->bars.emplace_back(std::make_unique<Bar>(it->get())); | ||||||
|  |     Glib::RefPtr<Gdk::Screen> screen = client->bars.back()->window.get_screen(); | ||||||
|  |     client->style_context_->add_provider_for_screen( | ||||||
|  |         screen, client->css_provider_, GTK_STYLE_PROVIDER_PRIORITY_USER); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void waybar::Client::handleDescription(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/, | ||||||
|  |                                        const char * /*description*/) { | ||||||
|  |   // Nothing here | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void waybar::Client::setupConfigs(const std::string &config, const std::string &style) { | ||||||
|  |   config_file_ = config.empty() ? getValidPath({ | ||||||
|  |                                       "$XDG_CONFIG_HOME/waybar/config", | ||||||
|  |                                       "$HOME/.config/waybar/config", | ||||||
|  |                                       "$HOME/waybar/config", | ||||||
|  |                                       "/etc/xdg/waybar/config", | ||||||
|  |                                       "./resources/config", | ||||||
|  |                                   }) | ||||||
|  |                                 : config; | ||||||
|  |   css_file_ = style.empty() ? getValidPath({ | ||||||
|  |                                   "$XDG_CONFIG_HOME/waybar/style.css", | ||||||
|  |                                   "$HOME/.config/waybar/style.css", | ||||||
|  |                                   "$HOME/waybar/style.css", | ||||||
|  |                                   "/etc/xdg/waybar/style.css", | ||||||
|  |                                   "./resources/style.css", | ||||||
|  |                               }) | ||||||
|  |                             : style; | ||||||
|  |   if (css_file_.empty() || config_file_.empty()) { | ||||||
|     throw std::runtime_error("Missing required resources files"); |     throw std::runtime_error("Missing required resources files"); | ||||||
|   } |   } | ||||||
|   std::cout << "Resources files: " + config_file + ", " + css_file << std::endl; |   std::cout << "Resources files: " + config_file_ + ", " + css_file_ << std::endl; | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::Client::bindInterfaces() | auto waybar::Client::setupConfig() -> void { | ||||||
| { |   std::ifstream file(config_file_); | ||||||
|  |   if (!file.is_open()) { | ||||||
|  |     throw std::runtime_error("Can't open config file"); | ||||||
|  |   } | ||||||
|  |   std::string      str((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); | ||||||
|  |   util::JsonParser parser; | ||||||
|  |   config_ = parser.parse(str); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | auto waybar::Client::setupCss() -> 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"); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void waybar::Client::bindInterfaces() { | ||||||
|   registry = wl_display_get_registry(wl_display); |   registry = wl_display_get_registry(wl_display); | ||||||
|   static const struct wl_registry_listener registry_listener = { |   static const struct wl_registry_listener registry_listener = { | ||||||
|     .global = handleGlobal, |       .global = handleGlobal, | ||||||
|     .global_remove = handleGlobalRemove, |       .global_remove = handleGlobalRemove, | ||||||
|   }; |   }; | ||||||
|   wl_registry_add_listener(registry, ®istry_listener, this); |   wl_registry_add_listener(registry, ®istry_listener, this); | ||||||
|   wl_display_roundtrip(wl_display); |   wl_display_roundtrip(wl_display); | ||||||
|   if (!layer_shell || !seat || !xdg_output_manager) { |   if (!layer_shell || !xdg_output_manager) { | ||||||
|     throw std::runtime_error("Failed to acquire required resources."); |     throw std::runtime_error("Failed to acquire required resources."); | ||||||
|   } |   } | ||||||
|   wl_display_roundtrip(wl_display); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::Client::main(int argc, char* argv[]) | int waybar::Client::main(int argc, char *argv[]) { | ||||||
| { |   gtk_app = Gtk::Application::create(argc, argv, "fr.arouillard.waybar"); | ||||||
|   bool show_help = false; |   gdk_display = Gdk::Display::get_default(); | ||||||
|   bool show_version = false; |   if (!gdk_display) { | ||||||
|  |     throw std::runtime_error("Can't find display"); | ||||||
|  |   } | ||||||
|  |   if (!GDK_IS_WAYLAND_DISPLAY(gdk_display->gobj())) { | ||||||
|  |     throw std::runtime_error("Bar need to run under Wayland"); | ||||||
|  |   } | ||||||
|  |   wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj()); | ||||||
|  |   bool        show_help = false; | ||||||
|  |   bool        show_version = false; | ||||||
|   std::string config; |   std::string config; | ||||||
|   std::string style; |   std::string style; | ||||||
|   std::string bar_id; |   std::string bar_id; | ||||||
|   auto cli = clara::detail::Help(show_help) |   auto        cli = clara::detail::Help(show_help) | | ||||||
|     | clara::detail::Opt(show_version)["-v"]["--version"]("Show version") |              clara::detail::Opt(show_version)["-v"]["--version"]("Show version") | | ||||||
|     | clara::detail::Opt(config, "config")["-c"]["--config"]("Config path") |              clara::detail::Opt(config, "config")["-c"]["--config"]("Config path") | | ||||||
|     | clara::detail::Opt(style, "style")["-s"]["--style"]("Style path") |              clara::detail::Opt(style, "style")["-s"]["--style"]("Style path") | | ||||||
|     | clara::detail::Opt(bar_id, "id")["-b"]["--bar"]("Bar id"); |              clara::detail::Opt(bar_id, "id")["-b"]["--bar"]("Bar id"); | ||||||
|   auto res = cli.parse(clara::detail::Args(argc, argv)); |   auto res = cli.parse(clara::detail::Args(argc, argv)); | ||||||
|   if (!res) { |   if (!res) { | ||||||
|     std::cerr << "Error in command line: " << res.errorMessage() << std::endl; |     std::cerr << "Error in command line: " << res.errorMessage() << std::endl; | ||||||
| @@ -139,6 +251,8 @@ int waybar::Client::main(int argc, char* argv[]) | |||||||
|     return 0; |     return 0; | ||||||
|   } |   } | ||||||
|   setupConfigs(config, style); |   setupConfigs(config, style); | ||||||
|  |   setupConfig(); | ||||||
|  |   setupCss(); | ||||||
|   bindInterfaces(); |   bindInterfaces(); | ||||||
|   gtk_app->hold(); |   gtk_app->hold(); | ||||||
|   gtk_app->run(); |   gtk_app->run(); | ||||||
| @@ -147,7 +261,6 @@ int waybar::Client::main(int argc, char* argv[]) | |||||||
|   zwlr_layer_shell_v1_destroy(layer_shell); |   zwlr_layer_shell_v1_destroy(layer_shell); | ||||||
|   zwp_idle_inhibit_manager_v1_destroy(idle_inhibit_manager); |   zwp_idle_inhibit_manager_v1_destroy(idle_inhibit_manager); | ||||||
|   wl_registry_destroy(registry); |   wl_registry_destroy(registry); | ||||||
|   wl_seat_destroy(seat); |  | ||||||
|   wl_display_disconnect(wl_display); |   wl_display_disconnect(wl_display); | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,11 +1,8 @@ | |||||||
| #include "factory.hpp" | #include "factory.hpp" | ||||||
|  |  | ||||||
| waybar::Factory::Factory(const Bar& bar, const Json::Value& config) | waybar::Factory::Factory(const Bar& bar, const Json::Value& config) : bar_(bar), config_(config) {} | ||||||
|   : bar_(bar), config_(config) |  | ||||||
| {} |  | ||||||
|  |  | ||||||
| waybar::IModule* waybar::Factory::makeModule(const std::string &name) const | waybar::IModule* waybar::Factory::makeModule(const std::string& name) const { | ||||||
| { |  | ||||||
|   try { |   try { | ||||||
|     auto hash_pos = name.find("#"); |     auto hash_pos = name.find("#"); | ||||||
|     auto ref = name.substr(0, hash_pos); |     auto ref = name.substr(0, hash_pos); | ||||||
| @@ -13,7 +10,7 @@ waybar::IModule* waybar::Factory::makeModule(const std::string &name) const | |||||||
|     if (ref == "battery") { |     if (ref == "battery") { | ||||||
|       return new waybar::modules::Battery(id, config_[name]); |       return new waybar::modules::Battery(id, config_[name]); | ||||||
|     } |     } | ||||||
|     #ifdef HAVE_SWAY | #ifdef HAVE_SWAY | ||||||
|     if (ref == "sway/mode") { |     if (ref == "sway/mode") { | ||||||
|       return new waybar::modules::sway::Mode(id, bar_, config_[name]); |       return new waybar::modules::sway::Mode(id, bar_, config_[name]); | ||||||
|     } |     } | ||||||
| @@ -23,7 +20,7 @@ waybar::IModule* waybar::Factory::makeModule(const std::string &name) const | |||||||
|     if (ref == "sway/window") { |     if (ref == "sway/window") { | ||||||
|       return new waybar::modules::sway::Window(id, bar_, config_[name]); |       return new waybar::modules::sway::Window(id, bar_, config_[name]); | ||||||
|     } |     } | ||||||
|     #endif | #endif | ||||||
|     if (ref == "idle_inhibitor") { |     if (ref == "idle_inhibitor") { | ||||||
|       return new waybar::modules::IdleInhibitor(id, bar_, config_[name]); |       return new waybar::modules::IdleInhibitor(id, bar_, config_[name]); | ||||||
|     } |     } | ||||||
| @@ -36,31 +33,31 @@ waybar::IModule* waybar::Factory::makeModule(const std::string &name) const | |||||||
|     if (ref == "clock") { |     if (ref == "clock") { | ||||||
|       return new waybar::modules::Clock(id, config_[name]); |       return new waybar::modules::Clock(id, config_[name]); | ||||||
|     } |     } | ||||||
|     #ifdef HAVE_DBUSMENU | #ifdef HAVE_DBUSMENU | ||||||
|     if (ref == "tray") { |     if (ref == "tray") { | ||||||
|       return new waybar::modules::SNI::Tray(id, bar_, config_[name]); |       return new waybar::modules::SNI::Tray(id, bar_, config_[name]); | ||||||
|     } |     } | ||||||
|     #endif | #endif | ||||||
|     #ifdef HAVE_LIBNL | #ifdef HAVE_LIBNL | ||||||
|     if (ref == "network") { |     if (ref == "network") { | ||||||
|       return new waybar::modules::Network(id, config_[name]); |       return new waybar::modules::Network(id, config_[name]); | ||||||
|     } |     } | ||||||
|     #endif | #endif | ||||||
|     #ifdef HAVE_LIBUDEV | #ifdef HAVE_LIBUDEV | ||||||
|     if (ref == "backlight") { |     if (ref == "backlight") { | ||||||
|       return new waybar::modules::Backlight(id, config_[name]); |       return new waybar::modules::Backlight(id, config_[name]); | ||||||
|     } |     } | ||||||
|     #endif | #endif | ||||||
|     #ifdef HAVE_LIBPULSE | #ifdef HAVE_LIBPULSE | ||||||
|     if (ref == "pulseaudio") { |     if (ref == "pulseaudio") { | ||||||
|       return new waybar::modules::Pulseaudio(id, config_[name]); |       return new waybar::modules::Pulseaudio(id, config_[name]); | ||||||
|     } |     } | ||||||
|     #endif | #endif | ||||||
|     #ifdef HAVE_LIBMPDCLIENT | #ifdef HAVE_LIBMPDCLIENT | ||||||
|     if (ref == "mpd") { |     if (ref == "mpd") { | ||||||
|       return new waybar::modules::MPD(id, config_[name]); |       return new waybar::modules::MPD(id, config_[name]); | ||||||
|     } |     } | ||||||
|     #endif | #endif | ||||||
|     if (ref == "temperature") { |     if (ref == "temperature") { | ||||||
|       return new waybar::modules::Temperature(id, config_[name]); |       return new waybar::modules::Temperature(id, config_[name]); | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/main.cpp
									
									
									
									
									
								
							| @@ -2,31 +2,26 @@ | |||||||
| #include <iostream> | #include <iostream> | ||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
|  |  | ||||||
| namespace waybar { |  | ||||||
|  |  | ||||||
| static Client* client; |  | ||||||
|  |  | ||||||
| }  // namespace waybar |  | ||||||
|  |  | ||||||
| int main(int argc, char* argv[]) { | int main(int argc, char* argv[]) { | ||||||
|   try { |   try { | ||||||
|     waybar::Client c(argc, argv); |     auto client = waybar::Client::inst(); | ||||||
|     waybar::client = &c; |  | ||||||
|     std::signal(SIGUSR1, [](int /*signal*/) { |     std::signal(SIGUSR1, [](int /*signal*/) { | ||||||
|       for (auto& bar : waybar::client->bars) { |       for (auto& bar : waybar::Client::inst()->bars) { | ||||||
|         bar->toggle(); |         bar->toggle(); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     for (int sig = SIGRTMIN + 1; sig <= SIGRTMAX; ++sig) { |     for (int sig = SIGRTMIN + 1; sig <= SIGRTMAX; ++sig) { | ||||||
|       std::signal(sig, [](int sig /*signal*/) { |       std::signal(sig, [](int sig) { | ||||||
|         for (auto& bar : waybar::client->bars) { |         for (auto& bar : waybar::Client::inst()->bars) { | ||||||
|           bar->handleSignal(sig); |           bar->handleSignal(sig); | ||||||
|         } |         } | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return c.main(argc, argv); |     auto ret = client->main(argc, argv); | ||||||
|  |     delete client; | ||||||
|  |     return ret; | ||||||
|   } catch (const std::exception& e) { |   } catch (const std::exception& e) { | ||||||
|     std::cerr << e.what() << std::endl; |     std::cerr << e.what() << std::endl; | ||||||
|     return 1; |     return 1; | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ | |||||||
|  |  | ||||||
| namespace { | namespace { | ||||||
| class FileDescriptor { | class FileDescriptor { | ||||||
| public: |  public: | ||||||
|   explicit FileDescriptor(int fd) : fd_(fd) {} |   explicit FileDescriptor(int fd) : fd_(fd) {} | ||||||
|   FileDescriptor(const FileDescriptor &other) = delete; |   FileDescriptor(const FileDescriptor &other) = delete; | ||||||
|   FileDescriptor(FileDescriptor &&other) noexcept = delete; |   FileDescriptor(FileDescriptor &&other) noexcept = delete; | ||||||
| @@ -28,7 +28,7 @@ public: | |||||||
|   } |   } | ||||||
|   int get() const { return fd_; } |   int get() const { return fd_; } | ||||||
|  |  | ||||||
| private: |  private: | ||||||
|   int fd_; |   int fd_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -60,9 +60,7 @@ void check_neq(int rc, int bad_rc, const char *message = "neq, rc was: ") { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void check0(int rc, const char *message = "rc wasn't 0") { | void check0(int rc, const char *message = "rc wasn't 0") { check_eq(rc, 0, message); } | ||||||
|   check_eq(rc, 0, message); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void check_gte(int rc, int gte, const char *message = "rc was: ") { | void check_gte(int rc, int gte, const char *message = "rc was: ") { | ||||||
|   if (rc < gte) { |   if (rc < gte) { | ||||||
| @@ -75,41 +73,33 @@ void check_nn(const void *ptr, const char *message = "ptr was null") { | |||||||
|     throw std::runtime_error(message); |     throw std::runtime_error(message); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| } // namespace | }  // namespace | ||||||
|  |  | ||||||
| waybar::modules::Backlight::BacklightDev::BacklightDev(std::string name, | waybar::modules::Backlight::BacklightDev::BacklightDev(std::string name, int actual, int max) | ||||||
|                                                        int actual, int max) |  | ||||||
|     : name_(std::move(name)), actual_(actual), max_(max) {} |     : name_(std::move(name)), actual_(actual), max_(max) {} | ||||||
|  |  | ||||||
| std::string_view waybar::modules::Backlight::BacklightDev::name() const { | std::string_view waybar::modules::Backlight::BacklightDev::name() const { return name_; } | ||||||
|   return name_; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int waybar::modules::Backlight::BacklightDev::get_actual() const { | int waybar::modules::Backlight::BacklightDev::get_actual() const { return actual_; } | ||||||
|   return actual_; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void waybar::modules::Backlight::BacklightDev::set_actual(int actual) { | void waybar::modules::Backlight::BacklightDev::set_actual(int actual) { actual_ = actual; } | ||||||
|   actual_ = actual; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int waybar::modules::Backlight::BacklightDev::get_max() const { return max_; } | int waybar::modules::Backlight::BacklightDev::get_max() const { return max_; } | ||||||
|  |  | ||||||
| void waybar::modules::Backlight::BacklightDev::set_max(int max) { max_ = max; } | void waybar::modules::Backlight::BacklightDev::set_max(int max) { max_ = max; } | ||||||
|  |  | ||||||
| waybar::modules::Backlight::Backlight(const std::string &name, | waybar::modules::Backlight::Backlight(const std::string &name, const Json::Value &config) | ||||||
|                                       const Json::Value &config) |     : ALabel(config, "{percent}%", 2), | ||||||
|     : ALabel(config, "{percent}%", 2), name_(name), |       name_(name), | ||||||
|       preferred_device_( |       preferred_device_(config["device"].isString() ? config["device"].asString() : "") { | ||||||
|           config["device"].isString() ? config["device"].asString() : "") { |  | ||||||
|   label_.set_name("backlight"); |   label_.set_name("backlight"); | ||||||
|  |  | ||||||
|   // Get initial state |   // Get initial state | ||||||
|   { |   { | ||||||
|     std::unique_ptr<udev, UdevDeleter> udev_check{udev_new()}; |     std::unique_ptr<udev, UdevDeleter> udev_check{udev_new()}; | ||||||
|     check_nn(udev_check.get(), "Udev check new failed"); |     check_nn(udev_check.get(), "Udev check new failed"); | ||||||
|     enumerate_devices(devices_.begin(), devices_.end(), |     enumerate_devices( | ||||||
|                       std::back_inserter(devices_), udev_check.get()); |         devices_.begin(), devices_.end(), std::back_inserter(devices_), udev_check.get()); | ||||||
|     if (devices_.empty()) { |     if (devices_.empty()) { | ||||||
|       throw std::runtime_error("No backlight found"); |       throw std::runtime_error("No backlight found"); | ||||||
|     } |     } | ||||||
| @@ -123,9 +113,9 @@ waybar::modules::Backlight::Backlight(const std::string &name, | |||||||
|     std::unique_ptr<udev_monitor, UdevMonitorDeleter> mon{ |     std::unique_ptr<udev_monitor, UdevMonitorDeleter> mon{ | ||||||
|         udev_monitor_new_from_netlink(udev.get(), "udev")}; |         udev_monitor_new_from_netlink(udev.get(), "udev")}; | ||||||
|     check_nn(mon.get(), "udev monitor new failed"); |     check_nn(mon.get(), "udev monitor new failed"); | ||||||
|     check_gte(udev_monitor_filter_add_match_subsystem_devtype( |     check_gte(udev_monitor_filter_add_match_subsystem_devtype(mon.get(), "backlight", nullptr), | ||||||
|                   mon.get(), "backlight", nullptr), |               0, | ||||||
|               0, "udev failed to add monitor filter: "); |               "udev failed to add monitor filter: "); | ||||||
|     udev_monitor_enable_receiving(mon.get()); |     udev_monitor_enable_receiving(mon.get()); | ||||||
|  |  | ||||||
|     auto udev_fd = udev_monitor_get_fd(mon.get()); |     auto udev_fd = udev_monitor_get_fd(mon.get()); | ||||||
| @@ -136,15 +126,13 @@ waybar::modules::Backlight::Backlight(const std::string &name, | |||||||
|     ctl_event.events = EPOLLIN; |     ctl_event.events = EPOLLIN; | ||||||
|     ctl_event.data.fd = udev_fd; |     ctl_event.data.fd = udev_fd; | ||||||
|  |  | ||||||
|     check0( |     check0(epoll_ctl(epoll_fd.get(), EPOLL_CTL_ADD, ctl_event.data.fd, &ctl_event), | ||||||
|         epoll_ctl(epoll_fd.get(), EPOLL_CTL_ADD, ctl_event.data.fd, &ctl_event), |            "epoll_ctl failed: {}"); | ||||||
|         "epoll_ctl failed: {}"); |  | ||||||
|     epoll_event events[EPOLL_MAX_EVENTS]; |     epoll_event events[EPOLL_MAX_EVENTS]; | ||||||
|  |  | ||||||
|     while (udev_thread_.isRunning()) { |     while (udev_thread_.isRunning()) { | ||||||
|       const int event_count = |       const int event_count = epoll_wait( | ||||||
|           epoll_wait(epoll_fd.get(), events, EPOLL_MAX_EVENTS, |           epoll_fd.get(), events, EPOLL_MAX_EVENTS, std::chrono::milliseconds{interval_}.count()); | ||||||
|                      std::chrono::milliseconds{interval_}.count()); |  | ||||||
|       if (!udev_thread_.isRunning()) { |       if (!udev_thread_.isRunning()) { | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
| @@ -156,17 +144,14 @@ waybar::modules::Backlight::Backlight(const std::string &name, | |||||||
|       for (int i = 0; i < event_count; ++i) { |       for (int i = 0; i < event_count; ++i) { | ||||||
|         const auto &event = events[i]; |         const auto &event = events[i]; | ||||||
|         check_eq(event.data.fd, udev_fd, "unexpected udev fd"); |         check_eq(event.data.fd, udev_fd, "unexpected udev fd"); | ||||||
|         std::unique_ptr<udev_device, UdevDeviceDeleter> dev{ |         std::unique_ptr<udev_device, UdevDeviceDeleter> dev{udev_monitor_receive_device(mon.get())}; | ||||||
|             udev_monitor_receive_device(mon.get())}; |  | ||||||
|         check_nn(dev.get(), "epoll dev was null"); |         check_nn(dev.get(), "epoll dev was null"); | ||||||
|         upsert_device(devices.begin(), devices.end(), |         upsert_device(devices.begin(), devices.end(), std::back_inserter(devices), dev.get()); | ||||||
|                       std::back_inserter(devices), dev.get()); |  | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       // Refresh state if timed out |       // Refresh state if timed out | ||||||
|       if (event_count == 0) { |       if (event_count == 0) { | ||||||
|         enumerate_devices(devices.begin(), devices.end(), |         enumerate_devices(devices.begin(), devices.end(), std::back_inserter(devices), udev.get()); | ||||||
|                           std::back_inserter(devices), udev.get()); |  | ||||||
|       } |       } | ||||||
|       { |       { | ||||||
|         std::scoped_lock<std::mutex> lock(udev_thread_mutex_); |         std::scoped_lock<std::mutex> lock(udev_thread_mutex_); | ||||||
| @@ -186,19 +171,16 @@ auto waybar::modules::Backlight::update() -> void { | |||||||
|     devices = devices_; |     devices = devices_; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const auto best = |   const auto best = best_device(devices.cbegin(), devices.cend(), preferred_device_); | ||||||
|       best_device(devices.cbegin(), devices.cend(), preferred_device_); |  | ||||||
|   if (best != nullptr) { |   if (best != nullptr) { | ||||||
|     if (previous_best_.has_value() && previous_best_.value() == *best && |     if (previous_best_.has_value() && previous_best_.value() == *best && | ||||||
|         !previous_format_.empty() && previous_format_ == format_) { |         !previous_format_.empty() && previous_format_ == format_) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const auto percent = |     const auto percent = best->get_max() == 0 ? 100 : best->get_actual() * 100 / best->get_max(); | ||||||
|         best->get_max() == 0 ? 100 : best->get_actual() * 100 / best->get_max(); |     label_.set_markup(fmt::format( | ||||||
|     label_.set_markup(fmt::format(format_, |         format_, fmt::arg("percent", std::to_string(percent)), fmt::arg("icon", getIcon(percent)))); | ||||||
|                                   fmt::arg("percent", std::to_string(percent)), |  | ||||||
|                                   fmt::arg("icon", getIcon(percent)))); |  | ||||||
|   } else { |   } else { | ||||||
|     if (!previous_best_.has_value()) { |     if (!previous_best_.has_value()) { | ||||||
|       return; |       return; | ||||||
| @@ -210,28 +192,22 @@ auto waybar::modules::Backlight::update() -> void { | |||||||
| } | } | ||||||
|  |  | ||||||
| template <class ForwardIt> | template <class ForwardIt> | ||||||
| const waybar::modules::Backlight::BacklightDev * | const waybar::modules::Backlight::BacklightDev *waybar::modules::Backlight::best_device( | ||||||
| waybar::modules::Backlight::best_device(ForwardIt first, ForwardIt last, |     ForwardIt first, ForwardIt last, std::string_view preferred_device) { | ||||||
|                                         std::string_view preferred_device) { |   const auto found = std::find_if( | ||||||
|   const auto found = |       first, last, [preferred_device](const auto &dev) { return dev.name() == preferred_device; }); | ||||||
|       std::find_if(first, last, [preferred_device](const auto &dev) { |  | ||||||
|         return dev.name() == preferred_device; |  | ||||||
|       }); |  | ||||||
|   if (found != last) { |   if (found != last) { | ||||||
|     return &(*found); |     return &(*found); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const auto max = |   const auto max = std::max_element( | ||||||
|       std::max_element(first, last, [](const auto &l, const auto &r) { |       first, last, [](const auto &l, const auto &r) { return l.get_max() < r.get_max(); }); | ||||||
|         return l.get_max() < r.get_max(); |  | ||||||
|       }); |  | ||||||
|  |  | ||||||
|   return max == last ? nullptr : &(*max); |   return max == last ? nullptr : &(*max); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <class ForwardIt, class Inserter> | template <class ForwardIt, class Inserter> | ||||||
| void waybar::modules::Backlight::upsert_device(ForwardIt first, ForwardIt last, | void waybar::modules::Backlight::upsert_device(ForwardIt first, ForwardIt last, Inserter inserter, | ||||||
|                                                Inserter inserter, |  | ||||||
|                                                udev_device *dev) { |                                                udev_device *dev) { | ||||||
|   const char *name = udev_device_get_sysname(dev); |   const char *name = udev_device_get_sysname(dev); | ||||||
|   check_nn(name); |   check_nn(name); | ||||||
| @@ -244,9 +220,8 @@ void waybar::modules::Backlight::upsert_device(ForwardIt first, ForwardIt last, | |||||||
|   check_nn(max); |   check_nn(max); | ||||||
|   const int max_int = std::stoi(max); |   const int max_int = std::stoi(max); | ||||||
|  |  | ||||||
|   auto found = std::find_if(first, last, [name](const auto &device) { |   auto found = | ||||||
|     return device.name() == name; |       std::find_if(first, last, [name](const auto &device) { return device.name() == name; }); | ||||||
|   }); |  | ||||||
|   if (found != last) { |   if (found != last) { | ||||||
|     found->set_actual(actual_int); |     found->set_actual(actual_int); | ||||||
|     found->set_max(max_int); |     found->set_max(max_int); | ||||||
| @@ -257,21 +232,16 @@ void waybar::modules::Backlight::upsert_device(ForwardIt first, ForwardIt last, | |||||||
| } | } | ||||||
|  |  | ||||||
| template <class ForwardIt, class Inserter> | template <class ForwardIt, class Inserter> | ||||||
| void waybar::modules::Backlight::enumerate_devices(ForwardIt first, | void waybar::modules::Backlight::enumerate_devices(ForwardIt first, ForwardIt last, | ||||||
|                                                    ForwardIt last, |                                                    Inserter inserter, udev *udev) { | ||||||
|                                                    Inserter inserter, |   std::unique_ptr<udev_enumerate, UdevEnumerateDeleter> enumerate{udev_enumerate_new(udev)}; | ||||||
|                                                    udev *udev) { |  | ||||||
|   std::unique_ptr<udev_enumerate, UdevEnumerateDeleter> enumerate{ |  | ||||||
|       udev_enumerate_new(udev)}; |  | ||||||
|   udev_enumerate_add_match_subsystem(enumerate.get(), "backlight"); |   udev_enumerate_add_match_subsystem(enumerate.get(), "backlight"); | ||||||
|   udev_enumerate_scan_devices(enumerate.get()); |   udev_enumerate_scan_devices(enumerate.get()); | ||||||
|   udev_list_entry *enum_devices = |   udev_list_entry *enum_devices = udev_enumerate_get_list_entry(enumerate.get()); | ||||||
|       udev_enumerate_get_list_entry(enumerate.get()); |  | ||||||
|   udev_list_entry *dev_list_entry; |   udev_list_entry *dev_list_entry; | ||||||
|   udev_list_entry_foreach(dev_list_entry, enum_devices) { |   udev_list_entry_foreach(dev_list_entry, enum_devices) { | ||||||
|     const char *path = udev_list_entry_get_name(dev_list_entry); |     const char *                                    path = udev_list_entry_get_name(dev_list_entry); | ||||||
|     std::unique_ptr<udev_device, UdevDeviceDeleter> dev{ |     std::unique_ptr<udev_device, UdevDeviceDeleter> dev{udev_device_new_from_syspath(udev, path)}; | ||||||
|         udev_device_new_from_syspath(udev, path)}; |  | ||||||
|     check_nn(dev.get(), "dev new failed"); |     check_nn(dev.get(), "dev new failed"); | ||||||
|     upsert_device(first, last, inserter, dev.get()); |     upsert_device(first, last, inserter, dev.get()); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| #include "modules/battery.hpp" | #include "modules/battery.hpp" | ||||||
|  |  | ||||||
| waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config) | waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config) | ||||||
|   : ALabel(config, "{capacity}%", 60) |     : ALabel(config, "{capacity}%", 60) { | ||||||
| { |  | ||||||
|   label_.set_name("battery"); |   label_.set_name("battery"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
| @@ -21,23 +20,21 @@ waybar::modules::Battery::Battery(const std::string& id, const Json::Value& conf | |||||||
|   worker(); |   worker(); | ||||||
| } | } | ||||||
|  |  | ||||||
| waybar::modules::Battery::~Battery() | waybar::modules::Battery::~Battery() { | ||||||
| { |  | ||||||
|   for (auto wd : wds_) { |   for (auto wd : wds_) { | ||||||
|     inotify_rm_watch(fd_, wd); |     inotify_rm_watch(fd_, wd); | ||||||
|   } |   } | ||||||
|   close(fd_); |   close(fd_); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Battery::worker() | void waybar::modules::Battery::worker() { | ||||||
| { |  | ||||||
|   thread_timer_ = [this] { |   thread_timer_ = [this] { | ||||||
|     dp.emit(); |     dp.emit(); | ||||||
|     thread_timer_.sleep_for(interval_); |     thread_timer_.sleep_for(interval_); | ||||||
|   }; |   }; | ||||||
|   thread_ = [this] { |   thread_ = [this] { | ||||||
|     struct inotify_event event = {0}; |     struct inotify_event event = {0}; | ||||||
|     int nbytes = read(fd_, &event, sizeof(event)); |     int                  nbytes = read(fd_, &event, sizeof(event)); | ||||||
|     if (nbytes != sizeof(event) || event.mask & IN_IGNORED) { |     if (nbytes != sizeof(event) || event.mask & IN_IGNORED) { | ||||||
|       thread_.stop(); |       thread_.stop(); | ||||||
|       return; |       return; | ||||||
| @@ -48,8 +45,7 @@ void waybar::modules::Battery::worker() | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Battery::getBatteries() | void waybar::modules::Battery::getBatteries() { | ||||||
| { |  | ||||||
|   try { |   try { | ||||||
|     for (auto const& node : fs::directory_iterator(data_dir_)) { |     for (auto const& node : fs::directory_iterator(data_dir_)) { | ||||||
|       if (!fs::is_directory(node)) { |       if (!fs::is_directory(node)) { | ||||||
| @@ -57,18 +53,18 @@ void waybar::modules::Battery::getBatteries() | |||||||
|       } |       } | ||||||
|       auto dir_name = node.path().filename(); |       auto dir_name = node.path().filename(); | ||||||
|       auto bat_defined = config_["bat"].isString(); |       auto bat_defined = config_["bat"].isString(); | ||||||
|       if (((bat_defined && dir_name == config_["bat"].asString()) |       if (((bat_defined && dir_name == config_["bat"].asString()) || !bat_defined) && | ||||||
|         || !bat_defined) && fs::exists(node / "capacity") |           fs::exists(node / "capacity") && fs::exists(node / "uevent") && | ||||||
|         && fs::exists(node / "uevent") && fs::exists(node / "status")) { |           fs::exists(node / "status")) { | ||||||
|           batteries_.push_back(node); |         batteries_.push_back(node); | ||||||
|       } |       } | ||||||
|       auto adap_defined = config_["adapter"].isString(); |       auto adap_defined = config_["adapter"].isString(); | ||||||
|       if (((adap_defined && dir_name == config_["adapter"].asString()) |       if (((adap_defined && dir_name == config_["adapter"].asString()) || !adap_defined) && | ||||||
|         || !adap_defined) && fs::exists(node / "online")) { |           fs::exists(node / "online")) { | ||||||
|           adapter_ = node; |         adapter_ = node; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } catch (fs::filesystem_error &e) { |   } catch (fs::filesystem_error& e) { | ||||||
|     throw std::runtime_error(e.what()); |     throw std::runtime_error(e.what()); | ||||||
|   } |   } | ||||||
|   if (batteries_.empty()) { |   if (batteries_.empty()) { | ||||||
| @@ -79,13 +75,12 @@ void waybar::modules::Battery::getBatteries() | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| const std::tuple<uint8_t, std::string> waybar::modules::Battery::getInfos() const | const std::tuple<uint8_t, std::string> waybar::modules::Battery::getInfos() const { | ||||||
| { |  | ||||||
|   try { |   try { | ||||||
|     uint16_t total = 0; |     uint16_t    total = 0; | ||||||
|     std::string status = "Unknown"; |     std::string status = "Unknown"; | ||||||
|     for (auto const& bat : batteries_) { |     for (auto const& bat : batteries_) { | ||||||
|       uint16_t capacity; |       uint16_t    capacity; | ||||||
|       std::string _status; |       std::string _status; | ||||||
|       std::ifstream(bat / "capacity") >> capacity; |       std::ifstream(bat / "capacity") >> capacity; | ||||||
|       std::ifstream(bat / "status") >> _status; |       std::ifstream(bat / "status") >> _status; | ||||||
| @@ -102,8 +97,7 @@ const std::tuple<uint8_t, std::string> waybar::modules::Battery::getInfos() cons | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity) const | const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity) const { | ||||||
| { |  | ||||||
|   if (!adapter_.empty()) { |   if (!adapter_.empty()) { | ||||||
|     bool online; |     bool online; | ||||||
|     std::ifstream(adapter_ / "online") >> online; |     std::ifstream(adapter_ / "online") >> online; | ||||||
| @@ -115,8 +109,7 @@ const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity) c | |||||||
|   return "Unknown"; |   return "Unknown"; | ||||||
| } | } | ||||||
|  |  | ||||||
| const std::string waybar::modules::Battery::getState(uint8_t capacity) const | const std::string waybar::modules::Battery::getState(uint8_t capacity) const { | ||||||
| { |  | ||||||
|   // Get current state |   // Get current state | ||||||
|   std::vector<std::pair<std::string, uint8_t>> states; |   std::vector<std::pair<std::string, uint8_t>> states; | ||||||
|   if (config_["states"].isObject()) { |   if (config_["states"].isObject()) { | ||||||
| @@ -127,9 +120,7 @@ const std::string waybar::modules::Battery::getState(uint8_t capacity) const | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   // Sort states |   // Sort states | ||||||
|   std::sort(states.begin(), states.end(), [](auto &a, auto &b) { |   std::sort(states.begin(), states.end(), [](auto& a, auto& b) { return a.second < b.second; }); | ||||||
|     return a.second < b.second; |  | ||||||
|   }); |  | ||||||
|   std::string valid_state; |   std::string valid_state; | ||||||
|   for (auto const& state : states) { |   for (auto const& state : states) { | ||||||
|     if (capacity <= state.second && valid_state.empty()) { |     if (capacity <= state.second && valid_state.empty()) { | ||||||
| @@ -142,8 +133,7 @@ const std::string waybar::modules::Battery::getState(uint8_t capacity) const | |||||||
|   return valid_state; |   return valid_state; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Battery::update() -> void | auto waybar::modules::Battery::update() -> void { | ||||||
| { |  | ||||||
|   auto [capacity, status] = getInfos(); |   auto [capacity, status] = getInfos(); | ||||||
|   if (status == "Unknown") { |   if (status == "Unknown") { | ||||||
|     status = getAdapterStatus(capacity); |     status = getAdapterStatus(capacity); | ||||||
| @@ -168,7 +158,7 @@ auto waybar::modules::Battery::update() -> void | |||||||
|     event_box_.hide(); |     event_box_.hide(); | ||||||
|   } else { |   } else { | ||||||
|     event_box_.show(); |     event_box_.show(); | ||||||
|     label_.set_markup(fmt::format(format, fmt::arg("capacity", capacity), |     label_.set_markup( | ||||||
|       fmt::arg("icon", getIcon(capacity)))); |         fmt::format(format, fmt::arg("capacity", capacity), fmt::arg("icon", getIcon(capacity)))); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| #include "modules/clock.hpp" | #include "modules/clock.hpp" | ||||||
|  |  | ||||||
| waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) | waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) | ||||||
|   : ALabel(config, "{:%H:%M}", 60) |     : ALabel(config, "{:%H:%M}", 60) { | ||||||
| { |  | ||||||
|   label_.set_name("clock"); |   label_.set_name("clock"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
| @@ -13,18 +12,20 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) | |||||||
|     auto timeout = std::chrono::floor<std::chrono::seconds>(now + interval_); |     auto timeout = std::chrono::floor<std::chrono::seconds>(now + interval_); | ||||||
|     auto time_s = std::chrono::time_point_cast<std::chrono::seconds>(timeout); |     auto time_s = std::chrono::time_point_cast<std::chrono::seconds>(timeout); | ||||||
|     auto sub_m = |     auto sub_m = | ||||||
|       std::chrono::duration_cast<std::chrono::seconds>(time_s.time_since_epoch()).count() % interval_.count(); |         std::chrono::duration_cast<std::chrono::seconds>(time_s.time_since_epoch()).count() % | ||||||
|     if (sub_m > 0) thread_.sleep_until(timeout - std::chrono::seconds(sub_m - 1)); |         interval_.count(); | ||||||
|     else thread_.sleep_until(timeout - std::chrono::seconds(sub_m)); |     if (sub_m > 0) | ||||||
|  |       thread_.sleep_until(timeout - std::chrono::seconds(sub_m - 1)); | ||||||
|  |     else | ||||||
|  |       thread_.sleep_until(timeout - std::chrono::seconds(sub_m)); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Clock::update() -> void | auto waybar::modules::Clock::update() -> void { | ||||||
| { |  | ||||||
|   auto localtime = fmt::localtime(std::time(nullptr)); |   auto localtime = fmt::localtime(std::time(nullptr)); | ||||||
|   auto text = fmt::format(format_, localtime); |   auto text = fmt::format(format_, localtime); | ||||||
|   label_.set_markup(text); |   label_.set_markup(text); | ||||||
|    |  | ||||||
|   if (tooltipEnabled()) { |   if (tooltipEnabled()) { | ||||||
|     if (config_["tooltip-format"].isString()) { |     if (config_["tooltip-format"].isString()) { | ||||||
|       auto tooltip_format = config_["tooltip-format"].asString(); |       auto tooltip_format = config_["tooltip-format"].asString(); | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| #include "modules/cpu.hpp" | #include "modules/cpu.hpp" | ||||||
|  |  | ||||||
| waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config) | waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config) | ||||||
|   : ALabel(config, "{usage}%", 10) |     : ALabel(config, "{usage}%", 10) { | ||||||
| { |  | ||||||
|   label_.set_name("cpu"); |   label_.set_name("cpu"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
| @@ -13,44 +12,40 @@ waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config) | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Cpu::update() -> void | auto waybar::modules::Cpu::update() -> void { | ||||||
| { |  | ||||||
|   // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both |   // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both | ||||||
|   auto cpu_load = getCpuLoad(); |   auto cpu_load = getCpuLoad(); | ||||||
|   auto [cpu_usage, tooltip] = getCpuUsage(); |   auto [cpu_usage, tooltip] = getCpuUsage(); | ||||||
|   if (tooltipEnabled()) { |   if (tooltipEnabled()) { | ||||||
|     label_.set_tooltip_text(tooltip); |     label_.set_tooltip_text(tooltip); | ||||||
|   } |   } | ||||||
|   label_.set_markup(fmt::format(format_, |   label_.set_markup(fmt::format(format_, fmt::arg("load", cpu_load), fmt::arg("usage", cpu_usage))); | ||||||
|     fmt::arg("load", cpu_load), fmt::arg("usage", cpu_usage))); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| uint16_t waybar::modules::Cpu::getCpuLoad() | uint16_t waybar::modules::Cpu::getCpuLoad() { | ||||||
| { |  | ||||||
|   struct sysinfo info = {0}; |   struct sysinfo info = {0}; | ||||||
|   if (sysinfo(&info) == 0) { |   if (sysinfo(&info) == 0) { | ||||||
|     float f_load = 1.f / (1u << SI_LOAD_SHIFT); |     float    f_load = 1.f / (1u << SI_LOAD_SHIFT); | ||||||
|     uint16_t load = info.loads[0] * f_load * 100 / get_nprocs(); |     uint16_t load = info.loads[0] * f_load * 100 / get_nprocs(); | ||||||
|     return load; |     return load; | ||||||
|   } |   } | ||||||
|   throw std::runtime_error("Can't get Cpu load"); |   throw std::runtime_error("Can't get Cpu load"); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::tuple<uint16_t, std::string> waybar::modules::Cpu::getCpuUsage() | std::tuple<uint16_t, std::string> waybar::modules::Cpu::getCpuUsage() { | ||||||
| { |  | ||||||
|   if (prev_times_.empty()) { |   if (prev_times_.empty()) { | ||||||
|     prev_times_ = parseCpuinfo(); |     prev_times_ = parseCpuinfo(); | ||||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(100)); |     std::this_thread::sleep_for(std::chrono::milliseconds(100)); | ||||||
|   } |   } | ||||||
|   std::vector<std::tuple<size_t, size_t>> curr_times = parseCpuinfo(); |   std::vector<std::tuple<size_t, size_t>> curr_times = parseCpuinfo(); | ||||||
|   std::string tooltip; |   std::string                             tooltip; | ||||||
|   uint16_t usage = 0; |   uint16_t                                usage = 0; | ||||||
|   for (size_t i = 0; i < curr_times.size(); ++i) { |   for (size_t i = 0; i < curr_times.size(); ++i) { | ||||||
|     auto [curr_idle, curr_total] = curr_times[i]; |     auto [curr_idle, curr_total] = curr_times[i]; | ||||||
|     auto [prev_idle, prev_total] = prev_times_[i]; |     auto [prev_idle, prev_total] = prev_times_[i]; | ||||||
|     const float delta_idle = curr_idle - prev_idle; |     const float delta_idle = curr_idle - prev_idle; | ||||||
|     const float delta_total = curr_total - prev_total; |     const float delta_total = curr_total - prev_total; | ||||||
|     uint16_t tmp = 100 * (1 - delta_idle / delta_total); |     uint16_t    tmp = 100 * (1 - delta_idle / delta_total); | ||||||
|     if (i == 0) { |     if (i == 0) { | ||||||
|       usage = tmp; |       usage = tmp; | ||||||
|       tooltip = fmt::format("Total: {}%", tmp); |       tooltip = fmt::format("Total: {}%", tmp); | ||||||
| @@ -62,21 +57,21 @@ std::tuple<uint16_t, std::string> waybar::modules::Cpu::getCpuUsage() | |||||||
|   return {usage, tooltip}; |   return {usage, tooltip}; | ||||||
| } | } | ||||||
|  |  | ||||||
| std::vector<std::tuple<size_t, size_t>> waybar::modules::Cpu::parseCpuinfo() | std::vector<std::tuple<size_t, size_t>> waybar::modules::Cpu::parseCpuinfo() { | ||||||
| { |  | ||||||
|   std::ifstream info(data_dir_); |   std::ifstream info(data_dir_); | ||||||
|   if (!info.is_open()) { |   if (!info.is_open()) { | ||||||
|     throw std::runtime_error("Can't open " + data_dir_); |     throw std::runtime_error("Can't open " + data_dir_); | ||||||
|   } |   } | ||||||
|   std::vector< std::tuple<size_t, size_t> > cpuinfo; |   std::vector<std::tuple<size_t, size_t>> cpuinfo; | ||||||
|   std::string line; |   std::string                             line; | ||||||
|   while (getline(info, line)) {     |   while (getline(info, line)) { | ||||||
|     if (line.substr(0,3).compare("cpu") != 0) { |     if (line.substr(0, 3).compare("cpu") != 0) { | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|     std::stringstream sline(line.substr(5)); |     std::stringstream   sline(line.substr(5)); | ||||||
|     std::vector<size_t> times; |     std::vector<size_t> times; | ||||||
|     for (size_t time; sline >> time; times.push_back(time)); |     for (size_t time; sline >> time; times.push_back(time)) | ||||||
|  |       ; | ||||||
|  |  | ||||||
|     size_t idle_time = 0; |     size_t idle_time = 0; | ||||||
|     size_t total_time = 0; |     size_t total_time = 0; | ||||||
|   | |||||||
| @@ -1,9 +1,7 @@ | |||||||
| #include "modules/custom.hpp" | #include "modules/custom.hpp" | ||||||
|  |  | ||||||
| waybar::modules::Custom::Custom(const std::string& name, | waybar::modules::Custom::Custom(const std::string& name, const Json::Value& config) | ||||||
|   const Json::Value& config) |     : ALabel(config, "{}"), name_(name), fp_(nullptr) { | ||||||
|   : ALabel(config, "{}"), name_(name), fp_(nullptr) |  | ||||||
| { |  | ||||||
|   label_.set_name("custom-" + name_); |   label_.set_name("custom-" + name_); | ||||||
|   if (config_["exec"].isString()) { |   if (config_["exec"].isString()) { | ||||||
|     if (interval_.count() > 0) { |     if (interval_.count() > 0) { | ||||||
| @@ -15,16 +13,14 @@ waybar::modules::Custom::Custom(const std::string& name, | |||||||
|   dp.emit(); |   dp.emit(); | ||||||
| } | } | ||||||
|  |  | ||||||
| waybar::modules::Custom::~Custom() | waybar::modules::Custom::~Custom() { | ||||||
| { |  | ||||||
|   if (fp_) { |   if (fp_) { | ||||||
|     pclose(fp_); |     pclose(fp_); | ||||||
|     fp_ = nullptr; |     fp_ = nullptr; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Custom::delayWorker() | void waybar::modules::Custom::delayWorker() { | ||||||
| { |  | ||||||
|   thread_ = [this] { |   thread_ = [this] { | ||||||
|     bool can_update = true; |     bool can_update = true; | ||||||
|     if (config_["exec-if"].isString()) { |     if (config_["exec-if"].isString()) { | ||||||
| @@ -42,15 +38,14 @@ void waybar::modules::Custom::delayWorker() | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Custom::continuousWorker() | void waybar::modules::Custom::continuousWorker() { | ||||||
| { |  | ||||||
|   auto cmd = config_["exec"].asString(); |   auto cmd = config_["exec"].asString(); | ||||||
|   fp_ = popen(cmd.c_str(), "r"); |   fp_ = popen(cmd.c_str(), "r"); | ||||||
|   if (!fp_) { |   if (!fp_) { | ||||||
|     throw std::runtime_error("Unable to open " + cmd); |     throw std::runtime_error("Unable to open " + cmd); | ||||||
|   } |   } | ||||||
|   thread_ = [this] { |   thread_ = [this] { | ||||||
|     char* buff = nullptr; |     char*  buff = nullptr; | ||||||
|     size_t len = 0; |     size_t len = 0; | ||||||
|     if (getline(&buff, &len, fp_) == -1) { |     if (getline(&buff, &len, fp_) == -1) { | ||||||
|       int exit_code = 1; |       int exit_code = 1; | ||||||
| @@ -60,7 +55,7 @@ void waybar::modules::Custom::continuousWorker() | |||||||
|       } |       } | ||||||
|       thread_.stop(); |       thread_.stop(); | ||||||
|       if (exit_code != 0) { |       if (exit_code != 0) { | ||||||
|         output_ = { exit_code, "" }; |         output_ = {exit_code, ""}; | ||||||
|         dp.emit(); |         dp.emit(); | ||||||
|         std::cerr << name_ + " just stopped unexpectedly, is it endless?" << std::endl; |         std::cerr << name_ + " just stopped unexpectedly, is it endless?" << std::endl; | ||||||
|       } |       } | ||||||
| @@ -69,23 +64,21 @@ void waybar::modules::Custom::continuousWorker() | |||||||
|     std::string output = buff; |     std::string output = buff; | ||||||
|  |  | ||||||
|     // Remove last newline |     // Remove last newline | ||||||
|     if (!output.empty() && output[output.length()-1] == '\n') { |     if (!output.empty() && output[output.length() - 1] == '\n') { | ||||||
|       output.erase(output.length()-1); |       output.erase(output.length() - 1); | ||||||
|     } |     } | ||||||
|     output_ = { 0, output }; |     output_ = {0, output}; | ||||||
|     dp.emit(); |     dp.emit(); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Custom::refresh(int sig /*signal*/) | void waybar::modules::Custom::refresh(int sig /*signal*/) { | ||||||
| { |   if (sig == SIGRTMIN + config_["signal"].asInt()) { | ||||||
|   if(sig == SIGRTMIN + config_["signal"].asInt()) { |  | ||||||
|     thread_.wake_up(); |     thread_.wake_up(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Custom::update() -> void | auto waybar::modules::Custom::update() -> void { | ||||||
| { |  | ||||||
|   // Hide label if output is empty |   // Hide label if output is empty | ||||||
|   if (config_["exec"].isString() && (output_.out.empty() || output_.exit_code != 0)) { |   if (config_["exec"].isString() && (output_.out.empty() || output_.exit_code != 0)) { | ||||||
|     event_box_.hide(); |     event_box_.hide(); | ||||||
| @@ -96,10 +89,11 @@ auto waybar::modules::Custom::update() -> void | |||||||
|       parseOutputRaw(); |       parseOutputRaw(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     auto str = fmt::format(format_, text_, |     auto str = fmt::format(format_, | ||||||
|       fmt::arg("alt", alt_), |                            text_, | ||||||
|       fmt::arg("icon", getIcon(percentage_, alt_)), |                            fmt::arg("alt", alt_), | ||||||
|       fmt::arg("percentage", percentage_)); |                            fmt::arg("icon", getIcon(percentage_, alt_)), | ||||||
|  |                            fmt::arg("percentage", percentage_)); | ||||||
|     label_.set_markup(str); |     label_.set_markup(str); | ||||||
|     if (tooltipEnabled()) { |     if (tooltipEnabled()) { | ||||||
|       if (text_ == tooltip_) { |       if (text_ == tooltip_) { | ||||||
| @@ -109,10 +103,10 @@ auto waybar::modules::Custom::update() -> void | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     auto classes = label_.get_style_context()->list_classes(); |     auto classes = label_.get_style_context()->list_classes(); | ||||||
|     for (auto const &c : classes) { |     for (auto const& c : classes) { | ||||||
|       label_.get_style_context()->remove_class(c); |       label_.get_style_context()->remove_class(c); | ||||||
|     } |     } | ||||||
|     for (auto const &c : class_) { |     for (auto const& c : class_) { | ||||||
|       label_.get_style_context()->add_class(c); |       label_.get_style_context()->add_class(c); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -120,11 +114,10 @@ auto waybar::modules::Custom::update() -> void | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Custom::parseOutputRaw() | void waybar::modules::Custom::parseOutputRaw() { | ||||||
| { |  | ||||||
|   std::istringstream output(output_.out); |   std::istringstream output(output_.out); | ||||||
|   std::string line; |   std::string        line; | ||||||
|   int i = 0; |   int                i = 0; | ||||||
|   while (getline(output, line)) { |   while (getline(output, line)) { | ||||||
|     if (i == 0) { |     if (i == 0) { | ||||||
|       if (config_["escape"].isBool() && config_["escape"].asBool()) { |       if (config_["escape"].isBool() && config_["escape"].asBool()) { | ||||||
| @@ -145,10 +138,9 @@ void waybar::modules::Custom::parseOutputRaw() | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Custom::parseOutputJson() | void waybar::modules::Custom::parseOutputJson() { | ||||||
| { |  | ||||||
|   std::istringstream output(output_.out); |   std::istringstream output(output_.out); | ||||||
|   std::string line; |   std::string        line; | ||||||
|   class_.clear(); |   class_.clear(); | ||||||
|   while (getline(output, line)) { |   while (getline(output, line)) { | ||||||
|     auto parsed = parser_.parse(line); |     auto parsed = parser_.parse(line); | ||||||
| @@ -166,7 +158,7 @@ void waybar::modules::Custom::parseOutputJson() | |||||||
|     if (parsed["class"].isString()) { |     if (parsed["class"].isString()) { | ||||||
|       class_.push_back(parsed["class"].asString()); |       class_.push_back(parsed["class"].asString()); | ||||||
|     } else if (parsed["class"].isArray()) { |     } else if (parsed["class"].isArray()) { | ||||||
|       for (auto const &c : parsed["class"]) { |       for (auto const& c : parsed["class"]) { | ||||||
|         class_.push_back(c.asString()); |         class_.push_back(c.asString()); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| #include "modules/idle_inhibitor.hpp" | #include "modules/idle_inhibitor.hpp" | ||||||
| #include "util/command.hpp" | #include "util/command.hpp" | ||||||
|  |  | ||||||
| waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, const Json::Value& config) | waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, | ||||||
|   : ALabel(config, "{status}"), bar_(bar), status_("deactivated"), idle_inhibitor_(nullptr) |                                               const Json::Value& config) | ||||||
| { |     : ALabel(config, "{status}"), bar_(bar), status_("deactivated"), idle_inhibitor_(nullptr) { | ||||||
|   label_.set_name("idle_inhibitor"); |   label_.set_name("idle_inhibitor"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
| @@ -14,21 +14,18 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& | |||||||
|   dp.emit(); |   dp.emit(); | ||||||
| } | } | ||||||
|  |  | ||||||
| waybar::modules::IdleInhibitor::~IdleInhibitor() | waybar::modules::IdleInhibitor::~IdleInhibitor() { | ||||||
| { |   if (idle_inhibitor_) { | ||||||
|   if(idle_inhibitor_) { |  | ||||||
|     zwp_idle_inhibitor_v1_destroy(idle_inhibitor_); |     zwp_idle_inhibitor_v1_destroy(idle_inhibitor_); | ||||||
|     idle_inhibitor_ = nullptr; |     idle_inhibitor_ = nullptr; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::IdleInhibitor::update() -> void | auto waybar::modules::IdleInhibitor::update() -> void { | ||||||
| { |  | ||||||
|   label_.set_markup( |   label_.set_markup( | ||||||
|       fmt::format(format_, fmt::arg("status", status_), |       fmt::format(format_, fmt::arg("status", status_), fmt::arg("icon", getIcon(0, status_)))); | ||||||
|                   fmt::arg("icon", getIcon(0, status_)))); |  | ||||||
|   label_.get_style_context()->add_class(status_); |   label_.get_style_context()->add_class(status_); | ||||||
|   if(tooltipEnabled()) { |   if (tooltipEnabled()) { | ||||||
|     label_.set_tooltip_text(status_); |     label_.set_tooltip_text(status_); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -42,7 +39,7 @@ bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) { | |||||||
|       status_ = "deactivated"; |       status_ = "deactivated"; | ||||||
|     } else { |     } else { | ||||||
|       idle_inhibitor_ = zwp_idle_inhibit_manager_v1_create_inhibitor( |       idle_inhibitor_ = zwp_idle_inhibit_manager_v1_create_inhibitor( | ||||||
|           bar_.client.idle_inhibit_manager, bar_.surface); |           waybar::Client::inst()->idle_inhibit_manager, bar_.surface); | ||||||
|       status_ = "activated"; |       status_ = "activated"; | ||||||
|     } |     } | ||||||
|     if (config_["on-click"].isString() && e->button == 1) { |     if (config_["on-click"].isString() && e->button == 1) { | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| #include "modules/memory.hpp" | #include "modules/memory.hpp" | ||||||
|  |  | ||||||
| waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config) | waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config) | ||||||
|   : ALabel(config, "{}%", 30) |     : ALabel(config, "{}%", 30) { | ||||||
| { |  | ||||||
|   label_.set_name("memory"); |   label_.set_name("memory"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
| @@ -13,8 +12,7 @@ waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Memory::update() -> void | auto waybar::modules::Memory::update() -> void { | ||||||
| { |  | ||||||
|   parseMeminfo(); |   parseMeminfo(); | ||||||
|   if (memtotal_ > 0 && memfree_ >= 0) { |   if (memtotal_ > 0 && memfree_ >= 0) { | ||||||
|     int used_ram_percentage = 100 * (memtotal_ - memfree_) / memtotal_; |     int used_ram_percentage = 100 * (memtotal_ - memfree_) / memtotal_; | ||||||
| @@ -29,9 +27,8 @@ auto waybar::modules::Memory::update() -> void | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Memory::parseMeminfo() | void waybar::modules::Memory::parseMeminfo() { | ||||||
| { |   long          memfree = -1, membuffer = -1, memcache = -1, memavail = -1; | ||||||
|   long memfree = -1, membuffer = -1, memcache = -1, memavail = -1; |  | ||||||
|   std::ifstream info(data_dir_); |   std::ifstream info(data_dir_); | ||||||
|   if (!info.is_open()) { |   if (!info.is_open()) { | ||||||
|     throw std::runtime_error("Can't open " + data_dir_); |     throw std::runtime_error("Can't open " + data_dir_); | ||||||
| @@ -43,7 +40,7 @@ void waybar::modules::Memory::parseMeminfo() | |||||||
|       continue; |       continue; | ||||||
|     } |     } | ||||||
|     std::string name = line.substr(0, posDelim); |     std::string name = line.substr(0, posDelim); | ||||||
|     long value = std::stol(line.substr(posDelim + 1)); |     long        value = std::stol(line.substr(posDelim + 1)); | ||||||
|  |  | ||||||
|     if (name.compare("MemTotal") == 0) { |     if (name.compare("MemTotal") == 0) { | ||||||
|       memtotal_ = value; |       memtotal_ = value; | ||||||
| @@ -56,8 +53,7 @@ void waybar::modules::Memory::parseMeminfo() | |||||||
|     } else if (name.compare("Cached") == 0) { |     } else if (name.compare("Cached") == 0) { | ||||||
|       memcache = value; |       memcache = value; | ||||||
|     } |     } | ||||||
|     if (memtotal_ > 0 && |     if (memtotal_ > 0 && (memavail >= 0 || (memfree > -1 && membuffer > -1 && memcache > -1))) { | ||||||
|       (memavail >= 0 || (memfree > -1  && membuffer > -1 && memcache > -1))) { |  | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,10 +1,14 @@ | |||||||
| #include <sys/eventfd.h> |  | ||||||
| #include "modules/network.hpp" | #include "modules/network.hpp" | ||||||
|  | #include <sys/eventfd.h> | ||||||
|  |  | ||||||
| waybar::modules::Network::Network(const std::string& id, const Json::Value& config) | waybar::modules::Network::Network(const std::string &id, const Json::Value &config) | ||||||
|   : ALabel(config, "{ifname}", 60), family_(AF_INET), efd_(-1), ev_fd_(-1), |     : ALabel(config, "{ifname}", 60), | ||||||
|     cidr_(-1), signal_strength_dbm_(0), signal_strength_(0) |       family_(AF_INET), | ||||||
| { |       efd_(-1), | ||||||
|  |       ev_fd_(-1), | ||||||
|  |       cidr_(-1), | ||||||
|  |       signal_strength_dbm_(0), | ||||||
|  |       signal_strength_(0) { | ||||||
|   label_.set_name("network"); |   label_.set_name("network"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
| @@ -29,8 +33,7 @@ waybar::modules::Network::Network(const std::string& id, const Json::Value& conf | |||||||
|   worker(); |   worker(); | ||||||
| } | } | ||||||
|  |  | ||||||
| waybar::modules::Network::~Network() | waybar::modules::Network::~Network() { | ||||||
| { |  | ||||||
|   if (ev_fd_ > -1) { |   if (ev_fd_ > -1) { | ||||||
|     eventfd_write(ev_fd_, 1); |     eventfd_write(ev_fd_, 1); | ||||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(150)); |     std::this_thread::sleep_for(std::chrono::milliseconds(150)); | ||||||
| @@ -51,8 +54,7 @@ waybar::modules::Network::~Network() | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Network::createInfoSocket() | void waybar::modules::Network::createInfoSocket() { | ||||||
| { |  | ||||||
|   info_sock_ = nl_socket_alloc(); |   info_sock_ = nl_socket_alloc(); | ||||||
|   if (nl_connect(info_sock_, NETLINK_ROUTE) != 0) { |   if (nl_connect(info_sock_, NETLINK_ROUTE) != 0) { | ||||||
|     throw std::runtime_error("Can't connect network socket"); |     throw std::runtime_error("Can't connect network socket"); | ||||||
| @@ -72,7 +74,7 @@ void waybar::modules::Network::createInfoSocket() | |||||||
|   } |   } | ||||||
|   { |   { | ||||||
|     ev_fd_ = eventfd(0, EFD_NONBLOCK); |     ev_fd_ = eventfd(0, EFD_NONBLOCK); | ||||||
|     struct epoll_event event; |     struct epoll_event event = {0}; | ||||||
|     event.events = EPOLLIN | EPOLLET; |     event.events = EPOLLIN | EPOLLET; | ||||||
|     event.data.fd = ev_fd_; |     event.data.fd = ev_fd_; | ||||||
|     if (epoll_ctl(efd_, EPOLL_CTL_ADD, ev_fd_, &event) == -1) { |     if (epoll_ctl(efd_, EPOLL_CTL_ADD, ev_fd_, &event) == -1) { | ||||||
| @@ -80,8 +82,8 @@ void waybar::modules::Network::createInfoSocket() | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   { |   { | ||||||
|     auto fd = nl_socket_get_fd(info_sock_); |     auto               fd = nl_socket_get_fd(info_sock_); | ||||||
|     struct epoll_event event; |     struct epoll_event event = {0}; | ||||||
|     event.events = EPOLLIN | EPOLLET | EPOLLRDHUP; |     event.events = EPOLLIN | EPOLLET | EPOLLRDHUP; | ||||||
|     event.data.fd = fd; |     event.data.fd = fd; | ||||||
|     if (epoll_ctl(efd_, EPOLL_CTL_ADD, fd, &event) == -1) { |     if (epoll_ctl(efd_, EPOLL_CTL_ADD, fd, &event) == -1) { | ||||||
| @@ -90,8 +92,7 @@ void waybar::modules::Network::createInfoSocket() | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Network::createEventSocket() | void waybar::modules::Network::createEventSocket() { | ||||||
| { |  | ||||||
|   sk_ = nl_socket_alloc(); |   sk_ = nl_socket_alloc(); | ||||||
|   if (genl_connect(sk_) != 0) { |   if (genl_connect(sk_) != 0) { | ||||||
|     throw std::runtime_error("Can't connect to netlink socket"); |     throw std::runtime_error("Can't connect to netlink socket"); | ||||||
| @@ -105,8 +106,7 @@ void waybar::modules::Network::createEventSocket() | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Network::worker() | void waybar::modules::Network::worker() { | ||||||
| { |  | ||||||
|   thread_timer_ = [this] { |   thread_timer_ = [this] { | ||||||
|     if (ifid_ > 0) { |     if (ifid_ > 0) { | ||||||
|       getInfo(); |       getInfo(); | ||||||
| @@ -114,9 +114,9 @@ void waybar::modules::Network::worker() | |||||||
|     } |     } | ||||||
|     thread_timer_.sleep_for(interval_); |     thread_timer_.sleep_for(interval_); | ||||||
|   }; |   }; | ||||||
|   struct epoll_event events[EPOLL_MAX]; |   std::array<struct epoll_event, EPOLL_MAX> events; | ||||||
|   thread_ = [this, &events] { |   thread_ = [this, &events] { | ||||||
|     int ec = epoll_wait(efd_, events, EPOLL_MAX, -1); |     int ec = epoll_wait(efd_, events.data(), EPOLL_MAX, -1); | ||||||
|     if (ec > 0) { |     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(info_sock_)) { |         if (events[i].data.fd == nl_socket_get_fd(info_sock_)) { | ||||||
| @@ -132,8 +132,7 @@ void waybar::modules::Network::worker() | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Network::update() -> void | auto waybar::modules::Network::update() -> void { | ||||||
| { |  | ||||||
|   std::string connectiontype; |   std::string connectiontype; | ||||||
|   std::string tooltip_format = ""; |   std::string tooltip_format = ""; | ||||||
|   if (config_["tooltip-format"].isString()) { |   if (config_["tooltip-format"].isString()) { | ||||||
| @@ -172,28 +171,26 @@ auto waybar::modules::Network::update() -> void | |||||||
|     format_ = default_format_; |     format_ = default_format_; | ||||||
|   } |   } | ||||||
|   auto text = fmt::format(format_, |   auto text = fmt::format(format_, | ||||||
|     fmt::arg("essid", essid_), |                           fmt::arg("essid", essid_), | ||||||
|     fmt::arg("signaldBm", signal_strength_dbm_), |                           fmt::arg("signaldBm", signal_strength_dbm_), | ||||||
|     fmt::arg("signalStrength", signal_strength_), |                           fmt::arg("signalStrength", signal_strength_), | ||||||
|     fmt::arg("ifname", ifname_), |                           fmt::arg("ifname", ifname_), | ||||||
|     fmt::arg("netmask", netmask_), |                           fmt::arg("netmask", netmask_), | ||||||
|     fmt::arg("ipaddr", ipaddr_), |                           fmt::arg("ipaddr", ipaddr_), | ||||||
|     fmt::arg("cidr", cidr_), |                           fmt::arg("cidr", cidr_), | ||||||
|     fmt::arg("icon", getIcon(signal_strength_, connectiontype)) |                           fmt::arg("icon", getIcon(signal_strength_, connectiontype))); | ||||||
|   ); |  | ||||||
|   label_.set_markup(text); |   label_.set_markup(text); | ||||||
|   if (tooltipEnabled()) { |   if (tooltipEnabled()) { | ||||||
|     if (!tooltip_format.empty()) { |     if (!tooltip_format.empty()) { | ||||||
|       auto tooltip_text = fmt::format(tooltip_format, |       auto tooltip_text = fmt::format(tooltip_format, | ||||||
|         fmt::arg("essid", essid_), |                                       fmt::arg("essid", essid_), | ||||||
|         fmt::arg("signaldBm", signal_strength_dbm_), |                                       fmt::arg("signaldBm", signal_strength_dbm_), | ||||||
|         fmt::arg("signalStrength", signal_strength_), |                                       fmt::arg("signalStrength", signal_strength_), | ||||||
|         fmt::arg("ifname", ifname_), |                                       fmt::arg("ifname", ifname_), | ||||||
|         fmt::arg("netmask", netmask_), |                                       fmt::arg("netmask", netmask_), | ||||||
|         fmt::arg("ipaddr", ipaddr_), |                                       fmt::arg("ipaddr", ipaddr_), | ||||||
|         fmt::arg("cidr", cidr_), |                                       fmt::arg("cidr", cidr_), | ||||||
|         fmt::arg("icon", getIcon(signal_strength_, connectiontype)) |                                       fmt::arg("icon", getIcon(signal_strength_, connectiontype))); | ||||||
|       ); |  | ||||||
|       label_.set_tooltip_text(tooltip_text); |       label_.set_tooltip_text(tooltip_text); | ||||||
|     } else { |     } else { | ||||||
|       label_.set_tooltip_text(text); |       label_.set_tooltip_text(text); | ||||||
| @@ -201,8 +198,7 @@ auto waybar::modules::Network::update() -> void | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Network::disconnected() | void waybar::modules::Network::disconnected() { | ||||||
| { |  | ||||||
|   essid_.clear(); |   essid_.clear(); | ||||||
|   signal_strength_dbm_ = 0; |   signal_strength_dbm_ = 0; | ||||||
|   signal_strength_ = 0; |   signal_strength_ = 0; | ||||||
| @@ -218,17 +214,16 @@ void waybar::modules::Network::disconnected() | |||||||
| } | } | ||||||
|  |  | ||||||
| // Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698 | // Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698 | ||||||
| int waybar::modules::Network::getExternalInterface() | int waybar::modules::Network::getExternalInterface() { | ||||||
| { |  | ||||||
|   static const uint32_t route_buffer_size = 8192; |   static const uint32_t route_buffer_size = 8192; | ||||||
|   struct nlmsghdr *hdr = nullptr; |   struct nlmsghdr *     hdr = nullptr; | ||||||
|   struct rtmsg *rt = nullptr; |   struct rtmsg *        rt = nullptr; | ||||||
|   char resp[route_buffer_size] = {0}; |   char                  resp[route_buffer_size] = {0}; | ||||||
|   int ifidx = -1; |   int                   ifidx = -1; | ||||||
|  |  | ||||||
|   /* Prepare request. */ |   /* Prepare request. */ | ||||||
|   constexpr uint32_t reqlen = NLMSG_SPACE(sizeof(*rt)); |   constexpr uint32_t reqlen = NLMSG_SPACE(sizeof(*rt)); | ||||||
|   char req[reqlen] = {0}; |   char               req[reqlen] = {0}; | ||||||
|  |  | ||||||
|   /* Build the RTM_GETROUTE request. */ |   /* Build the RTM_GETROUTE request. */ | ||||||
|   hdr = reinterpret_cast<struct nlmsghdr *>(req); |   hdr = reinterpret_cast<struct nlmsghdr *>(req); | ||||||
| @@ -257,7 +252,7 @@ int waybar::modules::Network::getExternalInterface() | |||||||
|  |  | ||||||
|     /* Parse the response payload into netlink messages. */ |     /* Parse the response payload into netlink messages. */ | ||||||
|     for (hdr = reinterpret_cast<struct nlmsghdr *>(resp); NLMSG_OK(hdr, len); |     for (hdr = reinterpret_cast<struct nlmsghdr *>(resp); NLMSG_OK(hdr, len); | ||||||
|       hdr = NLMSG_NEXT(hdr, len)) { |          hdr = NLMSG_NEXT(hdr, len)) { | ||||||
|       if (hdr->nlmsg_type == NLMSG_DONE) { |       if (hdr->nlmsg_type == NLMSG_DONE) { | ||||||
|         goto out; |         goto out; | ||||||
|       } |       } | ||||||
| @@ -284,10 +279,10 @@ int waybar::modules::Network::getExternalInterface() | |||||||
|  |  | ||||||
|       /* Parse all the attributes for a single routing table entry. */ |       /* Parse all the attributes for a single routing table entry. */ | ||||||
|       struct rtattr *attr = RTM_RTA(rt); |       struct rtattr *attr = RTM_RTA(rt); | ||||||
|       uint64_t attrlen = RTM_PAYLOAD(hdr); |       uint64_t       attrlen = RTM_PAYLOAD(hdr); | ||||||
|       bool has_gateway = false; |       bool           has_gateway = false; | ||||||
|       bool has_destination = false; |       bool           has_destination = false; | ||||||
|       int temp_idx = -1; |       int            temp_idx = -1; | ||||||
|       for (; RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) { |       for (; RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) { | ||||||
|         /* Determine if this routing table entry corresponds to the default |         /* Determine if this routing table entry corresponds to the default | ||||||
|          * route by seeing if it has a gateway, and if a destination addr is |          * route by seeing if it has a gateway, and if a destination addr is | ||||||
| @@ -307,8 +302,8 @@ int waybar::modules::Network::getExternalInterface() | |||||||
|              * Should be either missing, or maybe all 0s.  Accept both. |              * Should be either missing, or maybe all 0s.  Accept both. | ||||||
|              */ |              */ | ||||||
|             const uint32_t nr_zeroes = (family_ == AF_INET) ? 4 : 16; |             const uint32_t nr_zeroes = (family_ == AF_INET) ? 4 : 16; | ||||||
|             unsigned char c = 0; |             unsigned char  c = 0; | ||||||
|             size_t dstlen = RTA_PAYLOAD(attr); |             size_t         dstlen = RTA_PAYLOAD(attr); | ||||||
|             if (dstlen != nr_zeroes) { |             if (dstlen != nr_zeroes) { | ||||||
|               break; |               break; | ||||||
|             } |             } | ||||||
| @@ -320,7 +315,7 @@ int waybar::modules::Network::getExternalInterface() | |||||||
|           } |           } | ||||||
|           case RTA_OIF: |           case RTA_OIF: | ||||||
|             /* The output interface index. */ |             /* The output interface index. */ | ||||||
|             temp_idx = *static_cast<int*>(RTA_DATA(attr)); |             temp_idx = *static_cast<int *>(RTA_DATA(attr)); | ||||||
|             break; |             break; | ||||||
|           default: |           default: | ||||||
|             break; |             break; | ||||||
| @@ -341,7 +336,7 @@ out: | |||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Network::getInterfaceAddress() { | void waybar::modules::Network::getInterfaceAddress() { | ||||||
|   unsigned int cidrRaw; |   unsigned int    cidrRaw; | ||||||
|   struct ifaddrs *ifaddr, *ifa; |   struct ifaddrs *ifaddr, *ifa; | ||||||
|   ipaddr_.clear(); |   ipaddr_.clear(); | ||||||
|   netmask_.clear(); |   netmask_.clear(); | ||||||
| @@ -352,13 +347,13 @@ void waybar::modules::Network::getInterfaceAddress() { | |||||||
|     while (ifa != nullptr && ipaddr_.empty() && netmask_.empty()) { |     while (ifa != nullptr && ipaddr_.empty() && netmask_.empty()) { | ||||||
|       if (ifa->ifa_addr != nullptr && ifa->ifa_addr->sa_family == family_) { |       if (ifa->ifa_addr != nullptr && ifa->ifa_addr->sa_family == family_) { | ||||||
|         if (strcmp(ifa->ifa_name, ifname_.c_str()) == 0) { |         if (strcmp(ifa->ifa_name, ifname_.c_str()) == 0) { | ||||||
|           ipaddr_ = inet_ntoa(((struct sockaddr_in*)ifa->ifa_addr)->sin_addr); |           ipaddr_ = inet_ntoa(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr); | ||||||
|           netmask_ = inet_ntoa(((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr); |           netmask_ = inet_ntoa(((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr); | ||||||
|           cidrRaw = ((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr; |           cidrRaw = ((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr; | ||||||
|           unsigned int cidr = 0; |           unsigned int cidr = 0; | ||||||
|           while (cidrRaw) { |           while (cidrRaw) { | ||||||
|               cidr += cidrRaw & 1; |             cidr += cidrRaw & 1; | ||||||
|               cidrRaw >>= 1; |             cidrRaw >>= 1; | ||||||
|           } |           } | ||||||
|           cidr_ = cidr; |           cidr_ = cidr; | ||||||
|         } |         } | ||||||
| @@ -369,26 +364,22 @@ void waybar::modules::Network::getInterfaceAddress() { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::modules::Network::netlinkRequest(void *req, | int waybar::modules::Network::netlinkRequest(void *req, uint32_t reqlen, uint32_t groups) { | ||||||
|   uint32_t reqlen, uint32_t groups) |  | ||||||
| { |  | ||||||
|   struct sockaddr_nl sa = {}; |   struct sockaddr_nl sa = {}; | ||||||
|   sa.nl_family = AF_NETLINK; |   sa.nl_family = AF_NETLINK; | ||||||
|   sa.nl_groups = groups; |   sa.nl_groups = groups; | ||||||
|   struct iovec iov = { req, reqlen }; |   struct iovec  iov = {req, reqlen}; | ||||||
|   struct msghdr msg = { &sa, sizeof(sa), &iov, 1, nullptr, 0, 0 }; |   struct msghdr msg = {&sa, sizeof(sa), &iov, 1, nullptr, 0, 0}; | ||||||
|   return sendmsg(nl_socket_get_fd(info_sock_), &msg, 0); |   return sendmsg(nl_socket_get_fd(info_sock_), &msg, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::modules::Network::netlinkResponse(void *resp, | int waybar::modules::Network::netlinkResponse(void *resp, uint32_t resplen, uint32_t groups) { | ||||||
|   uint32_t resplen, uint32_t groups) |  | ||||||
| { |  | ||||||
|   struct sockaddr_nl sa = {}; |   struct sockaddr_nl sa = {}; | ||||||
|   sa.nl_family = AF_NETLINK; |   sa.nl_family = AF_NETLINK; | ||||||
|   sa.nl_groups = groups; |   sa.nl_groups = groups; | ||||||
|   struct iovec iov = { resp, resplen }; |   struct iovec  iov = {resp, resplen}; | ||||||
|   struct msghdr msg = { &sa, sizeof(sa), &iov, 1, nullptr, 0, 0 }; |   struct msghdr msg = {&sa, sizeof(sa), &iov, 1, nullptr, 0, 0}; | ||||||
|   auto ret = recvmsg(nl_socket_get_fd(info_sock_), &msg, 0); |   auto          ret = recvmsg(nl_socket_get_fd(info_sock_), &msg, 0); | ||||||
|   if (msg.msg_flags & MSG_TRUNC) { |   if (msg.msg_flags & MSG_TRUNC) { | ||||||
|     return -1; |     return -1; | ||||||
|   } |   } | ||||||
| @@ -396,11 +387,10 @@ int waybar::modules::Network::netlinkResponse(void *resp, | |||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { | int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { | ||||||
|   int ret = 0; |   int  ret = 0; | ||||||
|   auto net = static_cast<waybar::modules::Network *>(data); |   auto net = static_cast<waybar::modules::Network *>(data); | ||||||
|   bool need_update = false; |   bool need_update = false; | ||||||
|   for (nlmsghdr *nh = nlmsg_hdr(msg); NLMSG_OK(nh, ret); |   for (nlmsghdr *nh = nlmsg_hdr(msg); NLMSG_OK(nh, ret); nh = NLMSG_NEXT(nh, ret)) { | ||||||
|     nh = NLMSG_NEXT(nh, ret)) { |  | ||||||
|     if (nh->nlmsg_type == RTM_NEWADDR) { |     if (nh->nlmsg_type == RTM_NEWADDR) { | ||||||
|       need_update = true; |       need_update = true; | ||||||
|     } |     } | ||||||
| @@ -443,10 +433,10 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { | |||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) { | int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) { | ||||||
|   auto net = static_cast<waybar::modules::Network *>(data); |   auto              net = static_cast<waybar::modules::Network *>(data); | ||||||
|   auto gnlh = static_cast<genlmsghdr *>(nlmsg_data(nlmsg_hdr(msg))); |   auto              gnlh = static_cast<genlmsghdr *>(nlmsg_data(nlmsg_hdr(msg))); | ||||||
|   struct nlattr* tb[NL80211_ATTR_MAX + 1]; |   struct nlattr *   tb[NL80211_ATTR_MAX + 1]; | ||||||
|   struct nlattr* bss[NL80211_BSS_MAX + 1]; |   struct nlattr *   bss[NL80211_BSS_MAX + 1]; | ||||||
|   struct nla_policy bss_policy[NL80211_BSS_MAX + 1]{}; |   struct nla_policy bss_policy[NL80211_BSS_MAX + 1]{}; | ||||||
|   bss_policy[NL80211_BSS_TSF].type = NLA_U64; |   bss_policy[NL80211_BSS_TSF].type = NLA_U64; | ||||||
|   bss_policy[NL80211_BSS_FREQUENCY].type = NLA_U32; |   bss_policy[NL80211_BSS_FREQUENCY].type = NLA_U32; | ||||||
| @@ -458,7 +448,8 @@ int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) { | |||||||
|   bss_policy[NL80211_BSS_SIGNAL_UNSPEC].type = NLA_U8; |   bss_policy[NL80211_BSS_SIGNAL_UNSPEC].type = NLA_U8; | ||||||
|   bss_policy[NL80211_BSS_STATUS].type = NLA_U32; |   bss_policy[NL80211_BSS_STATUS].type = NLA_U32; | ||||||
|  |  | ||||||
|   if (nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), nullptr) < 0) { |   if (nla_parse( | ||||||
|  |           tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), nullptr) < 0) { | ||||||
|     return NL_SKIP; |     return NL_SKIP; | ||||||
|   } |   } | ||||||
|   if (tb[NL80211_ATTR_BSS] == nullptr) { |   if (tb[NL80211_ATTR_BSS] == nullptr) { | ||||||
| @@ -476,21 +467,19 @@ int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) { | |||||||
|   return NL_SKIP; |   return NL_SKIP; | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Network::parseEssid(struct nlattr **bss) | void waybar::modules::Network::parseEssid(struct nlattr **bss) { | ||||||
| { |  | ||||||
|   essid_.clear(); |   essid_.clear(); | ||||||
|   if (bss[NL80211_BSS_INFORMATION_ELEMENTS] != nullptr) { |   if (bss[NL80211_BSS_INFORMATION_ELEMENTS] != nullptr) { | ||||||
|     auto ies = |     auto       ies = static_cast<char *>(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS])); | ||||||
|       static_cast<char*>(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS])); |     auto       ies_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]); | ||||||
|     auto ies_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]); |  | ||||||
|     const auto hdr_len = 2; |     const auto hdr_len = 2; | ||||||
|     while (ies_len > hdr_len && ies[0] != 0) { |     while (ies_len > hdr_len && ies[0] != 0) { | ||||||
|       ies_len -= ies[1] + hdr_len; |       ies_len -= ies[1] + hdr_len; | ||||||
|       ies += ies[1] + hdr_len; |       ies += ies[1] + hdr_len; | ||||||
|     } |     } | ||||||
|     if (ies_len > hdr_len && ies_len > ies[1] + hdr_len) { |     if (ies_len > hdr_len && ies_len > ies[1] + hdr_len) { | ||||||
|       auto essid_begin = ies + hdr_len; |       auto        essid_begin = ies + hdr_len; | ||||||
|       auto essid_end = essid_begin + ies[1]; |       auto        essid_end = essid_begin + ies[1]; | ||||||
|       std::string essid_raw; |       std::string essid_raw; | ||||||
|       std::copy(essid_begin, essid_end, std::back_inserter(essid_raw)); |       std::copy(essid_begin, essid_end, std::back_inserter(essid_raw)); | ||||||
|       essid_ = Glib::Markup::escape_text(essid_raw); |       essid_ = Glib::Markup::escape_text(essid_raw); | ||||||
| @@ -506,16 +495,15 @@ void waybar::modules::Network::parseSignal(struct nlattr **bss) { | |||||||
|     // WiFi-hardware usually operates in the range -90 to -20dBm. |     // WiFi-hardware usually operates in the range -90 to -20dBm. | ||||||
|     const int hardwareMax = -20; |     const int hardwareMax = -20; | ||||||
|     const int hardwareMin = -90; |     const int hardwareMin = -90; | ||||||
|     signal_strength_ = ((signal_strength_dbm_ - hardwareMin) |     signal_strength_ = | ||||||
|       / double{hardwareMax - hardwareMin}) * 100; |         ((signal_strength_dbm_ - hardwareMin) / double{hardwareMax - hardwareMin}) * 100; | ||||||
|   } |   } | ||||||
|   if (bss[NL80211_BSS_SIGNAL_UNSPEC] != nullptr) { |   if (bss[NL80211_BSS_SIGNAL_UNSPEC] != nullptr) { | ||||||
|     signal_strength_ = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); |     signal_strength_ = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| bool waybar::modules::Network::associatedOrJoined(struct nlattr** bss) | bool waybar::modules::Network::associatedOrJoined(struct nlattr **bss) { | ||||||
| { |  | ||||||
|   if (bss[NL80211_BSS_STATUS] == nullptr) { |   if (bss[NL80211_BSS_STATUS] == nullptr) { | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
| @@ -530,16 +518,16 @@ bool waybar::modules::Network::associatedOrJoined(struct nlattr** bss) | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Network::getInfo() -> void | auto waybar::modules::Network::getInfo() -> void { | ||||||
| { |  | ||||||
|   getInterfaceAddress(); |   getInterfaceAddress(); | ||||||
|   struct nl_msg* nl_msg = nlmsg_alloc(); |   struct nl_msg *nl_msg = nlmsg_alloc(); | ||||||
|   if (nl_msg == nullptr) { |   if (nl_msg == nullptr) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (genlmsg_put(nl_msg, NL_AUTO_PORT, NL_AUTO_SEQ, nl80211_id_, 0, NLM_F_DUMP, |   if (genlmsg_put( | ||||||
|     NL80211_CMD_GET_SCAN, 0) == nullptr |           nl_msg, NL_AUTO_PORT, NL_AUTO_SEQ, nl80211_id_, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0) == | ||||||
|     || nla_put_u32(nl_msg, NL80211_ATTR_IFINDEX, ifid_) < 0) { |           nullptr || | ||||||
|  |       nla_put_u32(nl_msg, NL80211_ATTR_IFINDEX, ifid_) < 0) { | ||||||
|     nlmsg_free(nl_msg); |     nlmsg_free(nl_msg); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| #include "modules/pulseaudio.hpp" | #include "modules/pulseaudio.hpp" | ||||||
| #include <array> | #include <array> | ||||||
|  |  | ||||||
| waybar::modules::Pulseaudio::Pulseaudio(const std::string& id, const Json::Value &config) | waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value &config) | ||||||
|     : ALabel(config, "{volume}%"), |     : ALabel(config, "{volume}%"), | ||||||
|       mainloop_(nullptr), |       mainloop_(nullptr), | ||||||
|       mainloop_api_(nullptr), |       mainloop_api_(nullptr), | ||||||
| @@ -24,10 +24,9 @@ waybar::modules::Pulseaudio::Pulseaudio(const std::string& id, const Json::Value | |||||||
|   if (context_ == nullptr) { |   if (context_ == nullptr) { | ||||||
|     throw std::runtime_error("pa_context_new() failed."); |     throw std::runtime_error("pa_context_new() failed."); | ||||||
|   } |   } | ||||||
|   if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOAUTOSPAWN, |   if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOAUTOSPAWN, nullptr) < 0) { | ||||||
|     nullptr) < 0) { |     auto err = | ||||||
|     auto err = fmt::format("pa_context_connect() failed: {}", |         fmt::format("pa_context_connect() failed: {}", pa_strerror(pa_context_errno(context_))); | ||||||
|       pa_strerror(pa_context_errno(context_))); |  | ||||||
|     throw std::runtime_error(err); |     throw std::runtime_error(err); | ||||||
|   } |   } | ||||||
|   pa_context_set_state_callback(context_, contextStateCb, this); |   pa_context_set_state_callback(context_, contextStateCb, this); | ||||||
| @@ -38,11 +37,9 @@ waybar::modules::Pulseaudio::Pulseaudio(const std::string& id, const Json::Value | |||||||
|  |  | ||||||
|   // define the pulse scroll events only when no user provided |   // define the pulse scroll events only when no user provided | ||||||
|   // events are configured |   // events are configured | ||||||
|   if (!config["on-scroll-up"].isString() && |   if (!config["on-scroll-up"].isString() && !config["on-scroll-down"].isString()) { | ||||||
|       !config["on-scroll-down"].isString()) { |  | ||||||
|     event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); |     event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); | ||||||
|     event_box_.signal_scroll_event().connect( |     event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Pulseaudio::handleScroll)); | ||||||
|         sigc::mem_fun(*this, &Pulseaudio::handleScroll)); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -52,8 +49,7 @@ waybar::modules::Pulseaudio::~Pulseaudio() { | |||||||
|   pa_threaded_mainloop_free(mainloop_); |   pa_threaded_mainloop_free(mainloop_); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data) | void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data) { | ||||||
| { |  | ||||||
|   auto pa = static_cast<waybar::modules::Pulseaudio *>(data); |   auto pa = static_cast<waybar::modules::Pulseaudio *>(data); | ||||||
|   switch (pa_context_get_state(c)) { |   switch (pa_context_get_state(c)) { | ||||||
|     case PA_CONTEXT_TERMINATED: |     case PA_CONTEXT_TERMINATED: | ||||||
| @@ -77,8 +73,8 @@ void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data) | |||||||
|  |  | ||||||
| bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { | bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { | ||||||
|   // Avoid concurrent scroll event |   // Avoid concurrent scroll event | ||||||
|   bool direction_up = false; |   bool       direction_up = false; | ||||||
|   uint16_t change = config_["scroll-step"].isUInt() ? config_["scroll-step"].asUInt() * 100 : 100; |   uint16_t   change = config_["scroll-step"].isUInt() ? config_["scroll-step"].asUInt() * 100 : 100; | ||||||
|   pa_cvolume pa_volume = pa_volume_; |   pa_cvolume pa_volume = pa_volume_; | ||||||
|  |  | ||||||
|   if (scrolling_) { |   if (scrolling_) { | ||||||
| @@ -94,8 +90,7 @@ bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { | |||||||
|  |  | ||||||
|   if (e->direction == GDK_SCROLL_SMOOTH) { |   if (e->direction == GDK_SCROLL_SMOOTH) { | ||||||
|     gdouble delta_x, delta_y; |     gdouble delta_x, delta_y; | ||||||
|     gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e), &delta_x, |     gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e), &delta_x, &delta_y); | ||||||
|                                 &delta_y); |  | ||||||
|     if (delta_y < 0) { |     if (delta_y < 0) { | ||||||
|       direction_up = true; |       direction_up = true; | ||||||
|     } else if (delta_y > 0) { |     } else if (delta_y > 0) { | ||||||
| @@ -109,8 +104,7 @@ bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { | |||||||
|     if (volume_ - 1 > 0) pa_cvolume_dec(&pa_volume, change); |     if (volume_ - 1 > 0) pa_cvolume_dec(&pa_volume, change); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   pa_context_set_sink_volume_by_index(context_, sink_idx_, &pa_volume, |   pa_context_set_sink_volume_by_index(context_, sink_idx_, &pa_volume, volumeModifyCb, this); | ||||||
|                                       volumeModifyCb, this); |  | ||||||
|  |  | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| @@ -118,43 +112,39 @@ bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { | |||||||
| /* | /* | ||||||
|  * Called when an event we subscribed to occurs. |  * Called when an event we subscribed to occurs. | ||||||
|  */ |  */ | ||||||
| void waybar::modules::Pulseaudio::subscribeCb(pa_context* context, | void waybar::modules::Pulseaudio::subscribeCb(pa_context *                 context, | ||||||
|   pa_subscription_event_type_t type, uint32_t idx, void* data) |                                               pa_subscription_event_type_t type, uint32_t idx, | ||||||
| { |                                               void *data) { | ||||||
|   unsigned facility = type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; |   unsigned facility = type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; | ||||||
|  |  | ||||||
|   switch (facility) { |   switch (facility) { | ||||||
|     case PA_SUBSCRIPTION_EVENT_SINK: |     case PA_SUBSCRIPTION_EVENT_SINK: | ||||||
|         pa_context_get_sink_info_by_index(context, idx, sinkInfoCb, data); |       pa_context_get_sink_info_by_index(context, idx, sinkInfoCb, data); | ||||||
|         break; |       break; | ||||||
|     default: |     default: | ||||||
|         break; |       break; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Called in response to a volume change request |  * Called in response to a volume change request | ||||||
|  */ |  */ | ||||||
| void waybar::modules::Pulseaudio::volumeModifyCb(pa_context *c, int success, | void waybar::modules::Pulseaudio::volumeModifyCb(pa_context *c, int success, void *data) { | ||||||
|                                                  void *data) { |  | ||||||
|   auto pa = static_cast<waybar::modules::Pulseaudio *>(data); |   auto pa = static_cast<waybar::modules::Pulseaudio *>(data); | ||||||
|   if (success) { |   if (success) { | ||||||
|     pa_context_get_sink_info_by_index(pa->context_, pa->sink_idx_, sinkInfoCb, |     pa_context_get_sink_info_by_index(pa->context_, pa->sink_idx_, sinkInfoCb, data); | ||||||
|                                       data); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Called when the requested sink information is ready. |  * Called when the requested sink information is ready. | ||||||
|  */ |  */ | ||||||
| void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, | void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, | ||||||
|                                              const pa_sink_info *i, int /*eol*/, |                                              int /*eol*/, void *                           data) { | ||||||
|                                              void *data) { |  | ||||||
|   if (i != nullptr) { |   if (i != nullptr) { | ||||||
|     auto pa = static_cast<waybar::modules::Pulseaudio *>(data); |     auto pa = static_cast<waybar::modules::Pulseaudio *>(data); | ||||||
|     pa->pa_volume_ = i->volume; |     pa->pa_volume_ = i->volume; | ||||||
|     float volume = static_cast<float>(pa_cvolume_avg(&(pa->pa_volume_))) / |     float volume = static_cast<float>(pa_cvolume_avg(&(pa->pa_volume_))) / float{PA_VOLUME_NORM}; | ||||||
|                    float{PA_VOLUME_NORM}; |  | ||||||
|     pa->sink_idx_ = i->index; |     pa->sink_idx_ = i->index; | ||||||
|     pa->volume_ = std::round(volume * 100.0f); |     pa->volume_ = std::round(volume * 100.0f); | ||||||
|     pa->muted_ = i->mute != 0; |     pa->muted_ = i->mute != 0; | ||||||
| @@ -168,30 +158,27 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, | |||||||
|  * Called when the requested information on the server is ready. This is |  * Called when the requested information on the server is ready. This is | ||||||
|  * used to find the default PulseAudio sink. |  * used to find the default PulseAudio sink. | ||||||
|  */ |  */ | ||||||
| void waybar::modules::Pulseaudio::serverInfoCb(pa_context *context, | void waybar::modules::Pulseaudio::serverInfoCb(pa_context *context, const pa_server_info *i, | ||||||
|   const pa_server_info *i, void *data) |                                                void *data) { | ||||||
| { |   pa_context_get_sink_info_by_name(context, i->default_sink_name, sinkInfoCb, data); | ||||||
|   pa_context_get_sink_info_by_name(context, i->default_sink_name, |  | ||||||
|     sinkInfoCb, data); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static const std::array<std::string, 9> ports = { | static const std::array<std::string, 9> ports = { | ||||||
|   "headphones", |     "headphones", | ||||||
|   "speaker", |     "speaker", | ||||||
|   "hdmi", |     "hdmi", | ||||||
|   "headset", |     "headset", | ||||||
|   "handsfree", |     "handsfree", | ||||||
|   "portable", |     "portable", | ||||||
|   "car", |     "car", | ||||||
|   "hifi", |     "hifi", | ||||||
|   "phone", |     "phone", | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const std::string waybar::modules::Pulseaudio::getPortIcon() const | const std::string waybar::modules::Pulseaudio::getPortIcon() const { | ||||||
| { |  | ||||||
|   std::string nameLC = port_name_; |   std::string nameLC = port_name_; | ||||||
|   std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower); |   std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower); | ||||||
|   for (auto const& port : ports) { |   for (auto const &port : ports) { | ||||||
|     if (nameLC.find(port) != std::string::npos) { |     if (nameLC.find(port) != std::string::npos) { | ||||||
|       return port; |       return port; | ||||||
|     } |     } | ||||||
| @@ -199,26 +186,23 @@ const std::string waybar::modules::Pulseaudio::getPortIcon() const | |||||||
|   return port_name_; |   return port_name_; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Pulseaudio::update() -> void | auto waybar::modules::Pulseaudio::update() -> void { | ||||||
| { |  | ||||||
|   auto format = format_; |   auto format = format_; | ||||||
|   if (muted_) { |   if (muted_) { | ||||||
|     format = |     format = config_["format-muted"].isString() ? config_["format-muted"].asString() : format; | ||||||
|       config_["format-muted"].isString() ? config_["format-muted"].asString() : format; |  | ||||||
|     label_.get_style_context()->add_class("muted"); |     label_.get_style_context()->add_class("muted"); | ||||||
|   } else { |   } else { | ||||||
|     label_.get_style_context()->remove_class("muted"); |     label_.get_style_context()->remove_class("muted"); | ||||||
|     if (port_name_.find("a2dp_sink") != std::string::npos) { |     if (port_name_.find("a2dp_sink") != std::string::npos) { | ||||||
|       format = config_["format-bluetooth"].isString() |       format = | ||||||
|         ? config_["format-bluetooth"].asString() : format; |           config_["format-bluetooth"].isString() ? config_["format-bluetooth"].asString() : format; | ||||||
|       label_.get_style_context()->add_class("bluetooth"); |       label_.get_style_context()->add_class("bluetooth"); | ||||||
|     } else { |     } else { | ||||||
|       label_.get_style_context()->remove_class("bluetooth"); |       label_.get_style_context()->remove_class("bluetooth"); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   label_.set_markup( |   label_.set_markup(fmt::format( | ||||||
|       fmt::format(format, fmt::arg("volume", volume_), |       format, fmt::arg("volume", volume_), fmt::arg("icon", getIcon(volume_, getPortIcon())))); | ||||||
|                   fmt::arg("icon", getIcon(volume_, getPortIcon())))); |  | ||||||
|   if (tooltipEnabled()) { |   if (tooltipEnabled()) { | ||||||
|     label_.set_tooltip_text(desc_); |     label_.set_tooltip_text(desc_); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -16,10 +16,23 @@ Host::Host(const std::size_t id, const Json::Value& config, | |||||||
|       on_add_(on_add), |       on_add_(on_add), | ||||||
|       on_remove_(on_remove) {} |       on_remove_(on_remove) {} | ||||||
|  |  | ||||||
| Host::~Host() { Gio::DBus::unwatch_name(bus_name_id_); } | Host::~Host() { | ||||||
|  |   if (bus_name_id_ > 0) { | ||||||
|  |     Gio::DBus::unwatch_name(bus_name_id_); | ||||||
|  |     bus_name_id_ = 0; | ||||||
|  |   } | ||||||
|  |   if (watcher_id_ > 0) { | ||||||
|  |     Gio::DBus::unwatch_name(watcher_id_); | ||||||
|  |     watcher_id_ = 0; | ||||||
|  |   } | ||||||
|  |   g_cancellable_cancel(cancellable_); | ||||||
|  |   g_clear_object(&cancellable_); | ||||||
|  |   g_clear_object(&watcher_); | ||||||
|  | } | ||||||
|  |  | ||||||
| void Host::busAcquired(const Glib::RefPtr<Gio::DBus::Connection>& conn, Glib::ustring name) { | void Host::busAcquired(const Glib::RefPtr<Gio::DBus::Connection>& conn, Glib::ustring name) { | ||||||
|   watcher_id_ = Gio::DBus::watch_name(conn, "org.kde.StatusNotifierWatcher", |   watcher_id_ = Gio::DBus::watch_name(conn, | ||||||
|  |                                       "org.kde.StatusNotifierWatcher", | ||||||
|                                       sigc::mem_fun(*this, &Host::nameAppeared), |                                       sigc::mem_fun(*this, &Host::nameAppeared), | ||||||
|                                       sigc::mem_fun(*this, &Host::nameVanished)); |                                       sigc::mem_fun(*this, &Host::nameVanished)); | ||||||
| } | } | ||||||
| @@ -31,8 +44,13 @@ void Host::nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>& conn, const G | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   cancellable_ = g_cancellable_new(); |   cancellable_ = g_cancellable_new(); | ||||||
|   sn_watcher_proxy_new(conn->gobj(), G_DBUS_PROXY_FLAGS_NONE, "org.kde.StatusNotifierWatcher", |   sn_watcher_proxy_new(conn->gobj(), | ||||||
|                        "/StatusNotifierWatcher", cancellable_, &Host::proxyReady, this); |                        G_DBUS_PROXY_FLAGS_NONE, | ||||||
|  |                        "org.kde.StatusNotifierWatcher", | ||||||
|  |                        "/StatusNotifierWatcher", | ||||||
|  |                        cancellable_, | ||||||
|  |                        &Host::proxyReady, | ||||||
|  |                        this); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Host::nameVanished(const Glib::RefPtr<Gio::DBus::Connection>& conn, const Glib::ustring name) { | void Host::nameVanished(const Glib::RefPtr<Gio::DBus::Connection>& conn, const Glib::ustring name) { | ||||||
| @@ -43,7 +61,7 @@ void Host::nameVanished(const Glib::RefPtr<Gio::DBus::Connection>& conn, const G | |||||||
| } | } | ||||||
|  |  | ||||||
| void Host::proxyReady(GObject* src, GAsyncResult* res, gpointer data) { | void Host::proxyReady(GObject* src, GAsyncResult* res, gpointer data) { | ||||||
|   GError* error = nullptr; |   GError*    error = nullptr; | ||||||
|   SnWatcher* watcher = sn_watcher_proxy_new_finish(res, &error); |   SnWatcher* watcher = sn_watcher_proxy_new_finish(res, &error); | ||||||
|   if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { |   if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { | ||||||
|     std::cerr << error->message << std::endl; |     std::cerr << error->message << std::endl; | ||||||
| @@ -57,8 +75,8 @@ void Host::proxyReady(GObject* src, GAsyncResult* res, gpointer data) { | |||||||
|     g_error_free(error); |     g_error_free(error); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   sn_watcher_call_register_host(host->watcher_, host->object_path_.c_str(), host->cancellable_, |   sn_watcher_call_register_host( | ||||||
|                                 &Host::registerHost, data); |       host->watcher_, host->object_path_.c_str(), host->cancellable_, &Host::registerHost, data); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Host::registerHost(GObject* src, GAsyncResult* res, gpointer data) { | void Host::registerHost(GObject* src, GAsyncResult* res, gpointer data) { | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| using namespace Glib; | using namespace Glib; | ||||||
|  |  | ||||||
| static const ustring SNI_INTERFACE_NAME = sn_item_interface_info()->name; | static const ustring  SNI_INTERFACE_NAME = sn_item_interface_info()->name; | ||||||
| static const unsigned UPDATE_DEBOUNCE_TIME = 10; | static const unsigned UPDATE_DEBOUNCE_TIME = 10; | ||||||
|  |  | ||||||
| waybar::modules::SNI::Item::Item(std::string bn, std::string op, const Json::Value& config) | waybar::modules::SNI::Item::Item(std::string bn, std::string op, const Json::Value& config) | ||||||
| @@ -25,9 +25,13 @@ waybar::modules::SNI::Item::Item(std::string bn, std::string op, const Json::Val | |||||||
|   cancellable_ = Gio::Cancellable::create(); |   cancellable_ = Gio::Cancellable::create(); | ||||||
|  |  | ||||||
|   auto interface = Glib::wrap(sn_item_interface_info(), true); |   auto interface = Glib::wrap(sn_item_interface_info(), true); | ||||||
|   Gio::DBus::Proxy::create_for_bus(Gio::DBus::BusType::BUS_TYPE_SESSION, bus_name, object_path, |   Gio::DBus::Proxy::create_for_bus(Gio::DBus::BusType::BUS_TYPE_SESSION, | ||||||
|                                    SNI_INTERFACE_NAME, sigc::mem_fun(*this, &Item::proxyReady), |                                    bus_name, | ||||||
|                                    cancellable_, interface); |                                    object_path, | ||||||
|  |                                    SNI_INTERFACE_NAME, | ||||||
|  |                                    sigc::mem_fun(*this, &Item::proxyReady), | ||||||
|  |                                    cancellable_, | ||||||
|  |                                    interface); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::SNI::Item::proxyReady(Glib::RefPtr<Gio::AsyncResult>& result) { | void waybar::modules::SNI::Item::proxyReady(Glib::RefPtr<Gio::AsyncResult>& result) { | ||||||
| @@ -52,10 +56,14 @@ void waybar::modules::SNI::Item::proxyReady(Glib::RefPtr<Gio::AsyncResult>& resu | |||||||
|     // this->event_box.set_tooltip_text(this->title); |     // this->event_box.set_tooltip_text(this->title); | ||||||
|  |  | ||||||
|   } catch (const Glib::Error& err) { |   } catch (const Glib::Error& err) { | ||||||
|     g_error("Failed to create DBus Proxy for %s %s: %s", bus_name.c_str(), object_path.c_str(), |     g_error("Failed to create DBus Proxy for %s %s: %s", | ||||||
|  |             bus_name.c_str(), | ||||||
|  |             object_path.c_str(), | ||||||
|             err.what().c_str()); |             err.what().c_str()); | ||||||
|   } catch (const std::exception& err) { |   } catch (const std::exception& err) { | ||||||
|     g_error("Failed to create DBus Proxy for %s %s: %s", bus_name.c_str(), object_path.c_str(), |     g_error("Failed to create DBus Proxy for %s %s: %s", | ||||||
|  |             bus_name.c_str(), | ||||||
|  |             object_path.c_str(), | ||||||
|             err.what()); |             err.what()); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -109,7 +117,8 @@ void waybar::modules::SNI::Item::getUpdatedProperties() { | |||||||
|  |  | ||||||
|   auto params = VariantContainerBase::create_tuple({Variant<ustring>::create(SNI_INTERFACE_NAME)}); |   auto params = VariantContainerBase::create_tuple({Variant<ustring>::create(SNI_INTERFACE_NAME)}); | ||||||
|   proxy_->call("org.freedesktop.DBus.Properties.GetAll", |   proxy_->call("org.freedesktop.DBus.Properties.GetAll", | ||||||
|                sigc::mem_fun(*this, &Item::processUpdatedProperties), params); |                sigc::mem_fun(*this, &Item::processUpdatedProperties), | ||||||
|  |                params); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| void waybar::modules::SNI::Item::processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& _result) { | void waybar::modules::SNI::Item::processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& _result) { | ||||||
| @@ -159,11 +168,11 @@ Glib::RefPtr<Gdk::Pixbuf> waybar::modules::SNI::Item::extractPixBuf(GVariant* va | |||||||
|     return Glib::RefPtr<Gdk::Pixbuf>{}; |     return Glib::RefPtr<Gdk::Pixbuf>{}; | ||||||
|   } |   } | ||||||
|   GVariant* val; |   GVariant* val; | ||||||
|   gint lwidth = 0; |   gint      lwidth = 0; | ||||||
|   gint lheight = 0; |   gint      lheight = 0; | ||||||
|   gint width; |   gint      width; | ||||||
|   gint height; |   gint      height; | ||||||
|   guchar* array = nullptr; |   guchar*   array = nullptr; | ||||||
|   while (g_variant_iter_loop(it, "(ii@ay)", &width, &height, &val)) { |   while (g_variant_iter_loop(it, "(ii@ay)", &width, &height, &val)) { | ||||||
|     if (width > 0 && height > 0 && val != nullptr && width * height > lwidth * lheight) { |     if (width > 0 && height > 0 && val != nullptr && width * height > lwidth * lheight) { | ||||||
|       auto size = g_variant_get_size(val); |       auto size = g_variant_get_size(val); | ||||||
| @@ -192,8 +201,14 @@ Glib::RefPtr<Gdk::Pixbuf> waybar::modules::SNI::Item::extractPixBuf(GVariant* va | |||||||
|       array[i + 2] = array[i + 3]; |       array[i + 2] = array[i + 3]; | ||||||
|       array[i + 3] = alpha; |       array[i + 3] = alpha; | ||||||
|     } |     } | ||||||
|     return Gdk::Pixbuf::create_from_data(array, Gdk::Colorspace::COLORSPACE_RGB, true, 8, lwidth, |     return Gdk::Pixbuf::create_from_data(array, | ||||||
|                                          lheight, 4 * lwidth, &pixbuf_data_deleter); |                                          Gdk::Colorspace::COLORSPACE_RGB, | ||||||
|  |                                          true, | ||||||
|  |                                          8, | ||||||
|  |                                          lwidth, | ||||||
|  |                                          lheight, | ||||||
|  |                                          4 * lwidth, | ||||||
|  |                                          &pixbuf_data_deleter); | ||||||
|   } |   } | ||||||
|   return Glib::RefPtr<Gdk::Pixbuf>{}; |   return Glib::RefPtr<Gdk::Pixbuf>{}; | ||||||
| } | } | ||||||
| @@ -230,7 +245,7 @@ void waybar::modules::SNI::Item::updateImage() { | |||||||
| } | } | ||||||
|  |  | ||||||
| Glib::RefPtr<Gdk::Pixbuf> waybar::modules::SNI::Item::getIconByName(std::string name, | Glib::RefPtr<Gdk::Pixbuf> waybar::modules::SNI::Item::getIconByName(std::string name, | ||||||
|                                                                     int request_size) { |                                                                     int         request_size) { | ||||||
|   int tmp_size = 0; |   int tmp_size = 0; | ||||||
|   icon_theme->rescan_if_needed(); |   icon_theme->rescan_if_needed(); | ||||||
|   auto sizes = icon_theme->get_icon_sizes(name.c_str()); |   auto sizes = icon_theme->get_icon_sizes(name.c_str()); | ||||||
| @@ -250,15 +265,16 @@ Glib::RefPtr<Gdk::Pixbuf> waybar::modules::SNI::Item::getIconByName(std::string | |||||||
|   if (tmp_size == 0) { |   if (tmp_size == 0) { | ||||||
|     tmp_size = request_size; |     tmp_size = request_size; | ||||||
|   } |   } | ||||||
|   auto icon = |   if (!icon_theme_path.empty() && | ||||||
|       icon_theme->load_icon(name.c_str(), tmp_size, Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE); |       icon_theme->lookup_icon( | ||||||
|   if (!icon) { |           name.c_str(), tmp_size, Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE)) { | ||||||
|     Glib::RefPtr<Gtk::IconTheme> default_theme = Gtk::IconTheme::get_default(); |     return icon_theme->load_icon( | ||||||
|     default_theme->rescan_if_needed(); |         name.c_str(), tmp_size, Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE); | ||||||
|     return default_theme->load_icon(name.c_str(), tmp_size, |  | ||||||
|                                     Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE); |  | ||||||
|   } |   } | ||||||
|   return icon; |   Glib::RefPtr<Gtk::IconTheme> default_theme = Gtk::IconTheme::get_default(); | ||||||
|  |   default_theme->rescan_if_needed(); | ||||||
|  |   return default_theme->load_icon( | ||||||
|  |       name.c_str(), tmp_size, Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::SNI::Item::onMenuDestroyed(Item* self) { | void waybar::modules::SNI::Item::onMenuDestroyed(Item* self) { | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ waybar::modules::SNI::Tray::Tray(const std::string& id, const Bar& bar, const Js | |||||||
|       watcher_(), |       watcher_(), | ||||||
|       host_(nb_hosts_, config, std::bind(&Tray::onAdd, this, std::placeholders::_1), |       host_(nb_hosts_, config, std::bind(&Tray::onAdd, this, std::placeholders::_1), | ||||||
|             std::bind(&Tray::onRemove, this, std::placeholders::_1)) { |             std::bind(&Tray::onRemove, this, std::placeholders::_1)) { | ||||||
|   std::cout << "Tray is in beta, so there may be bugs or even be unusable." << std::endl; |  | ||||||
|   if (config_["spacing"].isUInt()) { |   if (config_["spacing"].isUInt()) { | ||||||
|     box_.set_spacing(config_["spacing"].asUInt()); |     box_.set_spacing(config_["spacing"].asUInt()); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -28,23 +28,22 @@ Watcher::~Watcher() { | |||||||
|     g_slist_free_full(items_, gfWatchFree); |     g_slist_free_full(items_, gfWatchFree); | ||||||
|     items_ = NULL; |     items_ = NULL; | ||||||
|   } |   } | ||||||
|   g_signal_handler_disconnect(watcher_, handler_host_id_); |   g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(watcher_)); | ||||||
|   g_signal_handler_disconnect(watcher_, handler_item_id_); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void Watcher::busAcquired(const Glib::RefPtr<Gio::DBus::Connection>& conn, Glib::ustring name) { | void Watcher::busAcquired(const Glib::RefPtr<Gio::DBus::Connection>& conn, Glib::ustring name) { | ||||||
|   GError* error = nullptr; |   GError* error = nullptr; | ||||||
|   g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(watcher_), conn->gobj(), |   g_dbus_interface_skeleton_export( | ||||||
|                                    "/StatusNotifierWatcher", &error); |       G_DBUS_INTERFACE_SKELETON(watcher_), conn->gobj(), "/StatusNotifierWatcher", &error); | ||||||
|   if (error != nullptr) { |   if (error != nullptr) { | ||||||
|     std::cerr << error->message << std::endl; |     std::cerr << error->message << std::endl; | ||||||
|     g_error_free(error); |     g_error_free(error); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   handler_item_id_ = g_signal_connect_swapped(watcher_, "handle-register-item", |   g_signal_connect_swapped( | ||||||
|                            G_CALLBACK(&Watcher::handleRegisterItem), this); |       watcher_, "handle-register-item", G_CALLBACK(&Watcher::handleRegisterItem), this); | ||||||
|   handler_host_id_ = g_signal_connect_swapped(watcher_, "handle-register-host", |   g_signal_connect_swapped( | ||||||
|                            G_CALLBACK(&Watcher::handleRegisterHost), this); |       watcher_, "handle-register-host", G_CALLBACK(&Watcher::handleRegisterHost), this); | ||||||
| } | } | ||||||
|  |  | ||||||
| gboolean Watcher::handleRegisterHost(Watcher* obj, GDBusMethodInvocation* invocation, | gboolean Watcher::handleRegisterHost(Watcher* obj, GDBusMethodInvocation* invocation, | ||||||
| @@ -57,16 +56,22 @@ gboolean Watcher::handleRegisterHost(Watcher* obj, GDBusMethodInvocation* invoca | |||||||
|     object_path = service; |     object_path = service; | ||||||
|   } |   } | ||||||
|   if (g_dbus_is_name(bus_name) == FALSE) { |   if (g_dbus_is_name(bus_name) == FALSE) { | ||||||
|     g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, |     g_dbus_method_invocation_return_error(invocation, | ||||||
|                                           "D-Bus bus name '%s' is not valid", bus_name); |                                           G_DBUS_ERROR, | ||||||
|  |                                           G_DBUS_ERROR_INVALID_ARGS, | ||||||
|  |                                           "D-Bus bus name '%s' is not valid", | ||||||
|  |                                           bus_name); | ||||||
|     return TRUE; |     return TRUE; | ||||||
|   } |   } | ||||||
|   auto watch = gfWatchFind(obj->hosts_, bus_name, object_path); |   auto watch = gfWatchFind(obj->hosts_, bus_name, object_path); | ||||||
|   if (watch != nullptr) { |   if (watch != nullptr) { | ||||||
|     g_dbus_method_invocation_return_error( |     g_dbus_method_invocation_return_error( | ||||||
|         invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, |         invocation, | ||||||
|  |         G_DBUS_ERROR, | ||||||
|  |         G_DBUS_ERROR_INVALID_ARGS, | ||||||
|         "Status Notifier Host with bus name '%s' and object path '%s' is already registered", |         "Status Notifier Host with bus name '%s' and object path '%s' is already registered", | ||||||
|         bus_name, object_path); |         bus_name, | ||||||
|  |         object_path); | ||||||
|     return TRUE; |     return TRUE; | ||||||
|   } |   } | ||||||
|   watch = gfWatchNew(GF_WATCH_TYPE_HOST, service, bus_name, object_path, obj); |   watch = gfWatchNew(GF_WATCH_TYPE_HOST, service, bus_name, object_path, obj); | ||||||
| @@ -89,14 +94,18 @@ gboolean Watcher::handleRegisterItem(Watcher* obj, GDBusMethodInvocation* invoca | |||||||
|     object_path = service; |     object_path = service; | ||||||
|   } |   } | ||||||
|   if (g_dbus_is_name(bus_name) == FALSE) { |   if (g_dbus_is_name(bus_name) == FALSE) { | ||||||
|     g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, |     g_dbus_method_invocation_return_error(invocation, | ||||||
|                                           "D-Bus bus name '%s' is not valid", bus_name); |                                           G_DBUS_ERROR, | ||||||
|  |                                           G_DBUS_ERROR_INVALID_ARGS, | ||||||
|  |                                           "D-Bus bus name '%s' is not valid", | ||||||
|  |                                           bus_name); | ||||||
|     return TRUE; |     return TRUE; | ||||||
|   } |   } | ||||||
|   auto watch = gfWatchFind(obj->items_, bus_name, object_path); |   auto watch = gfWatchFind(obj->items_, bus_name, object_path); | ||||||
|   if (watch != nullptr) { |   if (watch != nullptr) { | ||||||
|     g_warning("Status Notifier Item with bus name '%s' and object path '%s' is already registered", |     g_warning("Status Notifier Item with bus name '%s' and object path '%s' is already registered", | ||||||
|               bus_name, object_path); |               bus_name, | ||||||
|  |               object_path); | ||||||
|     sn_watcher_complete_register_item(obj->watcher_, invocation); |     sn_watcher_complete_register_item(obj->watcher_, invocation); | ||||||
|     return TRUE; |     return TRUE; | ||||||
|   } |   } | ||||||
| @@ -144,8 +153,13 @@ Watcher::GfWatch* Watcher::gfWatchNew(GfWatchType type, const gchar* service, co | |||||||
|   watch->service = g_strdup(service); |   watch->service = g_strdup(service); | ||||||
|   watch->bus_name = g_strdup(bus_name); |   watch->bus_name = g_strdup(bus_name); | ||||||
|   watch->object_path = g_strdup(object_path); |   watch->object_path = g_strdup(object_path); | ||||||
|   watch->watch_id = g_bus_watch_name(G_BUS_TYPE_SESSION, bus_name, G_BUS_NAME_WATCHER_FLAGS_NONE, |   watch->watch_id = g_bus_watch_name(G_BUS_TYPE_SESSION, | ||||||
|                                      nullptr, &Watcher::nameVanished, watch, nullptr); |                                      bus_name, | ||||||
|  |                                      G_BUS_NAME_WATCHER_FLAGS_NONE, | ||||||
|  |                                      nullptr, | ||||||
|  |                                      &Watcher::nameVanished, | ||||||
|  |                                      watch, | ||||||
|  |                                      nullptr); | ||||||
|   return watch; |   return watch; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -171,11 +185,11 @@ void Watcher::updateRegisteredItems(SnWatcher* obj) { | |||||||
|   g_variant_builder_init(&builder, G_VARIANT_TYPE("as")); |   g_variant_builder_init(&builder, G_VARIANT_TYPE("as")); | ||||||
|   for (GSList* l = items_; l != nullptr; l = g_slist_next(l)) { |   for (GSList* l = items_; l != nullptr; l = g_slist_next(l)) { | ||||||
|     GfWatch* watch = static_cast<GfWatch*>(l->data); |     GfWatch* watch = static_cast<GfWatch*>(l->data); | ||||||
|     gchar* item = g_strdup_printf("%s%s", watch->bus_name, watch->object_path); |     gchar*   item = g_strdup_printf("%s%s", watch->bus_name, watch->object_path); | ||||||
|     g_variant_builder_add(&builder, "s", item); |     g_variant_builder_add(&builder, "s", item); | ||||||
|     g_free(item); |     g_free(item); | ||||||
|   } |   } | ||||||
|   GVariant* variant = g_variant_builder_end(&builder); |   GVariant*     variant = g_variant_builder_end(&builder); | ||||||
|   const gchar** items = g_variant_get_strv(variant, nullptr); |   const gchar** items = g_variant_get_strv(variant, nullptr); | ||||||
|   sn_watcher_set_registered_items(obj, items); |   sn_watcher_set_registered_items(obj, items); | ||||||
|   g_variant_unref(variant); |   g_variant_unref(variant); | ||||||
|   | |||||||
| @@ -1,33 +1,38 @@ | |||||||
| #include "modules/sway/ipc/client.hpp" | #include "modules/sway/ipc/client.hpp" | ||||||
|  | #include <fcntl.h> | ||||||
|  |  | ||||||
| waybar::modules::sway::Ipc::Ipc() | namespace waybar::modules::sway { | ||||||
| { |  | ||||||
|  | Ipc::Ipc() { | ||||||
|   const std::string& socketPath = getSocketPath(); |   const std::string& socketPath = getSocketPath(); | ||||||
|   fd_ = open(socketPath); |   fd_ = open(socketPath); | ||||||
|   fd_event_ = open(socketPath); |   fd_event_ = open(socketPath); | ||||||
| } | } | ||||||
|  |  | ||||||
| waybar::modules::sway::Ipc::~Ipc() | Ipc::~Ipc() { | ||||||
| { |  | ||||||
|   // To fail the IPC header |   // To fail the IPC header | ||||||
|   write(fd_, "close-sway-ipc", 14); |   write(fd_, "close-sway-ipc", 14); | ||||||
|   write(fd_event_, "close-sway-ipc", 14); |   write(fd_event_, "close-sway-ipc", 14); | ||||||
|  |   if (fd_ > 0) { | ||||||
|   close(fd_); |     close(fd_); | ||||||
|   close(fd_event_); |     fd_ = -1; | ||||||
|  |   } | ||||||
|  |   if (fd_event_ > 0) { | ||||||
|  |     close(fd_event_); | ||||||
|  |     fd_event_ = -1; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| const std::string waybar::modules::sway::Ipc::getSocketPath() const | const std::string Ipc::getSocketPath() const { | ||||||
| { |   const char* env = getenv("SWAYSOCK"); | ||||||
|   const char *env = getenv("SWAYSOCK"); |  | ||||||
|   if (env != nullptr) { |   if (env != nullptr) { | ||||||
|     return std::string(env); |     return std::string(env); | ||||||
|   } |   } | ||||||
|   std::string str; |   std::string str; | ||||||
|   { |   { | ||||||
|     std::string str_buf; |     std::string str_buf; | ||||||
|     FILE*  in; |     FILE*       in; | ||||||
|     char  buf[512] = { 0 }; |     char        buf[512] = {0}; | ||||||
|     if ((in = popen("sway --get-socketpath 2>/dev/null", "r")) == nullptr) { |     if ((in = popen("sway --get-socketpath 2>/dev/null", "r")) == nullptr) { | ||||||
|       throw std::runtime_error("Failed to get socket path"); |       throw std::runtime_error("Failed to get socket path"); | ||||||
|     } |     } | ||||||
| @@ -36,6 +41,9 @@ const std::string waybar::modules::sway::Ipc::getSocketPath() const | |||||||
|     } |     } | ||||||
|     pclose(in); |     pclose(in); | ||||||
|     str = str_buf; |     str = str_buf; | ||||||
|  |     if (str.empty()) { | ||||||
|  |       throw std::runtime_error("Socket path is empty"); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|   if (str.back() == '\n') { |   if (str.back() == '\n') { | ||||||
|     str.pop_back(); |     str.pop_back(); | ||||||
| @@ -43,39 +51,41 @@ const std::string waybar::modules::sway::Ipc::getSocketPath() const | |||||||
|   return str; |   return str; | ||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::modules::sway::Ipc::open(const std::string& socketPath) const | int Ipc::open(const std::string& socketPath) const { | ||||||
| { |   int32_t fd = socket(AF_UNIX, SOCK_STREAM, 0); | ||||||
|   struct sockaddr_un addr = {0}; |   if (fd == -1) { | ||||||
|   int fd = -1; |  | ||||||
|   if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { |  | ||||||
|     throw std::runtime_error("Unable to open Unix socket"); |     throw std::runtime_error("Unable to open Unix socket"); | ||||||
|   } |   } | ||||||
|  |   (void)fcntl(fd, F_SETFD, FD_CLOEXEC); | ||||||
|  |   struct sockaddr_un addr; | ||||||
|  |   memset(&addr, 0, sizeof(struct sockaddr_un)); | ||||||
|   addr.sun_family = AF_UNIX; |   addr.sun_family = AF_UNIX; | ||||||
|   strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1); |   strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1); | ||||||
|   addr.sun_path[sizeof(addr.sun_path) - 1] = 0; |   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<struct sockaddr *>(&addr), l) == -1) { |   if (::connect(fd, reinterpret_cast<struct sockaddr*>(&addr), l) == -1) { | ||||||
|     throw std::runtime_error("Unable to connect to Sway"); |     throw std::runtime_error("Unable to connect to Sway"); | ||||||
|   } |   } | ||||||
|   return fd; |   return fd; | ||||||
| } | } | ||||||
|  |  | ||||||
| struct waybar::modules::sway::Ipc::ipc_response | struct Ipc::ipc_response Ipc::recv(int fd) { | ||||||
|   waybar::modules::sway::Ipc::recv(int fd) const |  | ||||||
| { |  | ||||||
|   std::string header; |   std::string header; | ||||||
|   header.resize(ipc_header_size_); |   header.resize(ipc_header_size_); | ||||||
|   auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic_.size()); |   auto   data32 = reinterpret_cast<uint32_t*>(header.data() + ipc_magic_.size()); | ||||||
|   size_t total = 0; |   size_t total = 0; | ||||||
|  |  | ||||||
|   while (total < ipc_header_size_) { |   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, ""}; | ||||||
|  |     } | ||||||
|     if (res <= 0) { |     if (res <= 0) { | ||||||
|       throw std::runtime_error("Unable to receive IPC header"); |       throw std::runtime_error("Unable to receive IPC header"); | ||||||
|     } |     } | ||||||
|     total += res; |     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_) { |   if (magic != ipc_magic_) { | ||||||
|     throw std::runtime_error("Invalid IPC magic"); |     throw std::runtime_error("Invalid IPC magic"); | ||||||
| @@ -91,16 +101,13 @@ struct waybar::modules::sway::Ipc::ipc_response | |||||||
|     } |     } | ||||||
|     total += res; |     total += res; | ||||||
|   } |   } | ||||||
|   return { data32[0], data32[1], &payload.front() }; |   return {data32[0], data32[1], &payload.front()}; | ||||||
| } | } | ||||||
|  |  | ||||||
| struct waybar::modules::sway::Ipc::ipc_response | struct Ipc::ipc_response Ipc::send(int fd, uint32_t type, const std::string& payload) { | ||||||
|   waybar::modules::sway::Ipc::send(int fd, uint32_t type, |  | ||||||
|   const std::string& payload) const |  | ||||||
| { |  | ||||||
|   std::string header; |   std::string header; | ||||||
|   header.resize(ipc_header_size_); |   header.resize(ipc_header_size_); | ||||||
|   auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic_.size()); |   auto data32 = reinterpret_cast<uint32_t*>(header.data() + ipc_magic_.size()); | ||||||
|   memcpy(header.data(), ipc_magic_.c_str(), ipc_magic_.size()); |   memcpy(header.data(), ipc_magic_.c_str(), ipc_magic_.size()); | ||||||
|   data32[0] = payload.size(); |   data32[0] = payload.size(); | ||||||
|   data32[1] = type; |   data32[1] = type; | ||||||
| @@ -111,26 +118,27 @@ struct waybar::modules::sway::Ipc::ipc_response | |||||||
|   if (::send(fd, payload.c_str(), payload.size(), 0) == -1) { |   if (::send(fd, payload.c_str(), payload.size(), 0) == -1) { | ||||||
|     throw std::runtime_error("Unable to send IPC payload"); |     throw std::runtime_error("Unable to send IPC payload"); | ||||||
|   } |   } | ||||||
|   return recv(fd); |   return Ipc::recv(fd); | ||||||
| } | } | ||||||
|  |  | ||||||
| struct waybar::modules::sway::Ipc::ipc_response | void Ipc::sendCmd(uint32_t type, const std::string& payload) { | ||||||
|   waybar::modules::sway::Ipc::sendCmd(uint32_t type, |   std::lock_guard<std::mutex> lock(mutex_); | ||||||
|   const std::string& payload) const |   const auto res = Ipc::send(fd_, type, payload); | ||||||
| { |   signal_cmd.emit(res); | ||||||
|   return send(fd_, type, payload); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::sway::Ipc::subscribe(const std::string& payload) const | void Ipc::subscribe(const std::string& payload) { | ||||||
| { |   std::lock_guard<std::mutex> lock(mutex_event_); | ||||||
|   auto res = send(fd_event_, IPC_SUBSCRIBE, payload); |   auto res = Ipc::send(fd_event_, IPC_SUBSCRIBE, payload); | ||||||
|   if (res.payload != "{\"success\": true}") { |   if (res.payload != "{\"success\": true}") { | ||||||
|     throw std::runtime_error("Unable to subscribe ipc event"); |     throw std::runtime_error("Unable to subscribe ipc event"); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| struct waybar::modules::sway::Ipc::ipc_response | void Ipc::handleEvent() { | ||||||
|   waybar::modules::sway::Ipc::handleEvent() const |   std::lock_guard<std::mutex> lock(mutex_event_); | ||||||
| { |   const auto res = Ipc::recv(fd_event_); | ||||||
|   return recv(fd_event_); |   signal_event.emit(res); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | }  // namespace waybar::modules::sway | ||||||
| @@ -1,38 +1,41 @@ | |||||||
| #include "modules/sway/mode.hpp" | #include "modules/sway/mode.hpp" | ||||||
|  |  | ||||||
| waybar::modules::sway::Mode::Mode(const std::string& id, const Bar& bar, const Json::Value& config) | namespace waybar::modules::sway { | ||||||
|   : ALabel(config, "{}"), bar_(bar) |  | ||||||
| { | Mode::Mode(const std::string& id, const Bar& bar, const Json::Value& config) | ||||||
|  |     : ALabel(config, "{}"), bar_(bar) { | ||||||
|   label_.set_name("mode"); |   label_.set_name("mode"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
|   } |   } | ||||||
|   ipc_.subscribe("[ \"mode\" ]"); |   ipc_.subscribe("[ \"mode\" ]"); | ||||||
|  |   ipc_.signal_event.connect(sigc::mem_fun(*this, &Mode::onEvent)); | ||||||
|   // Launch worker |   // Launch worker | ||||||
|   worker(); |   worker(); | ||||||
|   dp.emit(); |   dp.emit(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::sway::Mode::worker() | void Mode::onEvent(const struct Ipc::ipc_response res) { | ||||||
| { |   auto parsed = parser_.parse(res.payload); | ||||||
|  |   if (parsed["change"] != "default") { | ||||||
|  |     mode_ = parsed["change"].asString(); | ||||||
|  |   } else { | ||||||
|  |     mode_.clear(); | ||||||
|  |   } | ||||||
|  |   dp.emit(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Mode::worker() { | ||||||
|   thread_ = [this] { |   thread_ = [this] { | ||||||
|     try { |     try { | ||||||
|       auto res = ipc_.handleEvent(); |       ipc_.handleEvent(); | ||||||
|       auto parsed = parser_.parse(res.payload); |  | ||||||
|       if (parsed["change"] != "default") { |  | ||||||
|         mode_ = parsed["change"].asString(); |  | ||||||
|       } else { |  | ||||||
|         mode_.clear(); |  | ||||||
|       } |  | ||||||
|       dp.emit(); |  | ||||||
|     } catch (const std::exception& e) { |     } catch (const std::exception& e) { | ||||||
|       std::cerr << "Mode: " << e.what() << std::endl; |       std::cerr << "Mode: " << e.what() << std::endl; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::sway::Mode::update() -> void | auto Mode::update() -> void { | ||||||
| { |  | ||||||
|   if (mode_.empty()) { |   if (mode_.empty()) { | ||||||
|     event_box_.hide(); |     event_box_.hide(); | ||||||
|   } else { |   } else { | ||||||
| @@ -42,4 +45,6 @@ auto waybar::modules::sway::Mode::update() -> void | |||||||
|     } |     } | ||||||
|     event_box_.show(); |     event_box_.show(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | }  // namespace waybar::modules::sway | ||||||
| @@ -1,8 +1,9 @@ | |||||||
| #include "modules/sway/window.hpp" | #include "modules/sway/window.hpp" | ||||||
|  |  | ||||||
| waybar::modules::sway::Window::Window(const std::string& id, const Bar &bar, const Json::Value& config) | namespace waybar::modules::sway { | ||||||
|   : ALabel(config, "{}"), bar_(bar), windowId_(-1) |  | ||||||
| { | Window::Window(const std::string& id, const Bar& bar, const Json::Value& config) | ||||||
|  |     : ALabel(config, "{}"), bar_(bar), windowId_(-1) { | ||||||
|   label_.set_name("window"); |   label_.set_name("window"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
| @@ -12,72 +13,76 @@ waybar::modules::sway::Window::Window(const std::string& id, const Bar &bar, con | |||||||
|     label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); |     label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); | ||||||
|   } |   } | ||||||
|   ipc_.subscribe("[\"window\",\"workspace\"]"); |   ipc_.subscribe("[\"window\",\"workspace\"]"); | ||||||
|  |   ipc_.signal_event.connect(sigc::mem_fun(*this, &Window::onEvent)); | ||||||
|  |   ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Window::onCmd)); | ||||||
|   getFocusedWindow(); |   getFocusedWindow(); | ||||||
|   // Launch worker |   // Launch worker | ||||||
|   worker(); |   worker(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::sway::Window::worker() | void Window::onEvent(const struct Ipc::ipc_response res) { | ||||||
| { |   auto parsed = parser_.parse(res.payload); | ||||||
|  |   // Check for waybar prevents flicker when hovering window module | ||||||
|  |   if ((parsed["change"] == "focus" || parsed["change"] == "title") && | ||||||
|  |       parsed["container"]["focused"].asBool() && | ||||||
|  |       parsed["container"]["name"].asString() != "waybar") { | ||||||
|  |     window_ = Glib::Markup::escape_text(parsed["container"]["name"].asString()); | ||||||
|  |     windowId_ = parsed["container"]["id"].asInt(); | ||||||
|  |     dp.emit(); | ||||||
|  |   } else if ((parsed["change"] == "close" && parsed["container"]["focused"].asBool() && | ||||||
|  |               windowId_ == parsed["container"]["id"].asInt()) || | ||||||
|  |              (parsed["change"] == "focus" && parsed["current"]["focus"].isArray() && | ||||||
|  |               parsed["current"]["focus"].empty())) { | ||||||
|  |     window_.clear(); | ||||||
|  |     windowId_ = -1; | ||||||
|  |     dp.emit(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Window::onCmd(const struct Ipc::ipc_response res) { | ||||||
|  |   auto parsed = parser_.parse(res.payload); | ||||||
|  |   auto [id, name] = getFocusedNode(parsed["nodes"]); | ||||||
|  |   windowId_ = id; | ||||||
|  |   window_ = name; | ||||||
|  |   dp.emit(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Window::worker() { | ||||||
|   thread_ = [this] { |   thread_ = [this] { | ||||||
|     try { |     try { | ||||||
|       auto res = ipc_.handleEvent(); |       ipc_.handleEvent(); | ||||||
|       auto parsed = parser_.parse(res.payload); |  | ||||||
|       // Check for waybar prevents flicker when hovering window module |  | ||||||
|       if ((parsed["change"] == "focus" || parsed["change"] == "title") |  | ||||||
|         && parsed["container"]["focused"].asBool() |  | ||||||
|         && parsed["container"]["name"].asString() != "waybar") { |  | ||||||
|         window_ = Glib::Markup::escape_text(parsed["container"]["name"].asString()); |  | ||||||
|         windowId_ = parsed["container"]["id"].asInt(); |  | ||||||
|         dp.emit(); |  | ||||||
|       } else if ((parsed["change"] == "close" |  | ||||||
|         && parsed["container"]["focused"].asBool() |  | ||||||
|         && windowId_ == parsed["container"]["id"].asInt()) |  | ||||||
|         || (parsed["change"] == "focus" && parsed["current"]["focus"].isArray() |  | ||||||
|         && parsed["current"]["focus"].empty())) { |  | ||||||
|         window_.clear(); |  | ||||||
|         windowId_ = -1; |  | ||||||
|         dp.emit(); |  | ||||||
|       } |  | ||||||
|     } catch (const std::exception& e) { |     } catch (const std::exception& e) { | ||||||
|       std::cerr << "Window: " << e.what() << std::endl; |       std::cerr << "Window: " << e.what() << std::endl; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::sway::Window::update() -> void | auto Window::update() -> void { | ||||||
| { |  | ||||||
|   label_.set_markup(fmt::format(format_, window_)); |   label_.set_markup(fmt::format(format_, window_)); | ||||||
|   if (tooltipEnabled()) { |   if (tooltipEnabled()) { | ||||||
|     label_.set_tooltip_text(window_); |     label_.set_tooltip_text(window_); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| std::tuple<int, std::string> waybar::modules::sway::Window::getFocusedNode( | std::tuple<int, std::string> Window::getFocusedNode(Json::Value nodes) { | ||||||
|   Json::Value nodes) |  | ||||||
| { |  | ||||||
|   for (auto const& node : nodes) { |   for (auto const& node : nodes) { | ||||||
|     if (node["focused"].asBool() && node["type"] == "con") { |     if (node["focused"].asBool() && node["type"] == "con") { | ||||||
|       return { node["id"].asInt(), node["name"].asString() }; |       return {node["id"].asInt(), node["name"].asString()}; | ||||||
|     } |     } | ||||||
|     auto [id, name] = getFocusedNode(node["nodes"]); |     auto [id, name] = getFocusedNode(node["nodes"]); | ||||||
|     if (id > -1 && !name.empty()) { |     if (id > -1 && !name.empty()) { | ||||||
|       return { id, name }; |       return {id, name}; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   return { -1, std::string() }; |   return {-1, std::string()}; | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::sway::Window::getFocusedWindow() | void Window::getFocusedWindow() { | ||||||
| { |  | ||||||
|   try { |   try { | ||||||
|     auto res = ipc_.sendCmd(IPC_GET_TREE); |     ipc_.sendCmd(IPC_GET_TREE); | ||||||
|     auto parsed = parser_.parse(res.payload); |   } catch (const std::exception& e) { | ||||||
|     auto [id, name] = getFocusedNode(parsed["nodes"]); |  | ||||||
|     windowId_ = id; |  | ||||||
|     window_ = name; |  | ||||||
|     Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Window::update)); |  | ||||||
|   } catch (const std::exception &e) { |  | ||||||
|     std::cerr << e.what() << std::endl; |     std::cerr << e.what() << std::endl; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | }  // namespace waybar::modules::sway | ||||||
| @@ -1,154 +1,138 @@ | |||||||
| #include "modules/sway/workspaces.hpp" | #include "modules/sway/workspaces.hpp" | ||||||
|  |  | ||||||
| waybar::modules::sway::Workspaces::Workspaces(const std::string& id, const Bar& bar, | namespace waybar::modules::sway { | ||||||
|   const Json::Value& config) |  | ||||||
|   : bar_(bar), config_(config), | Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config) | ||||||
|     box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0), |     : bar_(bar), | ||||||
|     scrolling_(false) |       config_(config), | ||||||
| { |       box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0), | ||||||
|  |       scrolling_(false) { | ||||||
|   box_.set_name("workspaces"); |   box_.set_name("workspaces"); | ||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     box_.get_style_context()->add_class(id); |     box_.get_style_context()->add_class(id); | ||||||
|   } |   } | ||||||
|   ipc_.subscribe("[ \"workspace\" ]"); |   ipc_.subscribe("[ \"workspace\" ]"); | ||||||
|  |   ipc_.signal_event.connect(sigc::mem_fun(*this, &Workspaces::onEvent)); | ||||||
|  |   ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Workspaces::onCmd)); | ||||||
|  |   ipc_.sendCmd(IPC_GET_WORKSPACES); | ||||||
|   // Launch worker |   // Launch worker | ||||||
|   worker(); |   worker(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::sway::Workspaces::worker() | void Workspaces::onEvent(const struct Ipc::ipc_response res) { ipc_.sendCmd(IPC_GET_WORKSPACES); } | ||||||
| { |  | ||||||
|  | void Workspaces::onCmd(const struct Ipc::ipc_response res) { | ||||||
|  |   if (res.type == IPC_GET_WORKSPACES) { | ||||||
|  |     auto workspaces = parser_.parse(res.payload); | ||||||
|  |     workspaces_.clear(); | ||||||
|  |     std::copy_if(workspaces.begin(), | ||||||
|  |                  workspaces.end(), | ||||||
|  |                  std::back_inserter(workspaces_), | ||||||
|  |                  [&](const auto &workspace) { | ||||||
|  |                    return !config_["all-outputs"].asBool() | ||||||
|  |                               ? workspace["output"].asString() == bar_.output->name | ||||||
|  |                               : true; | ||||||
|  |                  }); | ||||||
|  |     dp.emit(); | ||||||
|  |   } else { | ||||||
|  |     if (scrolling_) { | ||||||
|  |       scrolling_ = false; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Workspaces::worker() { | ||||||
|   thread_ = [this] { |   thread_ = [this] { | ||||||
|     try { |     try { | ||||||
|       if (!workspaces_.empty()) { |       ipc_.handleEvent(); | ||||||
|         ipc_.handleEvent(); |     } catch (const std::exception &e) { | ||||||
|       } |  | ||||||
|       { |  | ||||||
|         std::lock_guard<std::mutex> lock(mutex_); |  | ||||||
|         auto res = ipc_.sendCmd(IPC_GET_WORKSPACES); |  | ||||||
|         if (thread_.isRunning()) { |  | ||||||
|           workspaces_ = parser_.parse(res.payload); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       dp.emit(); |  | ||||||
|     } catch (const std::exception& e) { |  | ||||||
|       std::cerr << "Workspaces: " << e.what() << std::endl; |       std::cerr << "Workspaces: " << e.what() << std::endl; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::sway::Workspaces::update() -> void | bool Workspaces::filterButtons() { | ||||||
| { |  | ||||||
|   bool needReorder = false; |   bool needReorder = false; | ||||||
|   std::lock_guard<std::mutex> lock(mutex_); |  | ||||||
|   for (auto it = buttons_.begin(); it != buttons_.end();) { |   for (auto it = buttons_.begin(); it != buttons_.end();) { | ||||||
|     auto ws = std::find_if(workspaces_.begin(), workspaces_.end(), |     auto ws = std::find_if(workspaces_.begin(), workspaces_.end(), [it](const auto &node) { | ||||||
|       [it](auto node) -> bool { return node["name"].asString() == it->first; }); |       return node["name"].asString() == it->first; | ||||||
|  |     }); | ||||||
|     if (ws == workspaces_.end() || |     if (ws == workspaces_.end() || | ||||||
|             (!config_["all-outputs"].asBool() && (*ws)["output"].asString() != bar_.output_name)) { |         (!config_["all-outputs"].asBool() && (*ws)["output"].asString() != bar_.output->name)) { | ||||||
|       it = buttons_.erase(it); |       it = buttons_.erase(it); | ||||||
|       needReorder = true; |       needReorder = true; | ||||||
|     } else { |     } else { | ||||||
|       ++it; |       ++it; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   for (auto const& node : workspaces_) { |   return needReorder; | ||||||
|     if (!config_["all-outputs"].asBool() | } | ||||||
|       && bar_.output_name != node["output"].asString()) { |  | ||||||
|       continue; | auto Workspaces::update() -> void { | ||||||
|     } |   bool needReorder = filterButtons(); | ||||||
|     auto it = buttons_.find(node["name"].asString()); |   for (auto it = workspaces_.begin(); it != workspaces_.end(); ++it) { | ||||||
|     if (it == buttons_.end()) { |     auto bit = buttons_.find((*it)["name"].asString()); | ||||||
|       addWorkspace(node); |     if (bit == buttons_.end()) { | ||||||
|       needReorder = true; |       needReorder = true; | ||||||
|     } else { |  | ||||||
|       auto &button = it->second; |  | ||||||
|       if (node["focused"].asBool()) { |  | ||||||
|         button.get_style_context()->add_class("focused"); |  | ||||||
|       } else { |  | ||||||
|         button.get_style_context()->remove_class("focused"); |  | ||||||
|       } |  | ||||||
|       if (node["visible"].asBool()) { |  | ||||||
|         button.get_style_context()->add_class("visible"); |  | ||||||
|       } else { |  | ||||||
|         button.get_style_context()->remove_class("visible"); |  | ||||||
|       } |  | ||||||
|       if (node["urgent"].asBool()) { |  | ||||||
|         button.get_style_context()->add_class("urgent"); |  | ||||||
|       } else { |  | ||||||
|         button.get_style_context()->remove_class("urgent"); |  | ||||||
|       } |  | ||||||
|       if (needReorder) { |  | ||||||
|         box_.reorder_child(button, getWorkspaceIndex(node["name"].asString())); |  | ||||||
|       } |  | ||||||
|       auto icon = getIcon(node["name"].asString(), node); |  | ||||||
|       std::string output = icon; |  | ||||||
|       if (config_["format"].isString()) { |  | ||||||
|         auto format = config_["format"].asString(); |  | ||||||
|         output = fmt::format(format, fmt::arg("icon", icon), |  | ||||||
|           fmt::arg("name", trimWorkspaceName(node["name"].asString())), |  | ||||||
|           fmt::arg("index", node["num"].asString())); |  | ||||||
|       } |  | ||||||
|       if (!config_["disable-markup"].asBool()) { |  | ||||||
|         static_cast<Gtk::Label*>(button.get_children()[0])->set_markup(output); |  | ||||||
|       } else { |  | ||||||
|         button.set_label(output); |  | ||||||
|       } |  | ||||||
|       onButtonReady(node, button); |  | ||||||
|     } |     } | ||||||
|   } |     auto &button = bit == buttons_.end() ? addButton(*it) : bit->second; | ||||||
|   if (scrolling_) { |     if ((*it)["focused"].asBool()) { | ||||||
|     scrolling_ = false; |       button.get_style_context()->add_class("focused"); | ||||||
|  |     } else { | ||||||
|  |       button.get_style_context()->remove_class("focused"); | ||||||
|  |     } | ||||||
|  |     if ((*it)["visible"].asBool()) { | ||||||
|  |       button.get_style_context()->add_class("visible"); | ||||||
|  |     } else { | ||||||
|  |       button.get_style_context()->remove_class("visible"); | ||||||
|  |     } | ||||||
|  |     if ((*it)["urgent"].asBool()) { | ||||||
|  |       button.get_style_context()->add_class("urgent"); | ||||||
|  |     } else { | ||||||
|  |       button.get_style_context()->remove_class("urgent"); | ||||||
|  |     } | ||||||
|  |     if (needReorder) { | ||||||
|  |       box_.reorder_child(button, it - workspaces_.begin()); | ||||||
|  |     } | ||||||
|  |     std::string output = getIcon((*it)["name"].asString(), *it); | ||||||
|  |     if (config_["format"].isString()) { | ||||||
|  |       auto format = config_["format"].asString(); | ||||||
|  |       output = fmt::format(format, | ||||||
|  |                            fmt::arg("icon", output), | ||||||
|  |                            fmt::arg("name", trimWorkspaceName((*it)["name"].asString())), | ||||||
|  |                            fmt::arg("index", (*it)["num"].asString())); | ||||||
|  |     } | ||||||
|  |     if (!config_["disable-markup"].asBool()) { | ||||||
|  |       static_cast<Gtk::Label *>(button.get_children()[0])->set_markup(output); | ||||||
|  |     } else { | ||||||
|  |       button.set_label(output); | ||||||
|  |     } | ||||||
|  |     onButtonReady(*it, button); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::sway::Workspaces::addWorkspace(const Json::Value &node) | Gtk::Button &Workspaces::addButton(const Json::Value &node) { | ||||||
| { |   auto  pair = buttons_.emplace(node["name"].asString(), node["name"].asString()); | ||||||
|   auto icon = getIcon(node["name"].asString(), node); |  | ||||||
|   auto format = config_["format"].isString() |  | ||||||
|     ? fmt::format(config_["format"].asString(), fmt::arg("icon", icon), |  | ||||||
|       fmt::arg("name", trimWorkspaceName(node["name"].asString())), |  | ||||||
|       fmt::arg("index", node["num"].asString())) |  | ||||||
|     : icon; |  | ||||||
|   auto pair = buttons_.emplace(node["name"].asString(), format); |  | ||||||
|   auto &button = pair.first->second; |   auto &button = pair.first->second; | ||||||
|   if (!config_["disable-markup"].asBool()) { |  | ||||||
|     static_cast<Gtk::Label*>(button.get_children()[0])->set_markup(format); |  | ||||||
|   } |  | ||||||
|   box_.pack_start(button, false, false, 0); |   box_.pack_start(button, false, false, 0); | ||||||
|   button.set_relief(Gtk::RELIEF_NONE); |   button.set_relief(Gtk::RELIEF_NONE); | ||||||
|   button.signal_clicked().connect([this, pair] { |   button.signal_clicked().connect([this, pair] { | ||||||
|     try { |     try { | ||||||
|       std::lock_guard<std::mutex> lock(mutex_); |       ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", pair.first->first)); | ||||||
|       auto cmd = fmt::format("workspace \"{}\"", pair.first->first); |     } catch (const std::exception &e) { | ||||||
|       ipc_.sendCmd(IPC_COMMAND, cmd); |  | ||||||
|     } catch (const std::exception& e) { |  | ||||||
|       std::cerr << e.what() << std::endl; |       std::cerr << e.what() << std::endl; | ||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
|   if (!config_["disable-scroll"].asBool()) { |   if (!config_["disable-scroll"].asBool()) { | ||||||
|     button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); |     button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); | ||||||
|     button.signal_scroll_event() |     button.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll)); | ||||||
|       .connect(sigc::mem_fun(*this, &Workspaces::handleScroll)); |  | ||||||
|   } |   } | ||||||
|   box_.reorder_child(button, getWorkspaceIndex(node["name"].asString())); |   return button; | ||||||
|   if (node["focused"].asBool()) { |  | ||||||
|     button.get_style_context()->add_class("focused"); |  | ||||||
|   } |  | ||||||
|   if (node["visible"].asBool()) { |  | ||||||
|     button.get_style_context()->add_class("visible"); |  | ||||||
|   } |  | ||||||
|   if (node["urgent"].asBool()) { |  | ||||||
|     button.get_style_context()->add_class("urgent"); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| 	onButtonReady(node, button); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string waybar::modules::sway::Workspaces::getIcon(const std::string &name, | std::string Workspaces::getIcon(const std::string &name, const Json::Value &node) { | ||||||
|   const Json::Value &node) |   std::vector<std::string> keys = {name, "urgent", "focused", "visible", "default"}; | ||||||
| { |   for (auto const &key : keys) { | ||||||
|   std::vector<std::string> keys = { name, "urgent", "focused", "visible", "default" }; |  | ||||||
|   for (auto const& key : keys) { |  | ||||||
|     if (key == "focused" || key == "visible" || key == "urgent") { |     if (key == "focused" || key == "visible" || key == "urgent") { | ||||||
|       if (config_["format-icons"][key].isString() && node[key].asBool()) { |       if (config_["format-icons"][key].isString() && node[key].asBool()) { | ||||||
|         return config_["format-icons"][key].asString(); |         return config_["format-icons"][key].asString(); | ||||||
| @@ -160,112 +144,84 @@ std::string waybar::modules::sway::Workspaces::getIcon(const std::string &name, | |||||||
|   return name; |   return name; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e) | bool Workspaces::handleScroll(GdkEventScroll *e) { | ||||||
| { |  | ||||||
|   // Avoid concurrent scroll event |   // Avoid concurrent scroll event | ||||||
|   if (scrolling_) { |   if (scrolling_) { | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|   std::lock_guard<std::mutex> lock(mutex_); |  | ||||||
|   uint8_t idx; |  | ||||||
|   scrolling_ = true; |   scrolling_ = true; | ||||||
|   for (idx = 0; idx < workspaces_.size(); idx += 1) { |   std::string name; | ||||||
|     if (workspaces_[idx]["focused"].asBool()) { |   auto        it = std::find_if(workspaces_.begin(), workspaces_.end(), [](const auto &workspace) { | ||||||
|       break; |     return workspace["focused"].asBool(); | ||||||
|     } |   }); | ||||||
|   } |   if (it == workspaces_.end()) { | ||||||
|   if (idx == workspaces_.size()) { |  | ||||||
|     scrolling_ = false; |     scrolling_ = false; | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|   std::string name; |   switch (e->direction) { | ||||||
|   if (e->direction == GDK_SCROLL_UP) { |     case GDK_SCROLL_DOWN: | ||||||
|       name = getCycleWorkspace(idx, true); |     case GDK_SCROLL_RIGHT: | ||||||
|  |       name = getCycleWorkspace(it, false); | ||||||
|  |       break; | ||||||
|  |     case GDK_SCROLL_UP: | ||||||
|  |     case GDK_SCROLL_LEFT: | ||||||
|  |       name = getCycleWorkspace(it, true); | ||||||
|  |       break; | ||||||
|  |     case GDK_SCROLL_SMOOTH: | ||||||
|  |       gdouble delta_x, delta_y; | ||||||
|  |       gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e), &delta_x, &delta_y); | ||||||
|  |       if (delta_y < 0) { | ||||||
|  |         name = getCycleWorkspace(it, true); | ||||||
|  |       } else if (delta_y > 0) { | ||||||
|  |         name = getCycleWorkspace(it, false); | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       break; | ||||||
|   } |   } | ||||||
|   if (e->direction == GDK_SCROLL_DOWN) { |   if (name.empty() || name == (*it)["name"].asString()) { | ||||||
|       name = getCycleWorkspace(idx, false); |  | ||||||
|   } |  | ||||||
|   if (e->direction == GDK_SCROLL_SMOOTH) { |  | ||||||
|     gdouble delta_x, delta_y; |  | ||||||
|     gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e), |  | ||||||
|       &delta_x, &delta_y); |  | ||||||
|     if (delta_y < 0) { |  | ||||||
|       name = getCycleWorkspace(idx, true); |  | ||||||
|     } else if (delta_y > 0) { |  | ||||||
|       name = getCycleWorkspace(idx, false); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   if (name.empty() || name == workspaces_[idx]["name"].asString()) { |  | ||||||
|     scrolling_ = false; |     scrolling_ = false; | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|   ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", name)); |   ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", name)); | ||||||
|   std::this_thread::sleep_for(std::chrono::milliseconds(150)); |  | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| const std::string waybar::modules::sway::Workspaces::getCycleWorkspace( | const std::string Workspaces::getCycleWorkspace(std::vector<Json::Value>::iterator it, | ||||||
|   uint8_t focused_workspace, bool prev) const |                                                 bool                               prev) const { | ||||||
| { |   if (prev && it == workspaces_.begin()) { | ||||||
|   auto inc = prev ? -1 : 1; |     return (*(--workspaces_.end()))["name"].asString(); | ||||||
|   int size = workspaces_.size(); |  | ||||||
|   uint8_t idx = 0; |  | ||||||
|   for (int i = focused_workspace; i < size && i >= 0; i += inc) { |  | ||||||
|     bool same_output = (workspaces_[i]["output"].asString() == bar_.output_name |  | ||||||
|       && !config_["all-outputs"].asBool()) || config_["all-outputs"].asBool(); |  | ||||||
|     bool same_name = |  | ||||||
|       workspaces_[i]["name"].asString() == workspaces_[focused_workspace]["name"].asString(); |  | ||||||
|     if (same_output && !same_name) { |  | ||||||
|       return workspaces_[i]["name"].asString(); |  | ||||||
|     } |  | ||||||
|     if (prev && i - 1 < 0) { |  | ||||||
|       i = size; |  | ||||||
|     } else if (!prev && i + 1 >= size) { |  | ||||||
|       i = -1; |  | ||||||
|     } else if (idx >= workspaces_.size()) { |  | ||||||
|       return ""; |  | ||||||
|     } |  | ||||||
|     idx += 1; |  | ||||||
|   } |   } | ||||||
|   return ""; |   if (prev && it != workspaces_.begin()) | ||||||
|  |     --it; | ||||||
|  |   else if (!prev && it != workspaces_.end()) | ||||||
|  |     ++it; | ||||||
|  |   if (!prev && it == workspaces_.end()) { | ||||||
|  |     return (*(++workspaces_.begin()))["name"].asString(); | ||||||
|  |   } | ||||||
|  |   return (*it)["name"].asString(); | ||||||
| } | } | ||||||
|  |  | ||||||
| uint16_t waybar::modules::sway::Workspaces::getWorkspaceIndex(const std::string &name) const | std::string Workspaces::trimWorkspaceName(std::string name) { | ||||||
| { |  | ||||||
|   uint16_t idx = 0; |  | ||||||
|   for (const auto &workspace : workspaces_) { |  | ||||||
|     if (workspace["name"].asString() == name) { |  | ||||||
|       return idx; |  | ||||||
|     } |  | ||||||
|     if (!(!config_["all-outputs"].asBool() && workspace["output"].asString() != bar_.output_name)) { |  | ||||||
|       idx += 1; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   return workspaces_.size(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| std::string waybar::modules::sway::Workspaces::trimWorkspaceName(std::string name) |  | ||||||
| { |  | ||||||
|   std::size_t found = name.find(":"); |   std::size_t found = name.find(":"); | ||||||
|   if (found!=std::string::npos) { |   if (found != std::string::npos) { | ||||||
|     return name.substr(found+1); |     return name.substr(found + 1); | ||||||
|   } |   } | ||||||
|   return name; |   return name; | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::sway::Workspaces::onButtonReady(const Json::Value& node, Gtk::Button& button) | void Workspaces::onButtonReady(const Json::Value &node, Gtk::Button &button) { | ||||||
| { |   if (config_["current-only"].asBool()) { | ||||||
| 	if (config_["current-only"].asBool()) { |     if (node["focused"].asBool()) { | ||||||
| 		if (node["focused"].asBool()) { |       button.show(); | ||||||
| 			button.show(); |     } else { | ||||||
| 		} else { |       button.hide(); | ||||||
| 			button.hide(); |     } | ||||||
| 		} |   } else { | ||||||
| 	} else { |     button.show(); | ||||||
| 		button.show(); |   } | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| waybar::modules::sway::Workspaces::operator Gtk::Widget &() { | Workspaces::operator Gtk::Widget &() { return box_; } | ||||||
|   return box_; |  | ||||||
| } | }  // namespace waybar::modules::sway | ||||||
| @@ -1,13 +1,11 @@ | |||||||
| #include "modules/temperature.hpp" | #include "modules/temperature.hpp" | ||||||
|  |  | ||||||
| waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config) | waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config) | ||||||
|   : ALabel(config, "{temperatureC}°C", 10) |     : ALabel(config, "{temperatureC}°C", 10) { | ||||||
| { |  | ||||||
|   if (config_["hwmon-path"].isString()) { |   if (config_["hwmon-path"].isString()) { | ||||||
|     file_path_ = config_["hwmon-path"].asString(); |     file_path_ = config_["hwmon-path"].asString(); | ||||||
|   } else { |   } else { | ||||||
|     auto zone = |     auto zone = config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0; | ||||||
|       config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0; |  | ||||||
|     file_path_ = fmt::format("/sys/class/thermal/thermal_zone{}/temp", zone); |     file_path_ = fmt::format("/sys/class/thermal/thermal_zone{}/temp", zone); | ||||||
|   } |   } | ||||||
| #ifdef FILESYSTEM_EXPERIMENTAL | #ifdef FILESYSTEM_EXPERIMENTAL | ||||||
| @@ -27,24 +25,21 @@ waybar::modules::Temperature::Temperature(const std::string& id, const Json::Val | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| auto waybar::modules::Temperature::update() -> void | auto waybar::modules::Temperature::update() -> void { | ||||||
| { |  | ||||||
|   auto [temperature_c, temperature_f] = getTemperature(); |   auto [temperature_c, temperature_f] = getTemperature(); | ||||||
|   auto critical = isCritical(temperature_c); |   auto critical = isCritical(temperature_c); | ||||||
|   auto format = format_; |   auto format = format_; | ||||||
|   if (critical) { |   if (critical) { | ||||||
|     format = |     format = config_["format-critical"].isString() ? config_["format-critical"].asString() : format; | ||||||
|       config_["format-critical"].isString() ? config_["format-critical"].asString() : format; |  | ||||||
|     label_.get_style_context()->add_class("critical"); |     label_.get_style_context()->add_class("critical"); | ||||||
|   } else { |   } else { | ||||||
|     label_.get_style_context()->remove_class("critical"); |     label_.get_style_context()->remove_class("critical"); | ||||||
|   } |   } | ||||||
|   label_.set_markup(fmt::format(format, |   label_.set_markup(fmt::format( | ||||||
|     fmt::arg("temperatureC", temperature_c), fmt::arg("temperatureF", temperature_f))); |       format, fmt::arg("temperatureC", temperature_c), fmt::arg("temperatureF", temperature_f))); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::tuple<uint16_t, uint16_t> waybar::modules::Temperature::getTemperature() | std::tuple<uint16_t, uint16_t> waybar::modules::Temperature::getTemperature() { | ||||||
| { |  | ||||||
|   std::ifstream temp(file_path_); |   std::ifstream temp(file_path_); | ||||||
|   if (!temp.is_open()) { |   if (!temp.is_open()) { | ||||||
|     throw std::runtime_error("Can't open " + file_path_); |     throw std::runtime_error("Can't open " + file_path_); | ||||||
| @@ -54,13 +49,13 @@ std::tuple<uint16_t, uint16_t> waybar::modules::Temperature::getTemperature() | |||||||
|     getline(temp, line); |     getline(temp, line); | ||||||
|   } |   } | ||||||
|   temp.close(); |   temp.close(); | ||||||
|   auto temperature_c = std::strtol(line.c_str(), nullptr, 10) / 1000.0; |   auto                           temperature_c = std::strtol(line.c_str(), nullptr, 10) / 1000.0; | ||||||
|   auto temperature_f = temperature_c * 1.8 + 32; |   auto                           temperature_f = temperature_c * 1.8 + 32; | ||||||
|   std::tuple<uint16_t, uint16_t> temperatures(std::round(temperature_c), std::round(temperature_f)); |   std::tuple<uint16_t, uint16_t> temperatures(std::round(temperature_c), std::round(temperature_f)); | ||||||
|   return temperatures; |   return temperatures; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool waybar::modules::Temperature::isCritical(uint16_t temperature_c) | bool waybar::modules::Temperature::isCritical(uint16_t temperature_c) { | ||||||
| { |   return config_["critical-threshold"].isInt() && | ||||||
|   return config_["critical-threshold"].isInt() && temperature_c >= config_["critical-threshold"].asInt(); |          temperature_c >= config_["critical-threshold"].asInt(); | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user
	 Alex
					Alex