mirror of
				https://github.com/rad4day/Waybar.git
				synced 2025-10-31 16:02:43 +01:00 
			
		
		
		
	added backend and hyprland/window
This commit is contained in:
		| @@ -21,6 +21,10 @@ | ||||
| #include "modules/river/tags.hpp" | ||||
| #include "modules/river/window.hpp" | ||||
| #endif | ||||
| #ifdef HAVE_HYPRLAND | ||||
| #include "modules/hyprland/backend.hpp" | ||||
| #include "modules/hyprland/window.hpp" | ||||
| #endif | ||||
| #if defined(__linux__) && !defined(NO_FILESYSTEM) | ||||
| #include "modules/battery.hpp" | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										30
									
								
								include/modules/hyprland/backend.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								include/modules/hyprland/backend.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #pragma once | ||||
| #include <string> | ||||
| #include <memory> | ||||
| #include <mutex> | ||||
| #include <deque> | ||||
| #include <functional> | ||||
| #include <thread> | ||||
|  | ||||
| namespace waybar::modules::hyprland { | ||||
| class IPC { | ||||
| public: | ||||
|   IPC() { startIPC(); } | ||||
|  | ||||
|   void registerForIPC(const std::string&, std::function<void(const std::string&)>); | ||||
|  | ||||
|   std::string getSocket1Reply(const std::string& rq); | ||||
|  | ||||
| private: | ||||
|  | ||||
|  void startIPC(); | ||||
|  void parseIPC(const std::string&); | ||||
|  | ||||
|  std::mutex callbackMutex; | ||||
|  std::deque<std::pair<std::string, std::function<void(const std::string&)>>> callbacks; | ||||
| }; | ||||
|  | ||||
| inline std::unique_ptr<IPC> gIPC; | ||||
| inline bool modulesReady = false; | ||||
| }; | ||||
|  | ||||
							
								
								
									
										29
									
								
								include/modules/hyprland/window.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								include/modules/hyprland/window.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #include <fmt/format.h> | ||||
