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.
This commit is contained in:
Alex
2026-07-04 03:14:13 +02:00
parent c0a26104a5
commit 4229dc8ac2
+6 -1
View File
@@ -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