mirror of
				https://github.com/rad4day/Waybar.git
				synced 2025-10-29 23:22:41 +01:00 
			
		
		
		
	refactor(ipc): clean
This commit is contained in:
		| @@ -25,7 +25,8 @@ int ipcOpenSocket(const std::string &socketPath); | ||||
|  * Issues a single IPC command and returns the buffer. len will be updated with | ||||
|  * the length of the buffer returned from sway. | ||||
|  */ | ||||
| std::string ipcSingleCommand(int socketfd, uint32_t type, const char *payload, uint32_t *len); | ||||
| struct ipc_response ipcSingleCommand(int socketfd, uint32_t type, | ||||
|   const std::string& payload); | ||||
| /** | ||||
|  * Receives a single IPC response and returns an ipc_response. | ||||
|  */ | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
| #include <sys/socket.h> | ||||
| #include <sys/un.h> | ||||
|  | ||||
| static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'}; | ||||
| static const size_t ipc_header_size = sizeof(ipc_magic)+8; | ||||
| static const std::string ipc_magic("i3-ipc"); | ||||
| static const size_t ipc_header_size = ipc_magic.size() + 8; | ||||
|  | ||||
| std::string getSocketPath() { | ||||
|   const char *env = getenv("SWAYSOCK"); | ||||
| @@ -50,50 +50,48 @@ int ipcOpenSocket(const std::string &socketPath) { | ||||
| } | ||||
|  | ||||
| struct ipc_response ipcRecvResponse(int socketfd) { | ||||
|   struct ipc_response response; | ||||
|   char data[ipc_header_size]; | ||||
|   auto data32 = reinterpret_cast<uint32_t *>(data + sizeof(ipc_magic)); | ||||
|   std::string header; | ||||
|   header.reserve(ipc_header_size); | ||||
|   auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic.size()); | ||||
|   size_t total = 0; | ||||
|  | ||||
|   while (total < ipc_header_size) { | ||||
|     ssize_t received = recv(socketfd, data + total, ipc_header_size - total, 0); | ||||
|     if (received <= 0) { | ||||
|     ssize_t res = | ||||
|       ::recv(socketfd, header.data() + total, ipc_header_size - total, 0); | ||||
|     if (res <= 0) { | ||||
|       throw std::runtime_error("Unable to receive IPC response"); | ||||
|     } | ||||
|     total += received; | ||||
|     total += res; | ||||
|   } | ||||
|  | ||||
|   total = 0; | ||||
|   response.size = data32[0]; | ||||
|   response.type = data32[1]; | ||||
|   char payload[response.size + 1]; | ||||
|  | ||||
|   while (total < response.size) { | ||||
|     ssize_t received = recv(socketfd, payload + total, response.size - total, 0); | ||||
|     if (received < 0) { | ||||
|   std::string payload; | ||||
|   payload.reserve(data32[0]); | ||||
|   while (total < data32[0]) { | ||||
|     ssize_t res = | ||||
|       ::recv(socketfd, payload.data() + total, data32[0] - total, 0); | ||||
|     if (res < 0) { | ||||
|       throw std::runtime_error("Unable to receive IPC response"); | ||||
|     } | ||||
|     total += received; | ||||
|     total += res; | ||||
|   } | ||||
|   payload[response.size] = '\0'; | ||||
|   response.payload = std::string(payload); | ||||
|   return response; | ||||
|   return { data32[0], data32[1], &payload.front() }; | ||||
| } | ||||
|  | ||||
| std::string ipcSingleCommand(int socketfd, uint32_t type, const char *payload, uint32_t *len) { | ||||
|   char data[ipc_header_size]; | ||||
|   auto data32 = reinterpret_cast<uint32_t *>(data + sizeof(ipc_magic)); | ||||
|   memcpy(data, ipc_magic, sizeof(ipc_magic)); | ||||
|   data32[0] = *len; | ||||
| struct ipc_response ipcSingleCommand(int socketfd, uint32_t type, | ||||
|   const std::string& payload) { | ||||
|   std::string header; | ||||
|   header.reserve(ipc_header_size); | ||||
|   auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic.size()); | ||||
|   memcpy(header.data(), ipc_magic.c_str(), ipc_magic.size()); | ||||
|   data32[0] = payload.size(); | ||||
|   data32[1] = type; | ||||
|  | ||||
|   if (send(socketfd, data, ipc_header_size, 0) == -1) { | ||||
|   if (send(socketfd, header.data(), ipc_header_size, 0) == -1) { | ||||
|     throw std::runtime_error("Unable to send IPC header"); | ||||
|   } | ||||
|   if (send(socketfd, payload, *len, 0) == -1) { | ||||
|   if (send(socketfd, payload.c_str(), payload.size(), 0) == -1) { | ||||
|     throw std::runtime_error("Unable to send IPC payload"); | ||||
|   } | ||||
|   struct ipc_response resp = ipcRecvResponse(socketfd); | ||||
|   *len = resp.size; | ||||
|   return resp.payload; | ||||
|   return ipcRecvResponse(socketfd); | ||||
| } | ||||
|   | ||||
| @@ -8,9 +8,7 @@ waybar::modules::sway::Window::Window(Bar &bar, Json::Value config) | ||||
|   std::string socketPath = getSocketPath(); | ||||
|   ipcfd_ = ipcOpenSocket(socketPath); | ||||
|   ipc_eventfd_ = ipcOpenSocket(socketPath); | ||||
|   const char *subscribe = "[ \"window\" ]"; | ||||
|   uint32_t len = strlen(subscribe); | ||||
|   ipcSingleCommand(ipc_eventfd_, IPC_SUBSCRIBE, subscribe, &len); | ||||
|   ipcSingleCommand(ipc_eventfd_, IPC_SUBSCRIBE, "[ \"window\" ]"); | ||||
|   getFocusedWindow(); | ||||
|   thread_ = [this] { | ||||
|     try { | ||||
| @@ -50,9 +48,8 @@ std::string waybar::modules::sway::Window::getFocusedNode(Json::Value nodes) | ||||
| void waybar::modules::sway::Window::getFocusedWindow() | ||||
| { | ||||
|   try { | ||||
|     uint32_t len = 0; | ||||
|     auto res = ipcSingleCommand(ipcfd_, IPC_GET_TREE, nullptr, &len); | ||||
|     auto parsed = parser_.parse(res); | ||||
|     auto res = ipcSingleCommand(ipcfd_, IPC_GET_TREE, ""); | ||||
|     auto parsed = parser_.parse(res.payload); | ||||
|     window_ = getFocusedNode(parsed["nodes"]); | ||||
|     Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Window::update)); | ||||
|   } catch (const std::exception &e) { | ||||
|   | ||||
| @@ -8,9 +8,7 @@ waybar::modules::sway::Workspaces::Workspaces(Bar &bar, Json::Value config) | ||||
|   std::string socketPath = getSocketPath(); | ||||
|   ipcfd_ = ipcOpenSocket(socketPath); | ||||
|   ipc_eventfd_ = ipcOpenSocket(socketPath); | ||||
|   const char *subscribe = "[ \"workspace\" ]"; | ||||
|   uint32_t len = strlen(subscribe); | ||||
|   ipcSingleCommand(ipc_eventfd_, IPC_SUBSCRIBE, subscribe, &len); | ||||
|   ipcSingleCommand(ipc_eventfd_, IPC_SUBSCRIBE, "[ \"workspace\" ]"); | ||||
|   thread_ = [this] { | ||||
|     try { | ||||
|       // Wait for the name of the output | ||||
| @@ -21,10 +19,9 @@ waybar::modules::sway::Workspaces::Workspaces(Bar &bar, Json::Value config) | ||||
|       } else if (!workspaces_.empty()) { | ||||
|         ipcRecvResponse(ipc_eventfd_); | ||||
|       } | ||||
|       uint32_t len = 0; | ||||
|       std::lock_guard<std::mutex> lock(mutex_); | ||||
|       auto str = ipcSingleCommand(ipcfd_, IPC_GET_WORKSPACES, nullptr, &len); | ||||
|       workspaces_ = parser_.parse(str); | ||||
|       auto res = ipcSingleCommand(ipcfd_, IPC_GET_WORKSPACES, ""); | ||||
|       workspaces_ = parser_.parse(res.payload); | ||||
|       Glib::signal_idle() | ||||
|         .connect_once(sigc::mem_fun(*this, &Workspaces::update)); | ||||
|     } catch (const std::exception& e) { | ||||
| @@ -97,9 +94,8 @@ void waybar::modules::sway::Workspaces::addWorkspace(Json::Value node) | ||||
|   button.signal_clicked().connect([this, pair] { | ||||
|     try { | ||||
|       std::lock_guard<std::mutex> lock(mutex_); | ||||
|       auto value = fmt::format("workspace \"{}\"", pair.first->first); | ||||
|       uint32_t size = value.size(); | ||||
|       ipcSingleCommand(ipcfd_, IPC_COMMAND, value.c_str(), &size); | ||||
|       auto cmd = fmt::format("workspace \"{}\"", pair.first->first); | ||||
|       ipcSingleCommand(ipcfd_, IPC_COMMAND, cmd); | ||||
|     } catch (const std::exception& e) { | ||||
|       std::cerr << e.what() << std::endl; | ||||
|     } | ||||
| @@ -173,9 +169,7 @@ bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e) | ||||
|     scrolling_ = false; | ||||
|     return false; | ||||
|   } | ||||
|   auto value = fmt::format("workspace \"{}\"", id); | ||||
|   uint32_t size = value.size(); | ||||
|   ipcSingleCommand(ipcfd_, IPC_COMMAND, value.c_str(), &size); | ||||
|   ipcSingleCommand(ipcfd_, IPC_COMMAND, fmt::format("workspace \"{}\"", id)); | ||||
|   std::this_thread::sleep_for(std::chrono::milliseconds(150)); | ||||
|   return true; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Alexis
					Alexis