From 83e1949dd8435d5f8991de366a8327a2a6e58786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emir=20Baha=20Y=C4=B1ld=C4=B1r=C4=B1m?= Date: Thu, 19 Mar 2026 19:32:21 +0300 Subject: [PATCH] fix(hyprland/window): Fix segfault caused by use-after-free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The window module registers itself with the Hyprland IPC singleton at the start of its constructor, before calling update(). If update() throws an exception (e.g. from an invalid format string), the object is destroyed without the destructor running, leaving a dangling pointer in the IPC callback list. When the IPC thread receives an event, it attempts to call onEvent() on this invalid memory, causing a crash. Moving the update() call before IPC registration ensures that any initialization errors occur before the pointer is shared. If the configuration is invalid, the module fails to construct and is gracefully disabled by the factory without leaving a "landmine" in the background IPC thread. Fixes: #4923 Signed-off-by: Emir Baha Yıldırım --- src/modules/hyprland/window.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/modules/hyprland/window.cpp b/src/modules/hyprland/window.cpp index d3fe6edf..2e3e0bb9 100644 --- a/src/modules/hyprland/window.cpp +++ b/src/modules/hyprland/window.cpp @@ -19,20 +19,19 @@ std::shared_mutex windowIpcSmtx; Window::Window(const std::string& id, const Bar& bar, const Json::Value& config) : AAppIconLabel(config, "window", id, "{title}", 0, true), bar_(bar), m_ipc(IPC::inst()) { - std::unique_lock windowIpcUniqueLock(windowIpcSmtx); - separateOutputs_ = config["separate-outputs"].asBool(); + update(); + // register for hyprland ipc + std::unique_lock windowIpcUniqueLock(windowIpcSmtx); m_ipc.registerForIPC("activewindow", this); m_ipc.registerForIPC("closewindow", this); m_ipc.registerForIPC("movewindow", this); m_ipc.registerForIPC("changefloatingmode", this); m_ipc.registerForIPC("fullscreen", this); - windowIpcUniqueLock.unlock(); - update(); dp.emit(); }