mirror of
				https://github.com/rad4day/Waybar.git
				synced 2025-11-01 00:12:42 +01:00 
			
		
		
		
	Merge pull request #130 from Alexays/destructor
refactor: proper modules destruction
This commit is contained in:
		| @@ -18,6 +18,7 @@ class Bar { | ||||
|   public: | ||||
|     Bar(const Client&, std::unique_ptr<struct wl_output *>&&, uint32_t); | ||||
|     Bar(const Bar&) = delete; | ||||
|     ~Bar() = default; | ||||
|  | ||||
|     auto toggle() -> void; | ||||
|  | ||||
| @@ -54,6 +55,10 @@ class Bar { | ||||
|     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_; | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| #include <fmt/format.h> | ||||
| #include <sys/inotify.h> | ||||
| #include <algorithm> | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "ALabel.hpp" | ||||
|  | ||||
| namespace waybar::modules { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| #include <fmt/format.h> | ||||
| #include "fmt/time.h" | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "ALabel.hpp" | ||||
|  | ||||
| namespace waybar::modules { | ||||
| @@ -10,6 +10,7 @@ namespace waybar::modules { | ||||
| class Clock : public ALabel { | ||||
|   public: | ||||
|     Clock(const std::string&, const Json::Value&); | ||||
|     ~Clock() = default; | ||||
|     auto update() -> void; | ||||
|   private: | ||||
|     waybar::util::SleeperThread thread_; | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| #include <vector> | ||||
| #include <numeric> | ||||
| #include <iostream> | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "ALabel.hpp" | ||||
|  | ||||
| namespace waybar::modules { | ||||
| @@ -14,6 +14,7 @@ namespace waybar::modules { | ||||
| class Cpu : public ALabel { | ||||
|   public: | ||||
|     Cpu(const std::string&, const Json::Value&); | ||||
|     ~Cpu() = default; | ||||
|     auto update() -> void; | ||||
|   private: | ||||
|     static inline const std::string data_dir_ = "/proc/stat"; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| #include <fmt/format.h> | ||||
| #include <iostream> | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "util/command.hpp" | ||||
| #include "util/json.hpp" | ||||
| #include "ALabel.hpp" | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| #include <fmt/format.h> | ||||
| #include <fstream> | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "ALabel.hpp" | ||||
|  | ||||
| namespace waybar::modules { | ||||
| @@ -10,6 +10,7 @@ namespace waybar::modules { | ||||
| class Memory : public ALabel { | ||||
|   public: | ||||
|     Memory(const std::string&, const Json::Value&); | ||||
|     ~Memory() = default; | ||||
|     auto update() -> void; | ||||
|   private: | ||||
|     static inline const std::string data_dir_ = "/proc/meminfo"; | ||||
|   | ||||
| @@ -7,8 +7,9 @@ | ||||
| #include <netlink/genl/genl.h> | ||||
| #include <netlink/genl/ctrl.h> | ||||
| #include <linux/nl80211.h> | ||||
| #include <sys/epoll.h> | ||||
| #include <fmt/format.h> | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "ALabel.hpp" | ||||
|  | ||||
| namespace waybar::modules { | ||||
| @@ -19,15 +20,17 @@ class Network : public ALabel { | ||||
|     ~Network(); | ||||
|     auto update() -> void; | ||||
|   private: | ||||
|     static int netlinkRequest(int, void*, uint32_t, uint32_t groups = 0); | ||||
|     static int netlinkResponse(int, void*, uint32_t, uint32_t groups = 0); | ||||
|     static int scanCb(struct nl_msg*, void*); | ||||
|     static int handleEvents(struct nl_msg*, void*); | ||||
|     static int handleScan(struct nl_msg*, void*); | ||||
|  | ||||
|     void worker(); | ||||
|     void disconnected(); | ||||
|     void initNL80211(); | ||||
|     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**); | ||||
| @@ -37,9 +40,11 @@ class Network : public ALabel { | ||||
|     waybar::util::SleeperThread thread_timer_; | ||||
|     int ifid_; | ||||
|     sa_family_t family_; | ||||
|     int sock_fd_; | ||||
|     struct sockaddr_nl nladdr_ = {0}; | ||||
|     struct nl_sock* sk_ = nullptr; | ||||
|     struct nl_sock* info_sock_ = nullptr; | ||||
|     int efd_; | ||||
|     int ev_fd_; | ||||
|     int nl80211_id_; | ||||
|  | ||||
|     std::string essid_; | ||||
| @@ -47,8 +52,8 @@ class Network : public ALabel { | ||||
|     std::string ipaddr_; | ||||
|     std::string netmask_; | ||||
|     int cidr_; | ||||
|     int signal_strength_dbm_; | ||||
|     uint16_t signal_strength_; | ||||
|     int32_t signal_strength_dbm_; | ||||
|     uint8_t signal_strength_; | ||||
| }; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <fmt/format.h> | ||||
| #include <thread> | ||||
| #include "bar.hpp" | ||||
| #include "util/json.hpp" | ||||
| #include "IModule.hpp" | ||||
| @@ -13,6 +12,7 @@ namespace waybar::modules::SNI { | ||||
| class Tray : public IModule { | ||||
|   public: | ||||
|     Tray(const std::string&, const Json::Value&); | ||||
|     ~Tray() = default; | ||||
|     auto update() -> void; | ||||
|     operator Gtk::Widget &(); | ||||
|   private: | ||||
| @@ -20,7 +20,6 @@ class Tray : public IModule { | ||||
|     void onRemove(std::unique_ptr<Item>& item); | ||||
|  | ||||
|     static inline std::size_t nb_hosts_ = 0; | ||||
|     std::thread thread_; | ||||
|     const Json::Value& config_; | ||||
|     Gtk::Box box_; | ||||
|     SNI::Watcher watcher_ ; | ||||
|   | ||||
| @@ -10,33 +10,31 @@ | ||||
| namespace waybar::modules::sway { | ||||
|  | ||||
| class Ipc { | ||||
|   public: | ||||
|     Ipc(); | ||||
|     ~Ipc(); | ||||
| public: | ||||
|   Ipc(); | ||||
|   ~Ipc(); | ||||
|  | ||||
| 		struct ipc_response { | ||||
| 			uint32_t size; | ||||
| 			uint32_t type; | ||||
| 			std::string payload; | ||||
| 		}; | ||||
|   struct ipc_response { | ||||
|     uint32_t size; | ||||
|     uint32_t type; | ||||
|     std::string payload; | ||||
|   }; | ||||
|  | ||||
| 		void connect(); | ||||
| 		struct ipc_response sendCmd(uint32_t type, | ||||
| 			const std::string& payload = "") 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; | ||||
|   struct ipc_response sendCmd(uint32_t type, const std::string &payload = "") const; | ||||
|   void subscribe(const std::string &payload) const; | ||||
|   struct ipc_response handleEvent() const; | ||||
|  | ||||
| 		const std::string getSocketPath() const; | ||||
| 		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; | ||||
| protected: | ||||
|   static inline const std::string ipc_magic_ = "i3-ipc"; | ||||
|   static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8; | ||||
|  | ||||
| 		int fd_; | ||||
| 		int fd_event_; | ||||
|   const std::string getSocketPath() const; | ||||
|   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)) | ||||
|  | ||||
| enum ipc_command_type { | ||||
| 	// i3 command types - see i3's I3_REPLY_TYPE constants | ||||
| 	IPC_COMMAND = 0, | ||||
| 	IPC_GET_WORKSPACES = 1, | ||||
| 	IPC_SUBSCRIBE = 2, | ||||
| 	IPC_GET_OUTPUTS = 3, | ||||
| 	IPC_GET_TREE = 4, | ||||
| 	IPC_GET_MARKS = 5, | ||||
| 	IPC_GET_BAR_CONFIG = 6, | ||||
| 	IPC_GET_VERSION = 7, | ||||
| 	IPC_GET_BINDING_MODES = 8, | ||||
| 	IPC_GET_CONFIG = 9, | ||||
| 	IPC_SEND_TICK = 10, | ||||
|   // i3 command types - see i3's I3_REPLY_TYPE constants | ||||
|   IPC_COMMAND = 0, | ||||
|   IPC_GET_WORKSPACES = 1, | ||||
|   IPC_SUBSCRIBE = 2, | ||||
|   IPC_GET_OUTPUTS = 3, | ||||
|   IPC_GET_TREE = 4, | ||||
|   IPC_GET_MARKS = 5, | ||||
|   IPC_GET_BAR_CONFIG = 6, | ||||
|   IPC_GET_VERSION = 7, | ||||
|   IPC_GET_BINDING_MODES = 8, | ||||
|   IPC_GET_CONFIG = 9, | ||||
|   IPC_SEND_TICK = 10, | ||||
|  | ||||
| 	// sway-specific command types | ||||
| 	IPC_GET_INPUTS = 100, | ||||
| 	IPC_GET_SEATS = 101, | ||||
|   // sway-specific command types | ||||
|   IPC_GET_INPUTS = 100, | ||||
|   IPC_GET_SEATS = 101, | ||||
|  | ||||
| 	// Events sent from sway to clients. Events have the highest bits set. | ||||
| 	IPC_EVENT_WORKSPACE = ((1<<31) | 0), | ||||
| 	IPC_EVENT_OUTPUT = ((1<<31) | 1), | ||||
| 	IPC_EVENT_MODE = ((1<<31) | 2), | ||||
| 	IPC_EVENT_WINDOW = ((1<<31) | 3), | ||||
| 	IPC_EVENT_BARCONFIG_UPDATE = ((1<<31) | 4), | ||||
| 	IPC_EVENT_BINDING = ((1<<31) | 5), | ||||
| 	IPC_EVENT_SHUTDOWN = ((1<<31) | 6), | ||||
| 	IPC_EVENT_TICK = ((1<<31) | 7), | ||||
|   // Events sent from sway to clients. Events have the highest bits set. | ||||
|   IPC_EVENT_WORKSPACE = ((1 << 31) | 0), | ||||
|   IPC_EVENT_OUTPUT = ((1 << 31) | 1), | ||||
|   IPC_EVENT_MODE = ((1 << 31) | 2), | ||||
|   IPC_EVENT_WINDOW = ((1 << 31) | 3), | ||||
|   IPC_EVENT_BARCONFIG_UPDATE = ((1 << 31) | 4), | ||||
|   IPC_EVENT_BINDING = ((1 << 31) | 5), | ||||
|   IPC_EVENT_SHUTDOWN = ((1 << 31) | 6), | ||||
|   IPC_EVENT_TICK = ((1 << 31) | 7), | ||||
| }; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| #include <fmt/format.h> | ||||
| #include "bar.hpp" | ||||
| #include "client.hpp" | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "util/json.hpp" | ||||
| #include "ALabel.hpp" | ||||
| #include "modules/sway/ipc/client.hpp" | ||||
| @@ -13,6 +13,7 @@ namespace waybar::modules::sway { | ||||
| class Mode : public ALabel { | ||||
|   public: | ||||
|     Mode(const std::string&, const waybar::Bar&, const Json::Value&); | ||||
|     ~Mode() = default; | ||||
|     auto update() -> void; | ||||
|   private: | ||||
|     void worker(); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| #include <tuple> | ||||
| #include "bar.hpp" | ||||
| #include "client.hpp" | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "util/json.hpp" | ||||
| #include "ALabel.hpp" | ||||
| #include "modules/sway/ipc/client.hpp" | ||||
| @@ -14,6 +14,7 @@ namespace waybar::modules::sway { | ||||
| class Window : public ALabel { | ||||
|   public: | ||||
|     Window(const std::string&, const waybar::Bar&, const Json::Value&); | ||||
|     ~Window() = default; | ||||
|     auto update() -> void; | ||||
|   private: | ||||
|     void worker(); | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| #include <fmt/format.h> | ||||
| #include "bar.hpp" | ||||
| #include "client.hpp" | ||||
| #include "util/chrono.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| #include "util/json.hpp" | ||||
| #include "IModule.hpp" | ||||
| #include "modules/sway/ipc/client.hpp" | ||||
| @@ -14,6 +14,7 @@ namespace waybar::modules::sway { | ||||
| class Workspaces : public IModule { | ||||
|   public: | ||||
|     Workspaces(const std::string&, const waybar::Bar&, const Json::Value&); | ||||
|     ~Workspaces() = default; | ||||
|     auto update() -> void; | ||||
|     operator Gtk::Widget &(); | ||||
|   private: | ||||
| @@ -27,14 +28,14 @@ class Workspaces : public IModule { | ||||
|  | ||||
|     const Bar& bar_; | ||||
|     const Json::Value& config_; | ||||
|     Json::Value workspaces_; | ||||
|     waybar::util::SleeperThread thread_; | ||||
|     Gtk::Box box_; | ||||
|     util::JsonParser parser_; | ||||
|     Ipc ipc_; | ||||
|     std::mutex mutex_; | ||||
|     bool scrolling_; | ||||
|     std::unordered_map<std::string, Gtk::Button> buttons_; | ||||
|     Json::Value workspaces_; | ||||
|     Ipc ipc_; | ||||
| }; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| #include <sys/wait.h> | ||||
| #include <giomm.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| namespace waybar::util::command { | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ struct JsonParser { | ||||
|     : reader_(builder_.newCharReader()) | ||||
|   {} | ||||
|  | ||||
|   const Json::Value parse(const std::string data) const | ||||
|   const Json::Value parse(const std::string& data) const | ||||
|   { | ||||
|     Json::Value root; | ||||
|     std::string err; | ||||
|   | ||||
| @@ -6,30 +6,20 @@ | ||||
| #include <condition_variable> | ||||
| #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 { | ||||
| 
 | ||||
| struct SleeperThread { | ||||
| class SleeperThread { | ||||
| public: | ||||
|   SleeperThread() = default; | ||||
| 
 | ||||
|   SleeperThread(std::function<void()> func) | ||||
|     : do_run_(true), thread_{[this, func] { | ||||
|     : thread_{[this, func] { | ||||
|         while (do_run_) func(); | ||||
|       }} | ||||
|   {} | ||||
| 
 | ||||
|   SleeperThread& operator=(std::function<void()> func) | ||||
|   { | ||||
|     do_run_ = true; | ||||
|     thread_ = std::thread([this, func] { | ||||
|       while (do_run_) func(); | ||||
|     }); | ||||
| @@ -41,16 +31,17 @@ struct SleeperThread { | ||||
|     return do_run_; | ||||
|   } | ||||
| 
 | ||||
|   auto sleep_for(chrono::duration dur) | ||||
|   auto sleep_for(std::chrono::system_clock::duration dur) | ||||
|   { | ||||
|     auto lock = std::unique_lock(mutex_); | ||||
|     return condvar_.wait_for(lock, dur); | ||||
|     std::unique_lock lk(mutex_); | ||||
|     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_); | ||||
|     return condvar_.wait_until(lock, time); | ||||
|     std::unique_lock lk(mutex_); | ||||
|     return condvar_.wait_until(lk, time_point, [this] { return !do_run_; }); | ||||
|   } | ||||
| 
 | ||||
|   auto wake_up() | ||||
| @@ -60,7 +51,10 @@ struct SleeperThread { | ||||
| 
 | ||||
|   auto stop() | ||||
|   { | ||||
|     do_run_ = false; | ||||
|     { | ||||
|       std::lock_guard<std::mutex> lck(mutex_); | ||||
|       do_run_ = false; | ||||
|     } | ||||
|     condvar_.notify_all(); | ||||
|   } | ||||
| 
 | ||||
| @@ -68,15 +62,15 @@ struct SleeperThread { | ||||
|   { | ||||
|     stop(); | ||||
|     if (thread_.joinable()) { | ||||
|       thread_.detach(); | ||||
|       thread_.join(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| private: | ||||
|   bool do_run_ = false; | ||||
|   std::thread thread_; | ||||
|   std::condition_variable condvar_; | ||||
|   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 = [] | ||||
|  | ||||
| if false # libc++ | ||||
| @@ -22,6 +22,16 @@ else | ||||
| endif | ||||
|  | ||||
| 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') | ||||
|     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) | ||||
|   : client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL}, | ||||
|     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 = { | ||||
|     .logical_position = handleLogicalPosition, | ||||
| @@ -200,28 +202,23 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos) | ||||
|  | ||||
| auto waybar::Bar::setupWidgets() -> void | ||||
| { | ||||
|   auto &left = *Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 0)); | ||||
|   auto ¢er = *Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 0)); | ||||
|   auto &right = *Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 0)); | ||||
|  | ||||
|   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); | ||||
|   window.add(box_); | ||||
|   box_.pack_start(left_, true, true); | ||||
|   box_.set_center_widget(center_); | ||||
|   box_.pack_end(right_, true, true); | ||||
|  | ||||
|   Factory factory(*this, config_); | ||||
|   getModules(factory, "modules-left"); | ||||
|   getModules(factory, "modules-center"); | ||||
|   getModules(factory, "modules-right"); | ||||
|   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_) { | ||||
|     center.pack_start(*module, true, true, 0); | ||||
|     center_.pack_start(*module, true, true, 0); | ||||
|   } | ||||
|   std::reverse(modules_right_.begin(), modules_right_.end()); | ||||
|   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); | ||||
|   } | ||||
|   thread_ = [this] { | ||||
|     auto now = waybar::chrono::clock::now(); | ||||
|     auto now = std::chrono::system_clock::now(); | ||||
|     dp.emit(); | ||||
|     auto timeout = std::chrono::floor<std::chrono::seconds>(now + interval_); | ||||
|     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()) { | ||||
|     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::string tooltip; | ||||
|   | ||||
| @@ -1,23 +1,16 @@ | ||||
| #include <sys/eventfd.h> | ||||
| #include "modules/network.hpp" | ||||
|  | ||||
| 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) | ||||
| { | ||||
|   label_.set_name("network"); | ||||
|   if (!id.empty()) { | ||||
|     label_.get_style_context()->add_class(id); | ||||
|   } | ||||
|   sock_fd_ = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); | ||||
|   if (sock_fd_ < 0) { | ||||
|     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"); | ||||
|   } | ||||
|   createInfoSocket(); | ||||
|   createEventSocket(); | ||||
|   if (config_["interface"].isString()) { | ||||
|     ifid_ = if_nametoindex(config_["interface"].asCString()); | ||||
|     ifname_ = config_["interface"].asString(); | ||||
| @@ -32,73 +25,111 @@ waybar::modules::Network::Network(const std::string& id, const Json::Value& conf | ||||
|       ifname_ = ifname; | ||||
|     } | ||||
|   } | ||||
|   initNL80211(); | ||||
|   // Trigger first values | ||||
|   getInfo(); | ||||
|   dp.emit(); | ||||
|   worker(); | ||||
| } | ||||
|  | ||||
| waybar::modules::Network::~Network() | ||||
| { | ||||
|   close(sock_fd_); | ||||
|   nl_socket_free(sk_); | ||||
|   if (ev_fd_ > -1) { | ||||
|     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"); | ||||
|   } | ||||
|   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() | ||||
| { | ||||
|   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_.sleep_for(interval_); | ||||
|     if (ifid_ > 0) { | ||||
|       getInfo(); | ||||
|       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 +182,6 @@ void waybar::modules::Network::disconnected() | ||||
|   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 | ||||
| int waybar::modules::Network::getExternalInterface() | ||||
| { | ||||
| @@ -192,7 +205,7 @@ int waybar::modules::Network::getExternalInterface() | ||||
|   rt->rtm_table = RT_TABLE_MAIN; | ||||
|  | ||||
|   /* Issue the query. */ | ||||
|   if (netlinkRequest(sock_fd_, req, reqlen) < 0) { | ||||
|   if (netlinkRequest(req, reqlen) < 0) { | ||||
|     goto out; | ||||
|   } | ||||
|  | ||||
| @@ -202,7 +215,7 @@ int waybar::modules::Network::getExternalInterface() | ||||
|    * consume responses till NLMSG_DONE/NLMSG_ERROR is encountered). | ||||
|    */ | ||||
|   do { | ||||
|     auto len = netlinkResponse(sock_fd_, resp, route_buffer_size); | ||||
|     auto len = netlinkResponse(resp, route_buffer_size); | ||||
|     if (len < 0) { | ||||
|       goto out; | ||||
|     } | ||||
| @@ -322,7 +335,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) | ||||
| { | ||||
|   struct sockaddr_nl sa = {}; | ||||
| @@ -330,10 +343,10 @@ int waybar::modules::Network::netlinkRequest(int fd, void *req, | ||||
|   sa.nl_groups = groups; | ||||
|   struct iovec iov = { req, reqlen }; | ||||
|   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) | ||||
| { | ||||
|   struct sockaddr_nl sa = {}; | ||||
| @@ -341,14 +354,50 @@ int waybar::modules::Network::netlinkResponse(int fd, void *resp, | ||||
|   sa.nl_groups = groups; | ||||
|   struct iovec iov = { resp, resplen }; | ||||
|   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) { | ||||
|     return -1; | ||||
|   } | ||||
|   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 gnlh = static_cast<genlmsghdr *>(nlmsg_data(nlmsg_hdr(msg))); | ||||
|   struct nlattr* tb[NL80211_ATTR_MAX + 1]; | ||||
| @@ -404,9 +453,8 @@ void waybar::modules::Network::parseEssid(struct nlattr **bss) | ||||
|  | ||||
| void waybar::modules::Network::parseSignal(struct nlattr **bss) { | ||||
|   if (bss[NL80211_BSS_SIGNAL_MBM] != nullptr) { | ||||
|     // signalstrength in dBm | ||||
|     signal_strength_dbm_ = | ||||
|       static_cast<int>(nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM])) / 100; | ||||
|     // signalstrength in dBm from mBm | ||||
|     signal_strength_dbm_ = nla_get_s32(bss[NL80211_BSS_SIGNAL_MBM]) / 100; | ||||
|  | ||||
|     // WiFi-hardware usually operates in the range -90 to -20dBm. | ||||
|     const int hardwareMax = -20; | ||||
| @@ -414,6 +462,9 @@ void waybar::modules::Network::parseSignal(struct nlattr **bss) { | ||||
|     signal_strength_ = ((signal_strength_dbm_ - hardwareMin) | ||||
|       / 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) | ||||
| @@ -437,7 +488,6 @@ auto waybar::modules::Network::getInfo() -> void | ||||
|   getInterfaceAddress(); | ||||
|   struct nl_msg* nl_msg = nlmsg_alloc(); | ||||
|   if (nl_msg == nullptr) { | ||||
|     nlmsg_free(nl_msg); | ||||
|     return; | ||||
|   } | ||||
|   if (genlmsg_put(nl_msg, NL_AUTO_PORT, NL_AUTO_SEQ, nl80211_id_, 0, NLM_F_DUMP, | ||||
|   | ||||
| @@ -1,11 +1,18 @@ | ||||
| #include "modules/sway/ipc/client.hpp" | ||||
|  | ||||
| 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() | ||||
| { | ||||
|   // To fail the IPC header | ||||
|   write(fd_, "close-sway-ipc", 14); | ||||
|   write(fd_event_, "close-sway-ipc", 14); | ||||
|  | ||||
|   close(fd_); | ||||
|   close(fd_event_); | ||||
| } | ||||
| @@ -53,13 +60,6 @@ int waybar::modules::sway::Ipc::open(const std::string& socketPath) const | ||||
|   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 | ||||
|   waybar::modules::sway::Ipc::recv(int fd) const | ||||
| { | ||||
| @@ -71,18 +71,23 @@ struct waybar::modules::sway::Ipc::ipc_response | ||||
|   while (total < ipc_header_size_) { | ||||
|     auto res = ::recv(fd, header.data() + total, ipc_header_size_ - total, 0); | ||||
|     if (res <= 0) { | ||||
|       throw std::runtime_error("Unable to receive IPC response"); | ||||
|       throw std::runtime_error("Unable to receive IPC header"); | ||||
|     } | ||||
|     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; | ||||
|   std::string payload; | ||||
|   payload.reserve(data32[0] + 1); | ||||
|   while (total < data32[0]) { | ||||
|     auto res = ::recv(fd, payload.data() + total, data32[0] - total, 0); | ||||
|     if (res < 0) { | ||||
|       throw std::runtime_error("Unable to receive IPC response"); | ||||
|       throw std::runtime_error("Unable to receive IPC payload"); | ||||
|     } | ||||
|     total += res; | ||||
|   } | ||||
|   | ||||
| @@ -7,7 +7,6 @@ waybar::modules::sway::Mode::Mode(const std::string& id, const Bar& bar, const J | ||||
|   if (!id.empty()) { | ||||
|     label_.get_style_context()->add_class(id); | ||||
|   } | ||||
|   ipc_.connect(); | ||||
|   ipc_.subscribe("[ \"mode\" ]"); | ||||
|   // Launch worker | ||||
|   worker(); | ||||
| @@ -20,14 +19,12 @@ void waybar::modules::sway::Mode::worker() | ||||
|     try { | ||||
|       auto res = ipc_.handleEvent(); | ||||
|       auto parsed = parser_.parse(res.payload); | ||||
|       if ((parsed["change"]) != "default" ) { | ||||
|       if (parsed["change"] != "default") { | ||||
|         mode_ = parsed["change"].asString(); | ||||
|         dp.emit(); | ||||
|       } | ||||
|       else if ((parsed["change"]) == "default" ) { | ||||
|       } else { | ||||
|         mode_.clear(); | ||||
|         dp.emit(); | ||||
|       } | ||||
|       dp.emit(); | ||||
|     } catch (const std::exception& e) { | ||||
|       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_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); | ||||
|   } | ||||
|   ipc_.connect(); | ||||
|   ipc_.subscribe("[\"window\",\"workspace\"]"); | ||||
|   getFocusedWindow(); | ||||
|   // Launch worker | ||||
|   | ||||
| @@ -8,7 +8,6 @@ waybar::modules::sway::Workspaces::Workspaces(const std::string& id, const Bar& | ||||
|   if (!id.empty()) { | ||||
|     box_.get_style_context()->add_class(id); | ||||
|   } | ||||
|   ipc_.connect(); | ||||
|   ipc_.subscribe("[ \"workspace\" ]"); | ||||
|   // Launch worker | ||||
|   worker(); | ||||
| @@ -21,15 +20,17 @@ void waybar::modules::sway::Workspaces::worker() | ||||
|       // Wait for the name of the output | ||||
|       if (!config_["all-outputs"].asBool() && 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(); | ||||
|       } | ||||
|       { | ||||
|         std::lock_guard<std::mutex> lock(mutex_); | ||||
|         auto res = ipc_.sendCmd(IPC_GET_WORKSPACES); | ||||
|         workspaces_ = parser_.parse(res.payload); | ||||
|         if (thread_.isRunning()) { | ||||
|           workspaces_ = parser_.parse(res.payload); | ||||
|         } | ||||
|       } | ||||
|       dp.emit(); | ||||
|     } catch (const std::exception& e) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Alex
					Alex