From 4229dc8ac262d145b4aa4af3eb8d08f814dfd90a Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 4 Jul 2026 03:12:46 +0200 Subject: [PATCH] fix(sway/window): resolve app icon on the main thread to stop icon-theme race onCmd() runs on the sway IPC worker thread and called updateAppIconName(), which touches the global Gtk::IconTheme cache. Concurrent access with the main thread's draw (propagate_draw -> gtk_icon_theme_has_icon -> g_hash_table_lookup) races and can segfault, notably on multi-monitor and focus changes. Move the icon-theme lookup into Window::update(), which runs on the main thread via dp.emit(), and only store app_id_/app_class_ in onCmd(). Fixes #4108. --- src/modules/sway/window.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/modules/sway/window.cpp b/src/modules/sway/window.cpp index 2b62da14..f005bd14 100644 --- a/src/modules/sway/window.cpp +++ b/src/modules/sway/window.cpp @@ -43,7 +43,9 @@ void Window::onCmd(const struct Ipc::ipc_response& res) { auto output = payload["output"].isString() ? payload["output"].asString() : ""; std::tie(app_nb_, floating_count_, windowId_, window_, app_id_, app_class_, shell_, layout_, marks_) = getFocusedNode(payload["nodes"], output); - updateAppIconName(app_id_, app_class_); + // Do not resolve the app icon here: onCmd runs on the sway IPC worker thread and + // updateAppIconName() touches the global Gtk::IconTheme cache, which is not thread-safe. + // The icon is resolved in update() on the main thread instead (triggered by dp.emit()). dp.emit(); } catch (const std::exception& e) { spdlog::error("Window: {}", e.what()); @@ -102,6 +104,9 @@ auto Window::update() -> void { setTooltipMarkup(window_); } + // Resolve the app icon on the main thread to avoid racing with GTK draw on the + // global Gtk::IconTheme cache (see onCmd). + updateAppIconName(app_id_, app_class_); updateAppIcon(); // Call parent update