From b57086aa4362117c1f1025246f618d760e44b026 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 16 Oct 2024 22:22:36 +0100 Subject: [PATCH] window: properly break cycles in X11TransientFor ref #8045 --- src/desktop/Window.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index fa85dc07..a393f361 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -451,15 +451,21 @@ PHLWINDOW CWindow::X11TransientFor() { if (!m_pXWaylandSurface || !m_pXWaylandSurface->parent) return nullptr; - auto s = m_pXWaylandSurface->parent; - auto oldParent = s; + auto s = m_pXWaylandSurface->parent; + std::vector> visited; while (s) { - // break cyclic loop of m_pXWaylandSurface being parent of itself, #TODO reject this from even being created? - if (!s->parent || s->parent == oldParent) + // break loops. Some X apps make them, and it seems like it's valid behavior?!?!?! + // TODO: we should reject loops being created in the first place. + if (std::find(visited.begin(), visited.end(), s) != visited.end()) break; + + visited.emplace_back(s.lock()); s = s->parent; } + if (s == m_pXWaylandSurface) + return nullptr; // dead-ass circle + for (auto const& w : g_pCompositor->m_vWindows) { if (w->m_pXWaylandSurface != s) continue;