diff --git a/Services/WindowServer/Window.cpp b/Services/WindowServer/Window.cpp index e6387014b4..452b28e71f 100644 --- a/Services/WindowServer/Window.cpp +++ b/Services/WindowServer/Window.cpp @@ -634,4 +634,17 @@ void Window::set_progress(int progress) WindowManager::the().notify_progress_changed(*this); } +bool Window::is_descendant_of(Window& window) const +{ + for (auto* parent = parent_window(); parent; parent = parent->parent_window()) { + if (parent == &window) + return true; + for (auto& accessory : parent->accessory_windows()) { + if (accessory == &window) + return true; + } + } + return false; +} + } diff --git a/Services/WindowServer/Window.h b/Services/WindowServer/Window.h index 0fc84bf853..718d238c71 100644 --- a/Services/WindowServer/Window.h +++ b/Services/WindowServer/Window.h @@ -244,6 +244,8 @@ public: Vector>& accessory_windows() { return m_accessory_windows; } const Vector>& accessory_windows() const { return m_accessory_windows; } + bool is_descendant_of(Window&) const; + void set_accessory(bool accessory) { m_accessory = accessory; } bool is_accessory() const; bool is_accessory_of(Window&) const; diff --git a/Services/WindowServer/WindowManager.h b/Services/WindowServer/WindowManager.h index 2fac08daef..f1c351b1da 100644 --- a/Services/WindowServer/WindowManager.h +++ b/Services/WindowServer/WindowManager.h @@ -193,7 +193,8 @@ public: Vector modal_stack; auto* modal_stack_top = blocking_modal_window ? blocking_modal_window : &window; for (auto* parent = modal_stack_top->parent_window(); parent; parent = parent->parent_window()) { - if (parent->is_blocked_by_modal_window() != modal_stack_top) + auto* blocked_by = parent->is_blocked_by_modal_window(); + if (!blocked_by || (blocked_by != modal_stack_top && !modal_stack_top->is_descendant_of(*blocked_by))) break; modal_stack.append(parent); if (!parent->is_modal())