|  | ||||
| #include <tuple> | ||||
|  | ||||
| #include "ALabel.hpp" | ||||
| #include "bar.hpp" | ||||
| #include "modules/hyprland/backend.hpp" | ||||
| #include "util/json.hpp" | ||||
|  | ||||
| namespace waybar::modules::hyprland { | ||||
|  | ||||
| class Window : public waybar::ALabel { | ||||
| public: | ||||
|   Window(const std::string&, const waybar::Bar&, const Json::Value&); | ||||
|   ~Window() = default; | ||||
|  | ||||
| private: | ||||
|   void onEvent(const std::string&); | ||||
|  | ||||
|   const Bar& bar_; | ||||
|   IPC ipc; | ||||
|   unsigned app_icon_size_{24}; | ||||
|   bool update_app_icon_{true}; | ||||
|   std::string app_icon_name_; | ||||
|   util::JsonParser parser_; | ||||
|   std::string lastView; | ||||
| }; | ||||
|  | ||||
| } | ||||
| @@ -201,6 +201,12 @@ if true | ||||
|     src_files += 'src/modules/river/window.cpp' | ||||
| endif | ||||
|  | ||||
| if true | ||||
|     add_project_arguments('-DHAVE_HYPRLAND', language: 'cpp') | ||||
|     src_files += 'src/modules/hyprland/backend.cpp' | ||||
|     src_files += 'src/modules/hyprland/window.cpp' | ||||
| endif | ||||
|  | ||||
| if libnl.found() and libnlgen.found() | ||||
|     add_project_arguments('-DHAVE_LIBNL', language: 'cpp') | ||||
|     src_files += 'src/modules/network.cpp' | ||||
|   | ||||
| @@ -56,6 +56,11 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { | ||||
|     if (ref == "river/window") { | ||||
|       return new waybar::modules::river::Window(id, bar_, config_[name]); | ||||
|     } | ||||
| #endif | ||||
| #ifdef HAVE_HYPRLAND | ||||
|     if (ref == "hyprland/window") { | ||||
|       return new waybar::modules::hyprland::Window(id, bar_, config_[name]); | ||||
|     } | ||||
| #endif | ||||
|     if (ref == "idle_inhibitor") { | ||||
|       return new waybar::modules::IdleInhibitor(id, bar_, config_[name]); | ||||
|   | ||||
							
								
								
									
										105
									
								
								src/modules/hyprland/backend.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/modules/hyprland/backend.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| #include "modules/hyprland/backend.hpp" | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <netinet/in.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/un.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include <spdlog/spdlog.h> | ||||
|  | ||||
| void waybar::modules::hyprland::IPC::startIPC() { | ||||
|   // will start IPC and relay events to parseIPC | ||||
|  | ||||
|   std::thread([&]() { | ||||
|     // check for hyprland | ||||
|     const char* HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE"); | ||||
|  | ||||
|     if (!HIS) { | ||||
|       spdlog::warn("Hyprland is not running, Hyprland IPC will not be available."); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     if (!modulesReady) return; | ||||
|  | ||||
|     spdlog::info("Hyprland IPC starting"); | ||||
|  | ||||
|     struct sockaddr_un addr; | ||||
|     int socketfd = socket(AF_UNIX, SOCK_STREAM, 0); | ||||
|  | ||||
|     if (socketfd == -1) { | ||||
|       spdlog::error("Hyprland IPC: socketfd failed"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     addr.sun_family = AF_UNIX; | ||||
|  | ||||
|     // socket path | ||||
|     std::string socketPath = "/tmp/hypr/" + std::string(HIS) + "/.socket2.sock"; | ||||
|  | ||||
|     strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1); | ||||
|  | ||||
|     addr.sun_path[sizeof(addr.sun_path) - 1] = 0; | ||||
|  | ||||
|     int l = sizeof(struct sockaddr_un); | ||||
|  | ||||
|     if (connect(socketfd, (struct sockaddr*)&addr, l) == -1) { | ||||
|       spdlog::error("Hyprland IPC: Unable to connect?"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     auto file = fdopen(socketfd, "r"); | ||||
|  | ||||
|     while (1) { | ||||
|       // read | ||||
|  | ||||
|       char buffer[1024];  // Hyprland socket2 events are max 1024 bytes | ||||
|       auto recievedCharPtr = fgets(buffer, 1024, file); | ||||
|  | ||||
|       if (!recievedCharPtr) { | ||||
|         std::this_thread::sleep_for(std::chrono::milliseconds(1)); | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       callbackMutex.lock(); | ||||
|  | ||||
|       std::string messageRecieved(buffer); | ||||
|  | ||||
|       messageRecieved = messageRecieved.substr(0, messageRecieved.find_first_of('\n')); | ||||
|  | ||||
|       spdlog::debug("hyprland IPC received {}", messageRecieved); | ||||
|  | ||||
|       parseIPC(messageRecieved); | ||||
|  | ||||
|       callbackMutex.unlock(); | ||||
|  | ||||
|       std::this_thread::sleep_for(std::chrono::milliseconds(1)); | ||||
|     } | ||||
|   }).detach(); | ||||
| } | ||||
|  | ||||
| void waybar::modules::hyprland::IPC::parseIPC(const std::string& ev) { | ||||
|   // todo | ||||
|   std::string request = ev.substr(0, ev.find_first_of('>')); | ||||
|  | ||||
|   for (auto& [eventname, handler] : callbacks) { | ||||
|     if (eventname == request) { | ||||
|       handler(ev); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void waybar::modules::hyprland::IPC::registerForIPC(const std::string& ev, | ||||
|                                                     std::function<void(const std::string&)> fn) { | ||||
|   callbackMutex.lock(); | ||||
|  | ||||
|   callbacks.emplace_back(std::make_pair(ev, fn)); | ||||
|  | ||||
|   callbackMutex.unlock(); | ||||
| } | ||||
							
								
								
									
										54
									
								
								src/modules/hyprland/window.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/modules/hyprland/window.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| #include "modules/hyprland/backend.hpp" | ||||
| #include "modules/hyprland/window.hpp" | ||||
|  | ||||
| #include <spdlog/spdlog.h> | ||||
|  | ||||
| namespace waybar::modules::hyprland { | ||||
|  | ||||
| Window::Window(const std::string& id, const Bar& bar, const Json::Value& config) | ||||
|     : ALabel(config, "window", id, "{}", 0, true), bar_(bar) { | ||||
|   modulesReady = true; | ||||
|  | ||||
|   if (!gIPC.get()) { | ||||
|     gIPC = std::make_unique<IPC>(); | ||||
|   } | ||||
|  | ||||
|   label_.hide(); | ||||
|   ALabel::update(); | ||||
|  | ||||
|   // register for hyprland ipc | ||||
|   gIPC->registerForIPC("activewindow", [&](const std::string& ev) { this->onEvent(ev); }); | ||||
| } | ||||
|  | ||||
| void Window::onEvent(const std::string& ev) { | ||||
|   auto windowName = ev.substr(ev.find_first_of(',') + 1).substr(0, 256); | ||||
|  | ||||
|   // fix ampersands | ||||
|   auto replaceAll = [](std::string str, const std::string& from, | ||||
|                        const std::string& to) -> std::string { | ||||
|     size_t start_pos = 0; | ||||
|     while ((start_pos = str.find(from, start_pos)) != std::string::npos) { | ||||
|       str.replace(start_pos, from.length(), to); | ||||
|       start_pos += to.length(); | ||||
|     } | ||||
|     return str; | ||||
|   }; | ||||
|  | ||||
|   windowName = replaceAll(windowName, "&", "&"); | ||||
|  | ||||
|   if (windowName == lastView) return; | ||||
|  | ||||
|   lastView = windowName; | ||||
|  | ||||
|   spdlog::debug("hyprland window onevent with {}", windowName); | ||||
|  | ||||
|   if (!format_.empty()) { | ||||
|     label_.show(); | ||||
|     label_.set_markup(fmt::format(format_, windowName)); | ||||
|   } else { | ||||
|     label_.hide(); | ||||
|   } | ||||
|  | ||||
|   ALabel::update(); | ||||
| } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 vaxerski
					vaxerski