From 6e0b50567ee353870d34e3aa391f9f728371fc9b Mon Sep 17 00:00:00 2001 From: Adrian Ratiu Date: Fri, 3 Jul 2026 15:53:45 +0300 Subject: [PATCH] fix(sway/ipc): don't mistake events for the subscribe reply Ipc::subscribe() assumes the next message on the event socket is the reply to the IPC_SUBSCRIBE it just sent. When a module subscribes more than once (sway/workspaces subscribes to "workspace" and then to "window"), an event from the first subscription can arrive before the reply to the second one. The payload check fails and the thrown exception permanently disables the module for that bar. This is easy to hit when bars are (re)created on output hotplug, since sway emits a burst of workspace events at exactly that moment while moving workspaces to the new output: [warning] module sway/workspaces: Disabling module "sway/workspaces", Unable to subscribe ipc event Fix it by skipping over event messages (type high bit set) until the subscribe reply is found, re-emitting them on signal_event so none are lost. Fixes: #5218 Co-Authored-By: Claude Fable 5 Signed-off-by: Adrian Ratiu --- src/modules/sway/ipc/client.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/modules/sway/ipc/client.cpp b/src/modules/sway/ipc/client.cpp index ce67279c..6d6c07ff 100644 --- a/src/modules/sway/ipc/client.cpp +++ b/src/modules/sway/ipc/client.cpp @@ -193,6 +193,13 @@ void Ipc::sendCmd(uint32_t type, const std::string& payload) { void Ipc::subscribe(const std::string& payload) { auto res = Ipc::send(fd_event_, IPC_SUBSCRIBE, payload); + // Events subscribed to by a previous subscribe() call may arrive on the + // socket before the reply to this one; deliver them and keep reading until + // the subscribe reply is found. + while ((res.type >> 31) != 0U) { + signal_event.emit(res); + res = Ipc::recv(fd_event_); + } if (res.payload != "{\"success\": true}") { throw std::runtime_error("Unable to subscribe ipc event"); }