diff --git a/Userland/Services/WindowServer/MenuManager.cpp b/Userland/Services/WindowServer/MenuManager.cpp index f7521ff060..5f57c4dc03 100644 --- a/Userland/Services/WindowServer/MenuManager.cpp +++ b/Userland/Services/WindowServer/MenuManager.cpp @@ -225,7 +225,7 @@ void MenuManager::handle_mouse_event(MouseEvent& mouse_event) if (event_is_inside_current_menu) { WindowManager::the().set_hovered_window(window); auto translated_event = mouse_event.translated(-window->position()); - WindowManager::the().deliver_mouse_event(*window, translated_event); + WindowManager::the().deliver_mouse_event(*window, translated_event, true); return; } @@ -262,7 +262,7 @@ void MenuManager::handle_mouse_event(MouseEvent& mouse_event) continue; WindowManager::the().set_hovered_window(menu->menu_window()); auto translated_event = mouse_event.translated(-menu->menu_window()->position()); - WindowManager::the().deliver_mouse_event(*menu->menu_window(), translated_event); + WindowManager::the().deliver_mouse_event(*menu->menu_window(), translated_event, true); break; } } diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index e2dc90e86a..d9b3c729a3 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -716,7 +716,7 @@ bool WindowManager::process_ongoing_drag(MouseEvent& event, Window*& hovered_win auto translated_event = event.translated(-window.position()); translated_event.set_drag(true); translated_event.set_mime_data(*m_dnd_mime_data); - deliver_mouse_event(window, translated_event); + deliver_mouse_event(window, translated_event, false); return IterationDecision::Break; }); } @@ -875,10 +875,10 @@ void WindowManager::process_event_for_doubleclick(Window& window, MouseEvent& ev metadata.last_position = event.position(); } -void WindowManager::deliver_mouse_event(Window& window, MouseEvent& event) +void WindowManager::deliver_mouse_event(Window& window, MouseEvent& event, bool process_double_click) { window.dispatch_event(event); - if (event.type() == Event::MouseUp) { + if (process_double_click && event.type() == Event::MouseUp) { process_event_for_doubleclick(window, event); if (event.type() == Event::MouseDoubleClick) window.dispatch_event(event); @@ -887,21 +887,13 @@ void WindowManager::deliver_mouse_event(Window& window, MouseEvent& event) void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_window) { - HashTable windows_who_received_mouse_event_due_to_cursor_tracking; + Window* received_mouse_event = nullptr; // We need to process ongoing drag events first. Otherwise, global tracking // and dnd collides, leading to duplicate GUI::DragOperation instances if (process_ongoing_drag(event, hovered_window)) return; - for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) { - if (!window->global_cursor_tracking() || !window->is_visible() || window->is_minimized() || window->blocking_modal_window()) - continue; - windows_who_received_mouse_event_due_to_cursor_tracking.set(window); - auto translated_event = event.translated(-window->position()); - deliver_mouse_event(*window, translated_event); - } - hovered_window = nullptr; if (process_ongoing_window_move(event, hovered_window)) @@ -939,11 +931,10 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind // // This prevents e.g. moving on one window out of the bounds starting // a move in that other unrelated window, and other silly shenanigans. - if (!windows_who_received_mouse_event_due_to_cursor_tracking.contains(m_active_input_tracking_window)) { - auto translated_event = event.translated(-m_active_input_tracking_window->position()); - deliver_mouse_event(*m_active_input_tracking_window, translated_event); - windows_who_received_mouse_event_due_to_cursor_tracking.set(m_active_input_tracking_window.ptr()); - } + auto translated_event = event.translated(-m_active_input_tracking_window->position()); + deliver_mouse_event(*m_active_input_tracking_window, translated_event, true); + received_mouse_event = m_active_input_tracking_window.ptr(); + if (event.type() == Event::MouseUp && event.buttons() == 0) { m_active_input_tracking_window = nullptr; } @@ -1002,9 +993,10 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind // Well okay, let's see if we're hitting the frame or the window inside the frame. if (window.rect().contains(event.position())) { hovered_window = &window; - if (!window.global_cursor_tracking() && !windows_who_received_mouse_event_due_to_cursor_tracking.contains(&window) && !window.blocking_modal_window()) { + if (!window.global_cursor_tracking() && !window.blocking_modal_window()) { auto translated_event = event.translated(-window.position()); - deliver_mouse_event(window, translated_event); + deliver_mouse_event(window, translated_event, true); + received_mouse_event = &window; if (event.type() == Event::MouseDown) { m_active_input_tracking_window = window; } @@ -1034,6 +1026,15 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind set_active_window(nullptr); } + for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) { + if (received_mouse_event == window) + continue; + if (!window->global_cursor_tracking() || !window->is_visible() || window->is_minimized() || window->blocking_modal_window()) + continue; + auto translated_event = event.translated(-window->position()); + deliver_mouse_event(*window, translated_event, false); + } + if (event_window_with_frame != m_resize_candidate.ptr()) clear_resize_candidate(); } diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index 7711a19af9..21cb345f85 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -190,7 +190,7 @@ public: bool update_theme(String theme_path, String theme_name); void set_hovered_window(Window*); - void deliver_mouse_event(Window& window, MouseEvent& event); + void deliver_mouse_event(Window& window, MouseEvent& event, bool process_double_click); void did_popup_a_menu(Badge);