From f88361fc281c35ad29f7c3bbff01f78eb8deb885 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 18 Jun 2021 01:03:15 +0200 Subject: [PATCH] WindowServer: Add WindowStack::window_at() and use it a bunch This performs a hit test on the window stack to find the window under a given cursor position. --- .../Services/WindowServer/WindowManager.cpp | 24 +++---------------- .../Services/WindowServer/WindowStack.cpp | 20 ++++++++++++++++ Userland/Services/WindowServer/WindowStack.h | 4 ++++ 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 3a72630e0a..f8f6aebc8f 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -765,14 +765,7 @@ bool WindowManager::process_ongoing_drag(MouseEvent& event, Window*& hovered_win if (!(event.type() == Event::MouseUp && event.button() == MouseButton::Left)) return true; - hovered_window = nullptr; - m_window_stack.for_each_visible_window_from_front_to_back([&](auto& window) { - if (window.hit_test(event.position()).has_value()) { - hovered_window = &window; - return IterationDecision::Break; - } - return IterationDecision::Continue; - }); + hovered_window = m_window_stack.window_at(event.position()); if (hovered_window) { m_dnd_client->async_drag_accepted(); @@ -995,13 +988,7 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind m_active_input_tracking_window = nullptr; } - m_window_stack.for_each_visible_window_from_front_to_back([&](auto& window) { - if (window.hit_test(event.position()).has_value()) { - hovered_window = &window; - return IterationDecision::Break; - } - return IterationDecision::Continue; - }); + hovered_window = m_window_stack.window_at(event.position()); } else { auto process_mouse_event_for_window = [&](Window& window) { if (&window != m_resize_candidate.ptr()) @@ -1101,12 +1088,7 @@ void WindowManager::reevaluate_hovered_window(Window* updated_window) if (fullscreen_window->hit_test(cursor_location).has_value()) hovered_window = fullscreen_window; } else { - m_window_stack.for_each_visible_window_from_front_to_back([&](Window& window) { - if (!window.hit_test(cursor_location).has_value()) - return IterationDecision::Continue; - hovered_window = &window; - return IterationDecision::Break; - }); + hovered_window = m_window_stack.window_at(cursor_location); } if (set_hovered_window(hovered_window)) { diff --git a/Userland/Services/WindowServer/WindowStack.cpp b/Userland/Services/WindowServer/WindowStack.cpp index de0e5ad741..fdff6f4bbe 100644 --- a/Userland/Services/WindowServer/WindowStack.cpp +++ b/Userland/Services/WindowServer/WindowStack.cpp @@ -38,6 +38,14 @@ void WindowStack::move_to_front(Window& window) m_windows.append(window); } +Window* WindowStack::window_at(Gfx::IntPoint const& position) const +{ + auto result = hit_test(position); + if (!result.has_value()) + return nullptr; + return result->window; +} + void WindowStack::set_highlight_window(Window* window) { if (!window) @@ -54,4 +62,16 @@ void WindowStack::set_active_window(Window* window) m_active_window = window->make_weak_ptr(); } +Optional WindowStack::hit_test(Gfx::IntPoint const& position) const +{ + Optional result; + const_cast(this)->for_each_visible_window_from_front_to_back([&](Window& window) { + result = window.hit_test(position); + if (result.has_value()) + return IterationDecision::Break; + return IterationDecision::Continue; + }); + return result; +} + } diff --git a/Userland/Services/WindowServer/WindowStack.h b/Userland/Services/WindowServer/WindowStack.h index 768134c255..f11a43ba3f 100644 --- a/Userland/Services/WindowServer/WindowStack.h +++ b/Userland/Services/WindowServer/WindowStack.h @@ -20,6 +20,8 @@ public: void remove(Window&); void move_to_front(Window&); + Window* window_at(Gfx::IntPoint const&) const; + template IterationDecision for_each_visible_window_from_back_to_front(Callback); template @@ -44,6 +46,8 @@ public: Window const* active_window() const { return m_active_window; } void set_active_window(Window*); + Optional hit_test(Gfx::IntPoint const&) const; + private: WeakPtr m_highlight_window; WeakPtr m_active_window;