mirror of
				https://github.com/rad4day/Waybar.git
				synced 2025-10-25 23:22:28 +02:00 
			
		
		
		
	refactor: proper modules destruction
This commit is contained in:
		| @@ -18,6 +18,7 @@ class Bar { | |||||||
|   public: |   public: | ||||||
|     Bar(const Client&, std::unique_ptr<struct wl_output *>&&, uint32_t); |     Bar(const Client&, std::unique_ptr<struct wl_output *>&&, uint32_t); | ||||||
|     Bar(const Bar&) = delete; |     Bar(const Bar&) = delete; | ||||||
|  |     ~Bar() = default; | ||||||
|  |  | ||||||
|     auto toggle() -> void; |     auto toggle() -> void; | ||||||
|  |  | ||||||
| @@ -54,6 +55,10 @@ class Bar { | |||||||
|     Glib::RefPtr<Gtk::StyleContext> style_context_; |     Glib::RefPtr<Gtk::StyleContext> style_context_; | ||||||
|     Glib::RefPtr<Gtk::CssProvider> css_provider_; |     Glib::RefPtr<Gtk::CssProvider> css_provider_; | ||||||
|     struct zxdg_output_v1 *xdg_output_; |     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_left_; | ||||||
|     std::vector<std::unique_ptr<waybar::IModule>> modules_center_; |     std::vector<std::unique_ptr<waybar::IModule>> modules_center_; | ||||||
|     std::vector<std::unique_ptr<waybar::IModule>> modules_right_; |     std::vector<std::unique_ptr<waybar::IModule>> modules_right_; | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <sys/inotify.h> | #include <sys/inotify.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "fmt/time.h" | #include "fmt/time.h" | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
| @@ -10,6 +10,7 @@ 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; | ||||||
|     auto update() -> void; |     auto update() -> void; | ||||||
|   private: |   private: | ||||||
|     waybar::util::SleeperThread thread_; |     waybar::util::SleeperThread thread_; | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
| #include <vector> | #include <vector> | ||||||
| #include <numeric> | #include <numeric> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
| @@ -14,6 +14,7 @@ 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; | ||||||
|     auto update() -> void; |     auto update() -> void; | ||||||
|   private: |   private: | ||||||
|     static inline const std::string data_dir_ = "/proc/stat"; |     static inline const std::string data_dir_ = "/proc/stat"; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "util/command.hpp" | #include "util/command.hpp" | ||||||
| #include "util/json.hpp" | #include "util/json.hpp" | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <fstream> | #include <fstream> | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
| @@ -10,6 +10,7 @@ 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; | ||||||
|     auto update() -> void; |     auto update() -> void; | ||||||
|   private: |   private: | ||||||
|     static inline const std::string data_dir_ = "/proc/meminfo"; |     static inline const std::string data_dir_ = "/proc/meminfo"; | ||||||
|   | |||||||
| @@ -7,8 +7,9 @@ | |||||||
| #include <netlink/genl/genl.h> | #include <netlink/genl/genl.h> | ||||||
| #include <netlink/genl/ctrl.h> | #include <netlink/genl/ctrl.h> | ||||||
| #include <linux/nl80211.h> | #include <linux/nl80211.h> | ||||||
|  | #include <sys/epoll.h> | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
|  |  | ||||||
| namespace waybar::modules { | namespace waybar::modules { | ||||||
| @@ -19,15 +20,17 @@ class Network : public ALabel { | |||||||
|     ~Network(); |     ~Network(); | ||||||
|     auto update() -> void; |     auto update() -> void; | ||||||
|   private: |   private: | ||||||
|     static int netlinkRequest(int, void*, uint32_t, uint32_t groups = 0); |     static int handleEvents(struct nl_msg*, void*); | ||||||
|     static int netlinkResponse(int, void*, uint32_t, uint32_t groups = 0); |     static int handleScan(struct nl_msg*, void*); | ||||||
|     static int scanCb(struct nl_msg*, void*); |  | ||||||
|  |  | ||||||
|     void worker(); |     void worker(); | ||||||
|     void disconnected(); |     void disconnected(); | ||||||
|     void initNL80211(); |     void createInfoSocket(); | ||||||
|  |     void createEventSocket(); | ||||||
|     int getExternalInterface(); |     int getExternalInterface(); | ||||||
|     void getInterfaceAddress(); |     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 parseEssid(struct nlattr**); | ||||||
|     void parseSignal(struct nlattr**); |     void parseSignal(struct nlattr**); | ||||||
|     bool associatedOrJoined(struct nlattr**); |     bool associatedOrJoined(struct nlattr**); | ||||||
| @@ -37,9 +40,11 @@ class Network : public ALabel { | |||||||
|     waybar::util::SleeperThread thread_timer_; |     waybar::util::SleeperThread thread_timer_; | ||||||
|     int ifid_; |     int ifid_; | ||||||
|     sa_family_t family_; |     sa_family_t family_; | ||||||
|     int sock_fd_; |  | ||||||
|     struct sockaddr_nl nladdr_ = {0}; |     struct sockaddr_nl nladdr_ = {0}; | ||||||
|     struct nl_sock* sk_ = nullptr; |     struct nl_sock* sk_ = nullptr; | ||||||
|  |     struct nl_sock* info_sock_ = nullptr; | ||||||
|  |     int efd_; | ||||||
|  |     int ev_fd_; | ||||||
|     int nl80211_id_; |     int nl80211_id_; | ||||||
|  |  | ||||||
|     std::string essid_; |     std::string essid_; | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <thread> |  | ||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
| #include "util/json.hpp" | #include "util/json.hpp" | ||||||
| #include "IModule.hpp" | #include "IModule.hpp" | ||||||
| @@ -13,6 +12,7 @@ namespace waybar::modules::SNI { | |||||||
| class Tray : public IModule { | class Tray : public IModule { | ||||||
|   public: |   public: | ||||||
|     Tray(const std::string&, const Json::Value&); |     Tray(const std::string&, const Json::Value&); | ||||||
|  |     ~Tray() = default; | ||||||
|     auto update() -> void; |     auto update() -> void; | ||||||
|     operator Gtk::Widget &(); |     operator Gtk::Widget &(); | ||||||
|   private: |   private: | ||||||
| @@ -20,7 +20,6 @@ class Tray : public IModule { | |||||||
|     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; | ||||||
|     std::thread thread_; |  | ||||||
|     const Json::Value& config_; |     const Json::Value& config_; | ||||||
|     Gtk::Box box_; |     Gtk::Box box_; | ||||||
|     SNI::Watcher watcher_ ; |     SNI::Watcher watcher_ ; | ||||||
|   | |||||||
| @@ -10,33 +10,31 @@ | |||||||
| 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; | ||||||
| 		}; |   }; | ||||||
|  |  | ||||||
| 		void connect(); |   struct ipc_response sendCmd(uint32_t type, const std::string &payload = "") const; | ||||||
| 		struct ipc_response sendCmd(uint32_t type, |   void subscribe(const std::string &payload) const; | ||||||
| 			const std::string& payload = "") const; |   struct ipc_response handleEvent() const; | ||||||
| 		void subscribe(const std::string& payload) const; |  | ||||||
| 		struct ipc_response handleEvent() const; |  | ||||||
|   protected: |  | ||||||
| 		static inline const std::string ipc_magic_ = "i3-ipc"; |  | ||||||
| 		static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8; |  | ||||||
|  |  | ||||||
| 		const std::string getSocketPath() const; | protected: | ||||||
| 		int open(const std::string&) const; |   static inline const std::string ipc_magic_ = "i3-ipc"; | ||||||
| 		struct ipc_response send(int fd, uint32_t type, |   static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8; | ||||||
| 			const std::string& payload = "") const; |  | ||||||
| 		struct ipc_response recv(int fd) const; |  | ||||||
|  |  | ||||||
| 		int fd_; |   const std::string getSocketPath() const; | ||||||
| 		int fd_event_; |   int open(const std::string &) const; | ||||||
|  |   struct ipc_response send(int fd, uint32_t type, const std::string &payload = "") const; | ||||||
|  |   struct ipc_response recv(int fd) const; | ||||||
|  |  | ||||||
|  |   int fd_; | ||||||
|  |   int fd_event_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | } // namespace waybar::modules::sway | ||||||
|   | |||||||
| @@ -3,30 +3,30 @@ | |||||||
| #define event_mask(ev) (1u << (ev & 0x7F)) | #define event_mask(ev) (1u << (ev & 0x7F)) | ||||||
|  |  | ||||||
| enum ipc_command_type { | enum ipc_command_type { | ||||||
| 	// i3 command types - see i3's I3_REPLY_TYPE constants |   // i3 command types - see i3's I3_REPLY_TYPE constants | ||||||
| 	IPC_COMMAND = 0, |   IPC_COMMAND = 0, | ||||||
| 	IPC_GET_WORKSPACES = 1, |   IPC_GET_WORKSPACES = 1, | ||||||
| 	IPC_SUBSCRIBE = 2, |   IPC_SUBSCRIBE = 2, | ||||||
| 	IPC_GET_OUTPUTS = 3, |   IPC_GET_OUTPUTS = 3, | ||||||
| 	IPC_GET_TREE = 4, |   IPC_GET_TREE = 4, | ||||||
| 	IPC_GET_MARKS = 5, |   IPC_GET_MARKS = 5, | ||||||
| 	IPC_GET_BAR_CONFIG = 6, |   IPC_GET_BAR_CONFIG = 6, | ||||||
| 	IPC_GET_VERSION = 7, |   IPC_GET_VERSION = 7, | ||||||
| 	IPC_GET_BINDING_MODES = 8, |   IPC_GET_BINDING_MODES = 8, | ||||||
| 	IPC_GET_CONFIG = 9, |   IPC_GET_CONFIG = 9, | ||||||
| 	IPC_SEND_TICK = 10, |   IPC_SEND_TICK = 10, | ||||||
|  |  | ||||||
| 	// sway-specific command types |   // sway-specific command types | ||||||
| 	IPC_GET_INPUTS = 100, |   IPC_GET_INPUTS = 100, | ||||||
| 	IPC_GET_SEATS = 101, |   IPC_GET_SEATS = 101, | ||||||
|  |  | ||||||
| 	// Events sent from sway to clients. Events have the highest bits set. |   // Events sent from sway to clients. Events have the highest bits set. | ||||||
| 	IPC_EVENT_WORKSPACE = ((1<<31) | 0), |   IPC_EVENT_WORKSPACE = ((1 << 31) | 0), | ||||||
| 	IPC_EVENT_OUTPUT = ((1<<31) | 1), |   IPC_EVENT_OUTPUT = ((1 << 31) | 1), | ||||||
| 	IPC_EVENT_MODE = ((1<<31) | 2), |   IPC_EVENT_MODE = ((1 << 31) | 2), | ||||||
| 	IPC_EVENT_WINDOW = ((1<<31) | 3), |   IPC_EVENT_WINDOW = ((1 << 31) | 3), | ||||||
| 	IPC_EVENT_BARCONFIG_UPDATE = ((1<<31) | 4), |   IPC_EVENT_BARCONFIG_UPDATE = ((1 << 31) | 4), | ||||||
| 	IPC_EVENT_BINDING = ((1<<31) | 5), |   IPC_EVENT_BINDING = ((1 << 31) | 5), | ||||||
| 	IPC_EVENT_SHUTDOWN = ((1<<31) | 6), |   IPC_EVENT_SHUTDOWN = ((1 << 31) | 6), | ||||||
| 	IPC_EVENT_TICK = ((1<<31) | 7), |   IPC_EVENT_TICK = ((1 << 31) | 7), | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "util/json.hpp" | #include "util/json.hpp" | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
| #include "modules/sway/ipc/client.hpp" | #include "modules/sway/ipc/client.hpp" | ||||||
| @@ -13,6 +13,7 @@ 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; | ||||||
|     auto update() -> void; |     auto update() -> void; | ||||||
|   private: |   private: | ||||||
|     void worker(); |     void worker(); | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
| #include <tuple> | #include <tuple> | ||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "util/json.hpp" | #include "util/json.hpp" | ||||||
| #include "ALabel.hpp" | #include "ALabel.hpp" | ||||||
| #include "modules/sway/ipc/client.hpp" | #include "modules/sway/ipc/client.hpp" | ||||||
| @@ -14,6 +14,7 @@ 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; | ||||||
|     auto update() -> void; |     auto update() -> void; | ||||||
|   private: |   private: | ||||||
|     void worker(); |     void worker(); | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "bar.hpp" | #include "bar.hpp" | ||||||
| #include "client.hpp" | #include "client.hpp" | ||||||
| #include "util/chrono.hpp" | #include "util/sleeper_thread.hpp" | ||||||
| #include "util/json.hpp" | #include "util/json.hpp" | ||||||
| #include "IModule.hpp" | #include "IModule.hpp" | ||||||
| #include "modules/sway/ipc/client.hpp" | #include "modules/sway/ipc/client.hpp" | ||||||
| @@ -14,6 +14,7 @@ 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; | ||||||
|     auto update() -> void; |     auto update() -> void; | ||||||
|     operator Gtk::Widget &(); |     operator Gtk::Widget &(); | ||||||
|   private: |   private: | ||||||
| @@ -27,14 +28,14 @@ class Workspaces : public IModule { | |||||||
|  |  | ||||||
|     const Bar& bar_; |     const Bar& bar_; | ||||||
|     const Json::Value& config_; |     const Json::Value& config_; | ||||||
|  |     Json::Value workspaces_; | ||||||
|     waybar::util::SleeperThread thread_; |     waybar::util::SleeperThread thread_; | ||||||
|     Gtk::Box box_; |     Gtk::Box box_; | ||||||
|     util::JsonParser parser_; |     util::JsonParser parser_; | ||||||
|  |     Ipc ipc_; | ||||||
|     std::mutex mutex_; |     std::mutex mutex_; | ||||||
|     bool scrolling_; |     bool scrolling_; | ||||||
|     std::unordered_map<std::string, Gtk::Button> buttons_; |     std::unordered_map<std::string, Gtk::Button> buttons_; | ||||||
|     Json::Value workspaces_; |  | ||||||
|     Ipc ipc_; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| #include <sys/wait.h> | #include <sys/wait.h> | ||||||
| #include <giomm.h> | #include <giomm.h> | ||||||
|  | #include <unistd.h> | ||||||
|  |  | ||||||
| namespace waybar::util::command { | namespace waybar::util::command { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ struct JsonParser { | |||||||
|     : reader_(builder_.newCharReader()) |     : reader_(builder_.newCharReader()) | ||||||
|   {} |   {} | ||||||
|  |  | ||||||
|   const Json::Value parse(const std::string data) const |   const Json::Value parse(const std::string& data) const | ||||||
|   { |   { | ||||||
|     Json::Value root; |     Json::Value root; | ||||||
|     std::string err; |     std::string err; | ||||||
|   | |||||||
| @@ -6,30 +6,20 @@ | |||||||
| #include <condition_variable> | #include <condition_variable> | ||||||
| #include <thread> | #include <thread> | ||||||
| 
 | 
 | ||||||
| namespace waybar::chrono { |  | ||||||
| 
 |  | ||||||
| using namespace std::chrono; |  | ||||||
| 
 |  | ||||||
| using clock = std::chrono::system_clock; |  | ||||||
| using duration = clock::duration; |  | ||||||
| using time_point = std::chrono::time_point<clock, duration>; |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| namespace waybar::util { | namespace waybar::util { | ||||||
| 
 | 
 | ||||||
| struct SleeperThread { | class SleeperThread { | ||||||
|  | public: | ||||||
|   SleeperThread() = default; |   SleeperThread() = default; | ||||||
| 
 | 
 | ||||||
|   SleeperThread(std::function<void()> func) |   SleeperThread(std::function<void()> func) | ||||||
|     : do_run_(true), 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) | ||||||
|   { |   { | ||||||
|     do_run_ = true; |  | ||||||
|     thread_ = std::thread([this, func] { |     thread_ = std::thread([this, func] { | ||||||
|       while (do_run_) func(); |       while (do_run_) func(); | ||||||
|     }); |     }); | ||||||
| @@ -41,16 +31,17 @@ struct SleeperThread { | |||||||
|     return do_run_; |     return do_run_; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   auto sleep_for(chrono::duration dur) |   auto sleep_for(std::chrono::system_clock::duration dur) | ||||||
|   { |   { | ||||||
|     auto lock = std::unique_lock(mutex_); |     std::unique_lock lk(mutex_); | ||||||
|     return condvar_.wait_for(lock, dur); |     return condvar_.wait_for(lk, dur, [this] { return !do_run_; }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   auto sleep_until(chrono::time_point time) |   auto sleep_until(std::chrono::time_point<std::chrono::system_clock, | ||||||
|  |     std::chrono::system_clock::duration> time_point) | ||||||
|   { |   { | ||||||
|     auto lock = std::unique_lock(mutex_); |     std::unique_lock lk(mutex_); | ||||||
|     return condvar_.wait_until(lock, time); |     return condvar_.wait_until(lk, time_point, [this] { return !do_run_; }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   auto wake_up() |   auto wake_up() | ||||||
| @@ -60,7 +51,10 @@ struct SleeperThread { | |||||||
| 
 | 
 | ||||||
|   auto stop() |   auto stop() | ||||||
|   { |   { | ||||||
|     do_run_ = false; |     { | ||||||
|  |       std::lock_guard<std::mutex> lck(mutex_); | ||||||
|  |       do_run_ = false; | ||||||
|  |     } | ||||||
|     condvar_.notify_all(); |     condvar_.notify_all(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @@ -68,15 +62,15 @@ struct SleeperThread { | |||||||
|   { |   { | ||||||
|     stop(); |     stop(); | ||||||
|     if (thread_.joinable()) { |     if (thread_.joinable()) { | ||||||
|       thread_.detach(); |       thread_.join(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|   bool do_run_ = false; |  | ||||||
|   std::thread thread_; |   std::thread thread_; | ||||||
|   std::condition_variable condvar_; |   std::condition_variable condvar_; | ||||||
|   std::mutex mutex_; |   std::mutex mutex_; | ||||||
|  |   bool do_run_ = true; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
							
								
								
									
										12
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								meson.build
									
									
									
									
									
								
							| @@ -9,7 +9,7 @@ project( | |||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
| cpp_args = ['-DVERSION="@0@"'.format(meson.project_version())] | cpp_args = [] | ||||||
| cpp_link_args = [] | cpp_link_args = [] | ||||||
|  |  | ||||||
| if false # libc++ | if false # libc++ | ||||||
| @@ -22,6 +22,16 @@ else | |||||||
| endif | endif | ||||||
|  |  | ||||||
| compiler = meson.get_compiler('cpp') | compiler = meson.get_compiler('cpp') | ||||||
|  | git = find_program('git', required: false) | ||||||
|  |  | ||||||
|  | if not git.found() | ||||||
|  |     add_project_arguments('-DVERSION="@0@"'.format(meson.project_version()), language: 'cpp') | ||||||
|  | else | ||||||
|  |     git_commit_hash = run_command([git.path(), 'describe', '--always', '--tags']).stdout().strip() | ||||||
|  |     git_branch = run_command([git.path(), 'rev-parse', '--abbrev-ref', 'HEAD']).stdout().strip() | ||||||
|  |     version = '"@0@ (" __DATE__ ", branch \'@1@\')"'.format(git_commit_hash, git_branch) | ||||||
|  |     add_project_arguments('-DVERSION=@0@'.format(version), language: 'cpp') | ||||||
|  | endif | ||||||
|  |  | ||||||
| if not compiler.has_header('filesystem') | if not compiler.has_header('filesystem') | ||||||
|     add_project_arguments('-DFILESYSTEM_EXPERIMENTAL', language: 'cpp') |     add_project_arguments('-DFILESYSTEM_EXPERIMENTAL', language: 'cpp') | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								src/bar.cpp
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								src/bar.cpp
									
									
									
									
									
								
							| @@ -7,7 +7,9 @@ waybar::Bar::Bar(const Client& client, | |||||||
|   std::unique_ptr<struct wl_output *> &&p_output, uint32_t p_wl_name) |   std::unique_ptr<struct wl_output *> &&p_output, uint32_t p_wl_name) | ||||||
|   : client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL}, |   : client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL}, | ||||||
|     surface(nullptr), layer_surface(nullptr), |     surface(nullptr), layer_surface(nullptr), | ||||||
|     output(std::move(p_output)), wl_name(p_wl_name) |     output(std::move(p_output)), wl_name(p_wl_name), | ||||||
|  |     left_(Gtk::ORIENTATION_HORIZONTAL, 0), center_(Gtk::ORIENTATION_HORIZONTAL, 0), | ||||||
|  |     right_(Gtk::ORIENTATION_HORIZONTAL, 0), box_(Gtk::ORIENTATION_HORIZONTAL, 0) | ||||||
| { | { | ||||||
|   static const struct zxdg_output_v1_listener xdgOutputListener = { |   static const struct zxdg_output_v1_listener xdgOutputListener = { | ||||||
|     .logical_position = handleLogicalPosition, |     .logical_position = handleLogicalPosition, | ||||||
| @@ -200,28 +202,23 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos) | |||||||
|  |  | ||||||
| auto waybar::Bar::setupWidgets() -> void | auto waybar::Bar::setupWidgets() -> void | ||||||
| { | { | ||||||
|   auto &left = *Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 0)); |   window.add(box_); | ||||||
|   auto ¢er = *Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 0)); |   box_.pack_start(left_, true, true); | ||||||
|   auto &right = *Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 0)); |   box_.set_center_widget(center_); | ||||||
|  |   box_.pack_end(right_, true, true); | ||||||
|   auto &box = *Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 0)); |  | ||||||
|   window.add(box); |  | ||||||
|   box.pack_start(left, true, true); |  | ||||||
|   box.set_center_widget(center); |  | ||||||
|   box.pack_end(right, true, true); |  | ||||||
|  |  | ||||||
|   Factory factory(*this, config_); |   Factory factory(*this, 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"); | ||||||
|   for (auto const& module : modules_left_) { |   for (auto const& module : modules_left_) { | ||||||
|     left.pack_start(*module, false, true, 0); |     left_.pack_start(*module, false, true, 0); | ||||||
|   } |   } | ||||||
|   for (auto const& module : modules_center_) { |   for (auto const& module : modules_center_) { | ||||||
|     center.pack_start(*module, true, true, 0); |     center_.pack_start(*module, true, true, 0); | ||||||
|   } |   } | ||||||
|   std::reverse(modules_right_.begin(), modules_right_.end()); |   std::reverse(modules_right_.begin(), modules_right_.end()); | ||||||
|   for (auto const& module : modules_right_) { |   for (auto const& module : modules_right_) { | ||||||
|     right.pack_end(*module, false, false, 0); |     right_.pack_end(*module, false, false, 0); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) | |||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
|   } |   } | ||||||
|   thread_ = [this] { |   thread_ = [this] { | ||||||
|     auto now = waybar::chrono::clock::now(); |     auto now = std::chrono::system_clock::now(); | ||||||
|     dp.emit(); |     dp.emit(); | ||||||
|     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); | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ 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(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; | ||||||
|   | |||||||
| @@ -1,23 +1,16 @@ | |||||||
|  | #include <sys/eventfd.h> | ||||||
| #include "modules/network.hpp" | #include "modules/network.hpp" | ||||||
|  |  | ||||||
| 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), |   : ALabel(config, "{ifname}", 60), family_(AF_INET), efd_(-1), ev_fd_(-1), | ||||||
|     cidr_(-1), signal_strength_dbm_(0), signal_strength_(0) |     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); | ||||||
|   } |   } | ||||||
|   sock_fd_ = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); |   createInfoSocket(); | ||||||
|   if (sock_fd_ < 0) { |   createEventSocket(); | ||||||
|     throw std::runtime_error("Can't open network socket"); |  | ||||||
|   } |  | ||||||
|   nladdr_.nl_family = AF_NETLINK; |  | ||||||
|   nladdr_.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR; |  | ||||||
|   if (bind(sock_fd_, reinterpret_cast<struct sockaddr *>(&nladdr_), |  | ||||||
|     sizeof(nladdr_)) != 0) { |  | ||||||
|     throw std::runtime_error("Can't bind network socket"); |  | ||||||
|   } |  | ||||||
|   if (config_["interface"].isString()) { |   if (config_["interface"].isString()) { | ||||||
|     ifid_ = if_nametoindex(config_["interface"].asCString()); |     ifid_ = if_nametoindex(config_["interface"].asCString()); | ||||||
|     ifname_ = config_["interface"].asString(); |     ifname_ = config_["interface"].asString(); | ||||||
| @@ -32,73 +25,112 @@ waybar::modules::Network::Network(const std::string& id, const Json::Value& conf | |||||||
|       ifname_ = ifname; |       ifname_ = ifname; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   initNL80211(); |  | ||||||
|   // Trigger first values |  | ||||||
|   getInfo(); |  | ||||||
|   dp.emit(); |   dp.emit(); | ||||||
|   worker(); |   worker(); | ||||||
| } | } | ||||||
|  |  | ||||||
| waybar::modules::Network::~Network() | waybar::modules::Network::~Network() | ||||||
| { | { | ||||||
|   close(sock_fd_); |   if (ev_fd_ > -1) { | ||||||
|   nl_socket_free(sk_); |     eventfd_write(ev_fd_, 1); | ||||||
|  |     std::this_thread::sleep_for(std::chrono::milliseconds(150)); | ||||||
|  |     close(ev_fd_); | ||||||
|  |   } | ||||||
|  |   if (efd_ > -1) { | ||||||
|  |     close(efd_); | ||||||
|  |   } | ||||||
|  |   if (info_sock_ != nullptr) { | ||||||
|  |     nl_socket_drop_membership(info_sock_, RTMGRP_LINK); | ||||||
|  |     nl_socket_drop_membership(info_sock_, RTMGRP_IPV4_IFADDR); | ||||||
|  |     nl_close(info_sock_); | ||||||
|  |     nl_socket_free(info_sock_); | ||||||
|  |   } | ||||||
|  |   if (sk_ != nullptr) { | ||||||
|  |     nl_close(sk_); | ||||||
|  |     nl_socket_free(sk_); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void waybar::modules::Network::createInfoSocket() | ||||||
|  | { | ||||||
|  |   info_sock_ = nl_socket_alloc(); | ||||||
|  |   if (nl_connect(info_sock_, NETLINK_ROUTE) != 0) { | ||||||
|  | 		throw std::runtime_error("Can't connect network socket"); | ||||||
|  | 	} | ||||||
|  |   if (nl_socket_add_membership(info_sock_, RTMGRP_LINK) != 0) { | ||||||
|  |     throw std::runtime_error("Can't add membership"); | ||||||
|  |   } | ||||||
|  |   if (nl_socket_add_membership(info_sock_, RTMGRP_IPV4_IFADDR) != 0) { | ||||||
|  |     throw std::runtime_error("Can't add membership"); | ||||||
|  |   } | ||||||
|  |   nl_socket_disable_seq_check(info_sock_); | ||||||
|  |   nl_socket_set_nonblocking(info_sock_); | ||||||
|  |   nl_socket_modify_cb(info_sock_, NL_CB_MSG_IN, NL_CB_CUSTOM, handleEvents, this); | ||||||
|  |   efd_ = epoll_create1(0); | ||||||
|  |   if (efd_ < 0) { | ||||||
|  |     throw std::runtime_error("Can't create epoll"); | ||||||
|  |   } | ||||||
|  |   { | ||||||
|  |     ev_fd_ = eventfd(0, EFD_NONBLOCK); | ||||||
|  |     struct epoll_event event; | ||||||
|  |     event.events = EPOLLIN | EPOLLET; | ||||||
|  |     event.data.fd = ev_fd_; | ||||||
|  |     if (epoll_ctl(efd_, EPOLL_CTL_ADD, ev_fd_, &event) == -1) { | ||||||
|  |       throw std::runtime_error("Can't add epoll event"); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   { | ||||||
|  |     auto fd = nl_socket_get_fd(info_sock_); | ||||||
|  |     struct epoll_event event; | ||||||
|  |     event.events = EPOLLIN; | ||||||
|  |     event.data.fd = fd; | ||||||
|  |     if (epoll_ctl(efd_, EPOLL_CTL_ADD, fd, &event) == -1) { | ||||||
|  |       throw std::runtime_error("Can't add epoll event"); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void waybar::modules::Network::createEventSocket() | ||||||
|  | { | ||||||
|  |   sk_ = nl_socket_alloc(); | ||||||
|  | 	if (genl_connect(sk_) != 0) { | ||||||
|  |     throw std::runtime_error("Can't connect to netlink socket"); | ||||||
|  |   } | ||||||
|  |   nl_socket_disable_seq_check(sk_); | ||||||
|  |   if (nl_socket_modify_cb(sk_, NL_CB_VALID, NL_CB_CUSTOM, handleScan, this) < 0) { | ||||||
|  |     throw std::runtime_error("Can't set callback"); | ||||||
|  |   } | ||||||
|  |   nl80211_id_ = genl_ctrl_resolve(sk_, "nl80211"); | ||||||
|  |   if (nl80211_id_ < 0) { | ||||||
|  |     throw std::runtime_error("Can't resolve nl80211 interface"); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Network::worker() | void waybar::modules::Network::worker() | ||||||
| { | { | ||||||
|   thread_ = [this] { |  | ||||||
|     char buf[4096]; |  | ||||||
|     auto len = netlinkResponse(sock_fd_, buf, sizeof(buf), RTMGRP_LINK | RTMGRP_IPV4_IFADDR); |  | ||||||
|     if (len == 0) { |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     bool need_update = false; |  | ||||||
|     for (auto nh = reinterpret_cast<struct nlmsghdr *>(buf); NLMSG_OK(nh, len); |  | ||||||
|       nh = NLMSG_NEXT(nh, len)) { |  | ||||||
|       if (nh->nlmsg_type == NLMSG_DONE) { |  | ||||||
|         break; |  | ||||||
|       } |  | ||||||
|       if (nh->nlmsg_type == NLMSG_ERROR) { |  | ||||||
|         continue; |  | ||||||
|       } |  | ||||||
|       if (nh->nlmsg_type == RTM_NEWADDR) { |  | ||||||
|         need_update = true; |  | ||||||
|       } |  | ||||||
|       if (nh->nlmsg_type < RTM_NEWADDR) { |  | ||||||
|         auto rtif = static_cast<struct ifinfomsg *>(NLMSG_DATA(nh)); |  | ||||||
|         if (rtif->ifi_index == static_cast<int>(ifid_)) { |  | ||||||
|           need_update = true; |  | ||||||
|           if (!(rtif->ifi_flags & IFF_RUNNING)) { |  | ||||||
|             disconnected(); |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if (ifid_ <= 0 && !config_["interface"].isString()) { |  | ||||||
|       // Need to wait before get external interface |  | ||||||
|       thread_.sleep_for(std::chrono::seconds(1)); |  | ||||||
|       ifid_ = getExternalInterface(); |  | ||||||
|       if (ifid_ > 0) { |  | ||||||
|         char ifname[IF_NAMESIZE]; |  | ||||||
|         if_indextoname(ifid_, ifname); |  | ||||||
|         ifname_ = ifname; |  | ||||||
|         need_update = true; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if (need_update) { |  | ||||||
|       if (ifid_ > 0) { |  | ||||||
|         getInfo(); |  | ||||||
|       } |  | ||||||
|       dp.emit(); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|   thread_timer_ = [this] { |   thread_timer_ = [this] { | ||||||
|     thread_timer_.sleep_for(interval_); |  | ||||||
|     if (ifid_ > 0) { |     if (ifid_ > 0) { | ||||||
|       getInfo(); |       getInfo(); | ||||||
|       dp.emit(); |       dp.emit(); | ||||||
|     } |     } | ||||||
|  |     thread_timer_.sleep_for(interval_); | ||||||
|  |   }; | ||||||
|  |   thread_ = [this] { | ||||||
|  |     struct epoll_event events[16]; | ||||||
|  |     int ec = epoll_wait(efd_, events, 16, -1); | ||||||
|  |     if (ec > 0) { | ||||||
|  |       for (auto i = 0; i < ec; i++) { | ||||||
|  |         if (events[i].events & EPOLLIN | ||||||
|  |           && events[i].data.fd == nl_socket_get_fd(info_sock_)) { | ||||||
|  |           nl_recvmsgs_default(info_sock_); | ||||||
|  |         } else { | ||||||
|  |           thread_.stop(); | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } else if (ec == -1) { | ||||||
|  |       thread_.stop(); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -151,24 +183,6 @@ void waybar::modules::Network::disconnected() | |||||||
|   thread_.sleep_for(std::chrono::seconds(1)); |   thread_.sleep_for(std::chrono::seconds(1)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::Network::initNL80211() |  | ||||||
| { |  | ||||||
|   sk_ = nl_socket_alloc(); |  | ||||||
| 	if (genl_connect(sk_) != 0) { |  | ||||||
|     nl_socket_free(sk_); |  | ||||||
|     throw std::runtime_error("Can't connect to netlink socket"); |  | ||||||
|   } |  | ||||||
|   if (nl_socket_modify_cb(sk_, NL_CB_VALID, NL_CB_CUSTOM, scanCb, this) < 0) { |  | ||||||
|     nl_socket_free(sk_); |  | ||||||
|     throw std::runtime_error("Can't connect to netlink socket"); |  | ||||||
|   } |  | ||||||
|   nl80211_id_ = genl_ctrl_resolve(sk_, "nl80211"); |  | ||||||
|   if (nl80211_id_ < 0) { |  | ||||||
|     nl_socket_free(sk_); |  | ||||||
|     throw std::runtime_error("Can't resolve nl80211 interface"); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // 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() | ||||||
| { | { | ||||||
| @@ -192,7 +206,7 @@ int waybar::modules::Network::getExternalInterface() | |||||||
|   rt->rtm_table = RT_TABLE_MAIN; |   rt->rtm_table = RT_TABLE_MAIN; | ||||||
|  |  | ||||||
|   /* Issue the query. */ |   /* Issue the query. */ | ||||||
|   if (netlinkRequest(sock_fd_, req, reqlen) < 0) { |   if (netlinkRequest(req, reqlen) < 0) { | ||||||
|     goto out; |     goto out; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -202,7 +216,7 @@ int waybar::modules::Network::getExternalInterface() | |||||||
|    * consume responses till NLMSG_DONE/NLMSG_ERROR is encountered). |    * consume responses till NLMSG_DONE/NLMSG_ERROR is encountered). | ||||||
|    */ |    */ | ||||||
|   do { |   do { | ||||||
|     auto len = netlinkResponse(sock_fd_, resp, route_buffer_size); |     auto len = netlinkResponse(resp, route_buffer_size); | ||||||
|     if (len < 0) { |     if (len < 0) { | ||||||
|       goto out; |       goto out; | ||||||
|     } |     } | ||||||
| @@ -322,7 +336,7 @@ void waybar::modules::Network::getInterfaceAddress() { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::modules::Network::netlinkRequest(int fd, 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 = {}; | ||||||
| @@ -330,10 +344,10 @@ int waybar::modules::Network::netlinkRequest(int fd, void *req, | |||||||
|   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(fd, &msg, 0); |   return sendmsg(nl_socket_get_fd(info_sock_), &msg, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::modules::Network::netlinkResponse(int fd, 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 = {}; | ||||||
| @@ -341,14 +355,50 @@ int waybar::modules::Network::netlinkResponse(int fd, void *resp, | |||||||
|   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(fd, &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; | ||||||
|   } |   } | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| int waybar::modules::Network::scanCb(struct nl_msg *msg, void *data) { | int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { | ||||||
|  |   auto net = static_cast<waybar::modules::Network *>(data); | ||||||
|  |   bool need_update = false; | ||||||
|  |   nlmsghdr *nh = nlmsg_hdr(msg); | ||||||
|  |   if (nh->nlmsg_type == RTM_NEWADDR) { | ||||||
|  |     need_update = true; | ||||||
|  |   } | ||||||
|  |   if (nh->nlmsg_type < RTM_NEWADDR) { | ||||||
|  |     auto rtif = static_cast<struct ifinfomsg *>(NLMSG_DATA(nh)); | ||||||
|  |     if (rtif->ifi_index == static_cast<int>(net->ifid_)) { | ||||||
|  |       need_update = true; | ||||||
|  |       if (!(rtif->ifi_flags & IFF_RUNNING)) { | ||||||
|  |         net->disconnected(); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (net->ifid_ <= 0 && !net->config_["interface"].isString()) { | ||||||
|  |     // Need to wait before get external interface | ||||||
|  |     net->thread_.sleep_for(std::chrono::seconds(1)); | ||||||
|  |     net->ifid_ = net->getExternalInterface(); | ||||||
|  |     if (net->ifid_ > 0) { | ||||||
|  |       char ifname[IF_NAMESIZE]; | ||||||
|  |       if_indextoname(net->ifid_, ifname); | ||||||
|  |       net->ifname_ = ifname; | ||||||
|  |       need_update = true; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (need_update) { | ||||||
|  |     if (net->ifid_ > 0) { | ||||||
|  |       net->getInfo(); | ||||||
|  |     } | ||||||
|  |     net->dp.emit(); | ||||||
|  |   } | ||||||
|  |   return NL_SKIP; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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]; | ||||||
| @@ -404,7 +454,7 @@ void waybar::modules::Network::parseEssid(struct nlattr **bss) | |||||||
|  |  | ||||||
| void waybar::modules::Network::parseSignal(struct nlattr **bss) { | void waybar::modules::Network::parseSignal(struct nlattr **bss) { | ||||||
|   if (bss[NL80211_BSS_SIGNAL_MBM] != nullptr) { |   if (bss[NL80211_BSS_SIGNAL_MBM] != nullptr) { | ||||||
|     // signalstrength in dBm |     // signalstrength in dBm from mBm | ||||||
|     signal_strength_dbm_ = |     signal_strength_dbm_ = | ||||||
|       static_cast<int>(nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM])) / 100; |       static_cast<int>(nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM])) / 100; | ||||||
|  |  | ||||||
| @@ -414,6 +464,9 @@ void waybar::modules::Network::parseSignal(struct nlattr **bss) { | |||||||
|     signal_strength_ = ((signal_strength_dbm_ - hardwareMin) |     signal_strength_ = ((signal_strength_dbm_ - hardwareMin) | ||||||
|       / double{hardwareMax - hardwareMin}) * 100; |       / double{hardwareMax - hardwareMin}) * 100; | ||||||
|   } |   } | ||||||
|  |   if (bss[NL80211_BSS_SIGNAL_UNSPEC] != nullptr) { | ||||||
|  |     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) | ||||||
| @@ -446,5 +499,5 @@ auto waybar::modules::Network::getInfo() -> void | |||||||
|     nlmsg_free(nl_msg); |     nlmsg_free(nl_msg); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   nl_send_sync(sk_, nl_msg); |   nl_send_auto(sk_, nl_msg); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,11 +1,18 @@ | |||||||
| #include "modules/sway/ipc/client.hpp" | #include "modules/sway/ipc/client.hpp" | ||||||
|  |  | ||||||
| waybar::modules::sway::Ipc::Ipc() | waybar::modules::sway::Ipc::Ipc() | ||||||
|   : fd_(-1), fd_event_(-1) | { | ||||||
| {} |   const std::string& socketPath = getSocketPath(); | ||||||
|  |   fd_ = open(socketPath); | ||||||
|  |   fd_event_ = open(socketPath); | ||||||
|  | } | ||||||
|  |  | ||||||
| waybar::modules::sway::Ipc::~Ipc() | waybar::modules::sway::Ipc::~Ipc() | ||||||
| { | { | ||||||
|  |   // To fail the IPC header | ||||||
|  |   write(fd_, "close-sway-ipc", 14); | ||||||
|  |   write(fd_event_, "close-sway-ipc", 14); | ||||||
|  |  | ||||||
|   close(fd_); |   close(fd_); | ||||||
|   close(fd_event_); |   close(fd_event_); | ||||||
| } | } | ||||||
| @@ -53,13 +60,6 @@ int waybar::modules::sway::Ipc::open(const std::string& socketPath) const | |||||||
|   return fd; |   return fd; | ||||||
| } | } | ||||||
|  |  | ||||||
| void waybar::modules::sway::Ipc::connect() |  | ||||||
| { |  | ||||||
|   const std::string& socketPath = getSocketPath(); |  | ||||||
|   fd_ = open(socketPath); |  | ||||||
|   fd_event_ = open(socketPath); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct waybar::modules::sway::Ipc::ipc_response | struct waybar::modules::sway::Ipc::ipc_response | ||||||
|   waybar::modules::sway::Ipc::recv(int fd) const |   waybar::modules::sway::Ipc::recv(int fd) const | ||||||
| { | { | ||||||
| @@ -71,18 +71,23 @@ struct waybar::modules::sway::Ipc::ipc_response | |||||||
|   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 (res <= 0) { |     if (res <= 0) { | ||||||
|       throw std::runtime_error("Unable to receive IPC response"); |       throw std::runtime_error("Unable to receive IPC header"); | ||||||
|     } |     } | ||||||
|     total += res; |     total += res; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   auto magic = std::string(header.data(), header.data() + ipc_magic_.size()); | ||||||
|  |   if (magic != ipc_magic_) { | ||||||
|  |     throw std::runtime_error("Invalid IPC magic"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   total = 0; |   total = 0; | ||||||
|   std::string payload; |   std::string payload; | ||||||
|   payload.reserve(data32[0] + 1); |   payload.reserve(data32[0] + 1); | ||||||
|   while (total < data32[0]) { |   while (total < data32[0]) { | ||||||
|     auto res = ::recv(fd, payload.data() + total, data32[0] - total, 0); |     auto res = ::recv(fd, payload.data() + total, data32[0] - total, 0); | ||||||
|     if (res < 0) { |     if (res < 0) { | ||||||
|       throw std::runtime_error("Unable to receive IPC response"); |       throw std::runtime_error("Unable to receive IPC payload"); | ||||||
|     } |     } | ||||||
|     total += res; |     total += res; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ waybar::modules::sway::Mode::Mode(const std::string& id, const Bar& bar, const J | |||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     label_.get_style_context()->add_class(id); |     label_.get_style_context()->add_class(id); | ||||||
|   } |   } | ||||||
|   ipc_.connect(); |  | ||||||
|   ipc_.subscribe("[ \"mode\" ]"); |   ipc_.subscribe("[ \"mode\" ]"); | ||||||
|   // Launch worker |   // Launch worker | ||||||
|   worker(); |   worker(); | ||||||
| @@ -20,14 +19,12 @@ void waybar::modules::sway::Mode::worker() | |||||||
|     try { |     try { | ||||||
|       auto res = ipc_.handleEvent(); |       auto res = ipc_.handleEvent(); | ||||||
|       auto parsed = parser_.parse(res.payload); |       auto parsed = parser_.parse(res.payload); | ||||||
|       if ((parsed["change"]) != "default" ) { |       if (parsed["change"] != "default") { | ||||||
|         mode_ = parsed["change"].asString(); |         mode_ = parsed["change"].asString(); | ||||||
|         dp.emit(); |       } else { | ||||||
|       } |  | ||||||
|       else if ((parsed["change"]) == "default" ) { |  | ||||||
|         mode_.clear(); |         mode_.clear(); | ||||||
|         dp.emit(); |  | ||||||
|       } |       } | ||||||
|  |       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; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ waybar::modules::sway::Window::Window(const std::string& id, const Bar &bar, con | |||||||
|     label_.set_hexpand(true); |     label_.set_hexpand(true); | ||||||
|     label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); |     label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); | ||||||
|   } |   } | ||||||
|   ipc_.connect(); |  | ||||||
|   ipc_.subscribe("[\"window\",\"workspace\"]"); |   ipc_.subscribe("[\"window\",\"workspace\"]"); | ||||||
|   getFocusedWindow(); |   getFocusedWindow(); | ||||||
|   // Launch worker |   // Launch worker | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ waybar::modules::sway::Workspaces::Workspaces(const std::string& id, const Bar& | |||||||
|   if (!id.empty()) { |   if (!id.empty()) { | ||||||
|     box_.get_style_context()->add_class(id); |     box_.get_style_context()->add_class(id); | ||||||
|   } |   } | ||||||
|   ipc_.connect(); |  | ||||||
|   ipc_.subscribe("[ \"workspace\" ]"); |   ipc_.subscribe("[ \"workspace\" ]"); | ||||||
|   // Launch worker |   // Launch worker | ||||||
|   worker(); |   worker(); | ||||||
| @@ -21,9 +20,9 @@ void waybar::modules::sway::Workspaces::worker() | |||||||
|       // Wait for the name of the output |       // Wait for the name of the output | ||||||
|       if (!config_["all-outputs"].asBool() && bar_.output_name.empty()) { |       if (!config_["all-outputs"].asBool() && bar_.output_name.empty()) { | ||||||
|         while (bar_.output_name.empty()) { |         while (bar_.output_name.empty()) { | ||||||
|           thread_.sleep_for(chrono::milliseconds(150)); |           thread_.sleep_for(std::chrono::milliseconds(150)); | ||||||
|         } |         } | ||||||
|       } else if (thread_.isRunning() && !workspaces_.empty()) { |       } else if (!workspaces_.empty()) { | ||||||
|         ipc_.handleEvent(); |         ipc_.handleEvent(); | ||||||
|       } |       } | ||||||
|       { |       { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Alexis
					Alexis