mirror of
				https://github.com/rad4day/Waybar.git
				synced 2025-10-31 07:52:42 +01:00 
			
		
		
		
	Battery event (#18)
This commit is contained in:
		| @@ -15,7 +15,7 @@ namespace waybar { | ||||
|   class Factory { | ||||
| 	  public: | ||||
|       Factory(Bar &bar, Json::Value config); | ||||
|       IModule &makeModule(std::string name); | ||||
|       IModule *makeModule(std::string name); | ||||
|     private: | ||||
|       Bar &_bar; | ||||
|       Json::Value _config; | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include <fstream> | ||||
| #include <iostream> | ||||
| #include <fmt/format.h> | ||||
| #include <sys/inotify.h> | ||||
| #include "util/chrono.hpp" | ||||
| #include "IModule.hpp" | ||||
|  | ||||
| @@ -18,7 +19,7 @@ namespace waybar::modules { | ||||
|       auto update() -> void; | ||||
|       operator Gtk::Widget&(); | ||||
|     private: | ||||
|       std::string _getIcon(uint32_t percentage); | ||||
|       std::string _getIcon(uint16_t percentage); | ||||
|       static inline const fs::path _data_dir = "/sys/class/power_supply/"; | ||||
|       std::vector<fs::path> _batteries; | ||||
|       util::SleeperThread _thread; | ||||
|   | ||||
| @@ -39,7 +39,9 @@ namespace waybar::util { | ||||
|             func(); | ||||
|           } while (do_run); | ||||
|         }} | ||||
|     {} | ||||
|     { | ||||
|       defined = true; | ||||
|     } | ||||
|  | ||||
|     SleeperThread& operator=(std::function<void()> func) | ||||
|     { | ||||
| @@ -48,6 +50,7 @@ namespace waybar::util { | ||||
|           func(); | ||||
|         } while (do_run); | ||||
|       }); | ||||
|       defined = true; | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
| @@ -72,14 +75,17 @@ namespace waybar::util { | ||||
|     ~SleeperThread() | ||||
|     { | ||||
|       do_run = false; | ||||
|       if (defined) { | ||||
|         condvar.notify_all(); | ||||
|         thread.join(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   private: | ||||
|     std::thread thread; | ||||
|     std::condition_variable condvar; | ||||
|     std::mutex mutex; | ||||
|     bool defined = false; | ||||
|     bool do_run = true; | ||||
|   }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										15
									
								
								src/bar.cpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/bar.cpp
									
									
									
									
									
								
							| @@ -170,21 +170,24 @@ auto waybar::Bar::_setupWidgets() -> void | ||||
|    | ||||
|   if (_config["modules-left"]) { | ||||
|     for (auto name : _config["modules-left"]) { | ||||
|       auto &module = factory.makeModule(name.asString()); | ||||
|       left.pack_start(module, false, true, 0); | ||||
|       auto module = factory.makeModule(name.asString()); | ||||
|       if (module) | ||||
|         left.pack_start(*module, false, true, 0); | ||||
|     } | ||||
|   } | ||||
|   if (_config["modules-center"]) { | ||||
|     for (auto name : _config["modules-center"]) { | ||||
|       auto &module = factory.makeModule(name.asString()); | ||||
|       center.pack_start(module, true, false, 10); | ||||
|       auto module = factory.makeModule(name.asString()); | ||||
|       if (module) | ||||
|         center.pack_start(*module, true, false, 10); | ||||
|     } | ||||
|   } | ||||
|   if (_config["modules-right"]) { | ||||
|     std::reverse(_config["modules-right"].begin(), _config["modules-right"].end()); | ||||
|     for (auto name : _config["modules-right"]) { | ||||
|       auto &module = factory.makeModule(name.asString()); | ||||
|       right.pack_end(module, false, false, 0); | ||||
|       auto module = factory.makeModule(name.asString()); | ||||
|       if (module) | ||||
|         right.pack_end(*module, false, false, 0); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -4,23 +4,32 @@ waybar::Factory::Factory(Bar &bar, Json::Value config) | ||||
|   : _bar(bar), _config(config) | ||||
| {} | ||||
|  | ||||
| waybar::IModule &waybar::Factory::makeModule(std::string name) | ||||
| waybar::IModule *waybar::Factory::makeModule(std::string name) | ||||
| { | ||||
|   try { | ||||
|     if (name == "battery") | ||||
|     return *new waybar::modules::Battery(_config[name]); | ||||
|       return new waybar::modules::Battery(_config[name]); | ||||
|     if (name == "workspaces") | ||||
|     return *new waybar::modules::Workspaces(_bar); | ||||
|       return new waybar::modules::Workspaces(_bar); | ||||
|     if (name == "memory") | ||||
|     return *new waybar::modules::Memory(_config[name]); | ||||
|       return new waybar::modules::Memory(_config[name]); | ||||
|     if (name == "cpu") | ||||
|     return *new waybar::modules::Cpu(_config[name]); | ||||
|       return new waybar::modules::Cpu(_config[name]); | ||||
|     if (name == "clock") | ||||
|     return *new waybar::modules::Clock(_config[name]); | ||||
|       return new waybar::modules::Clock(_config[name]); | ||||
|     if (name == "network") | ||||
|     return *new waybar::modules::Network(_config[name]); | ||||
|       return new waybar::modules::Network(_config[name]); | ||||
|     if (name == "pulseaudio") | ||||
|     return *new waybar::modules::Pulseaudio(_config[name]); | ||||
|       return new waybar::modules::Pulseaudio(_config[name]); | ||||
|     if (!name.compare(0, 7, "custom/") && name.size() > 7) | ||||
|     return *new waybar::modules::Custom(name.substr(7), _config[name]); | ||||
|   throw std::runtime_error("Unknown module: " + name); | ||||
|       return new waybar::modules::Custom(name.substr(7), _config[name]); | ||||
|     std::cerr << "Unknown module: " + name << std::endl; | ||||
|   } catch (const std::exception& e) { | ||||
|     auto err = fmt::format("Disabling module \"{}\", {}", name, e.what()); | ||||
|     std::cerr << err << std::endl; | ||||
|   } catch (...) { | ||||
|     auto err = fmt::format("Disabling module \"{}\", Unknown reason", name); | ||||
|     std::cerr << err << std::endl; | ||||
|   } | ||||
|   return nullptr; | ||||
| } | ||||
|   | ||||
| @@ -5,62 +5,66 @@ waybar::modules::Battery::Battery(Json::Value config) | ||||
| { | ||||
|   try { | ||||
|     for (auto &node : fs::directory_iterator(_data_dir)) { | ||||
|       if (fs::is_directory(node) && fs::exists(node / "capacity") | ||||
|         && fs::exists(node / "status")) { | ||||
|       if (fs::is_directory(node) && fs::exists(node / "capacity")) | ||||
|         _batteries.push_back(node); | ||||
|     } | ||||
|     } | ||||
|   } catch (fs::filesystem_error &e) { | ||||
|     std::cerr << e.what() << std::endl; | ||||
|     throw std::runtime_error(e.what()); | ||||
|   } | ||||
|  | ||||
|   if (!_batteries.size()) { | ||||
|     std::cerr << "No batteries." << std::endl; | ||||
|     return; | ||||
|   } | ||||
|   if (!_batteries.size()) | ||||
|     throw std::runtime_error("No batteries."); | ||||
|  | ||||
|   auto fd = inotify_init(); | ||||
|   if (fd == -1) | ||||
|     throw std::runtime_error("Unable to listen batteries."); | ||||
|   for (auto &bat : _batteries) | ||||
|     inotify_add_watch(fd, (bat / "uevent").c_str(), IN_ACCESS); | ||||
|   // Trigger first value | ||||
|   update(); | ||||
|   _label.get_style_context()->add_class("battery"); | ||||
|   int interval = _config["interval"] ? _config["inveral"].asInt() : 1; | ||||
|   _thread = [this, interval] { | ||||
|   _thread = [this, fd] { | ||||
|     struct inotify_event event; | ||||
|     int nbytes = read(fd, &event, sizeof(event)); | ||||
|     if (nbytes != sizeof(event)) | ||||
|       return; | ||||
|     Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Battery::update)); | ||||
|     _thread.sleep_for(chrono::seconds(interval)); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| auto waybar::modules::Battery::update() -> void | ||||
| { | ||||
|   try { | ||||
|     int total = 0; | ||||
|     uint16_t total = 0; | ||||
|     bool charging = false; | ||||
|     for (auto &bat : _batteries) { | ||||
|       int capacity; | ||||
|     std::string status; | ||||
|     for (auto &bat : _batteries) { | ||||
|       uint16_t capacity; | ||||
|       std::ifstream(bat / "capacity") >> capacity; | ||||
|       total += capacity; | ||||
|       std::ifstream(bat / "status") >> status; | ||||
|       if (status == "Charging") { | ||||
|       if (status == "Charging") | ||||
|         charging = true; | ||||
|       total += capacity; | ||||
|     } | ||||
|     } | ||||
|     uint16_t capacity = total / _batteries.size(); | ||||
|     auto format = _config["format"] ? _config["format"].asString() : "{}%"; | ||||
|     auto value = total / _batteries.size(); | ||||
|     _label.set_text(fmt::format(format, fmt::arg("value", value), | ||||
|       fmt::arg("icon", _getIcon(value)))); | ||||
|     _label.set_tooltip_text(charging ? "Charging" : "Discharging"); | ||||
|     _label.set_text(fmt::format(format, fmt::arg("value", capacity), | ||||
|       fmt::arg("icon", _getIcon(capacity)))); | ||||
|     _label.set_tooltip_text(status); | ||||
|     if (charging) | ||||
|       _label.get_style_context()->add_class("charging"); | ||||
|     else | ||||
|       _label.get_style_context()->remove_class("charging"); | ||||
|     if (value < 16 && !charging) | ||||
|     if (capacity < 16 && !charging) | ||||
|       _label.get_style_context()->add_class("warning"); | ||||
|     else | ||||
|       _label.get_style_context()->remove_class("warning"); | ||||
|   } catch (std::exception &e) { | ||||
|   } catch (const std::exception& e) { | ||||
|     std::cerr << e.what() << std::endl; | ||||
|   } | ||||
| } | ||||
|  | ||||
| std::string waybar::modules::Battery::_getIcon(uint32_t percentage) | ||||
| std::string waybar::modules::Battery::_getIcon(uint16_t percentage) | ||||
| { | ||||
|   if (!_config["format-icons"] || !_config["format-icons"].isArray()) return ""; | ||||
|   auto step = 100 / _config["format-icons"].size(); | ||||
|   | ||||
| @@ -4,10 +4,8 @@ | ||||
| waybar::modules::Custom::Custom(std::string name, Json::Value config) | ||||
|   : _name(name), _config(config) | ||||
| { | ||||
|   if (!_config["exec"]) { | ||||
|     std::cerr << name + " has no exec path." << std::endl; | ||||
|     return; | ||||
|   } | ||||
|   if (!_config["exec"]) | ||||
|     throw std::runtime_error(name + " has no exec path."); | ||||
|   int interval = _config["interval"] ? _config["inveral"].asInt() : 30; | ||||
|   _thread = [this, interval] { | ||||
|     Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Custom::update)); | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| #include "modules/network.hpp" | ||||
|  | ||||
| waybar::modules::Network::Network(Json::Value config) | ||||
|   : _config(config), _ifid(if_nametoindex(config["interface"].asString().c_str())) | ||||
|   : _config(config), _ifid(if_nametoindex(config["interface"].asCString())) | ||||
| { | ||||
|   if (_ifid == 0) | ||||
|     throw std::runtime_error("Can't found network interface"); | ||||
|   _label.get_style_context()->add_class("network"); | ||||
|   int interval = _config["interval"] ? _config["inveral"].asInt() : 30; | ||||
|   _thread = [this, interval] { | ||||
| @@ -103,8 +105,6 @@ bool waybar::modules::Network::_associatedOrJoined(struct nlattr** bss) | ||||
|  | ||||
| auto waybar::modules::Network::_getInfo() -> void | ||||
| { | ||||
|   if (_ifid == 0) | ||||
|     return; | ||||
| 	struct nl_sock *sk = nl_socket_alloc(); | ||||
| 	if (genl_connect(sk) != 0) { | ||||
|     nl_socket_free(sk); | ||||
|   | ||||
| @@ -5,17 +5,12 @@ waybar::modules::Workspaces::Workspaces(Bar &bar) | ||||
|   : _bar(bar) | ||||
| { | ||||
|   _box.get_style_context()->add_class("workspaces"); | ||||
|   try { | ||||
|   std::string socketPath = get_socketpath(); | ||||
|   _ipcSocketfd = ipc_open_socket(socketPath); | ||||
|   _ipcEventSocketfd = ipc_open_socket(socketPath); | ||||
|   const char *subscribe = "[ \"workspace\", \"mode\" ]"; | ||||
|   uint32_t len = strlen(subscribe); | ||||
|   ipc_single_command(_ipcEventSocketfd, IPC_SUBSCRIBE, subscribe, &len); | ||||
|   } catch (const std::exception& e) { | ||||
|     std::cerr << e.what() << std::endl; | ||||
|     return; | ||||
|   } | ||||
|   _thread = [this] { | ||||
|     Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Workspaces::update)); | ||||
|     _thread.sleep_for(chrono::milliseconds(250)); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Alex
					Alex