diff options
Diffstat (limited to 'Userland/Services')
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.cpp | 158 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.h | 1 |
2 files changed, 82 insertions, 77 deletions
diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 70bc4fcbe4..e63860cd01 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -919,17 +919,39 @@ void WindowManager::deliver_mouse_event(Window& window, MouseEvent& event, bool } } +bool WindowManager::process_ongoing_active_input_mouse_event(MouseEvent& event, Window*& hovered_window) +{ + if (!m_active_input_tracking_window) + return false; + + // At this point, we have delivered the start of an input sequence to a + // client application. We must keep delivering to that client + // application until the input sequence is done. + // + // This prevents e.g. moving on one window out of the bounds starting + // a move in that other unrelated window, and other silly shenanigans. + auto translated_event = event.translated(-m_active_input_tracking_window->position()); + deliver_mouse_event(*m_active_input_tracking_window, translated_event, true); + + if (event.type() == Event::MouseUp && event.buttons() == 0) { + m_active_input_tracking_window = nullptr; + } + + hovered_window = m_window_stack.window_at(event.position()); + return true; +} + void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_window) { - Window* received_mouse_event = nullptr; + hovered_window = nullptr; + if (process_ongoing_active_input_mouse_event(event, hovered_window)) + return; // 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; - hovered_window = nullptr; - if (process_ongoing_window_move(event, hovered_window)) return; @@ -972,90 +994,73 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind } Window* event_window_with_frame = nullptr; + Window* received_mouse_event = nullptr; - if (m_active_input_tracking_window) { - // At this point, we have delivered the start of an input sequence to a - // client application. We must keep delivering to that client - // application until the input sequence is done. - // - // This prevents e.g. moving on one window out of the bounds starting - // a move in that other unrelated window, and other silly shenanigans. - 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; - } + auto process_mouse_event_for_window = [&](Window& window) { + if (&window != m_resize_candidate.ptr()) + clear_resize_candidate(); - hovered_window = m_window_stack.window_at(event.position()); - } else { - auto process_mouse_event_for_window = [&](Window& window) { - if (&window != m_resize_candidate.ptr()) - clear_resize_candidate(); - - // First check if we should initiate a move or resize (Super+LMB or Super+RMB). - // In those cases, the event is swallowed by the window manager. - if (window.is_movable()) { - if (!window.is_fullscreen() && m_keyboard_modifiers == Mod_Super && event.type() == Event::MouseDown && event.button() == MouseButton::Left) { - hovered_window = &window; - start_window_move(window, event); - return; - } - if (window.is_resizable() && m_keyboard_modifiers == Mod_Super && event.type() == Event::MouseDown && event.button() == MouseButton::Right && !window.blocking_modal_window()) { - hovered_window = &window; - start_window_resize(window, event); - return; - } + // First check if we should initiate a move or resize (Super+LMB or Super+RMB). + // In those cases, the event is swallowed by the window manager. + if (window.is_movable()) { + if (!window.is_fullscreen() && m_keyboard_modifiers == Mod_Super && event.type() == Event::MouseDown && event.button() == MouseButton::Left) { + hovered_window = &window; + start_window_move(window, event); + return; } - - VERIFY(window.hit_test(event.position()).has_value()); - if (event.type() == Event::MouseDown) { - // We're clicking on something that's blocked by a modal window. - // Flash the modal window to let the user know about it. - if (auto* blocking_modal_window = window.blocking_modal_window()) - blocking_modal_window->frame().start_flash_animation(); - - if (window.type() == WindowType::Normal || window.type() == WindowType::ToolWindow) - move_to_front_and_make_active(window); - else if (window.type() == WindowType::Desktop) - set_active_window(&window); + if (window.is_resizable() && m_keyboard_modifiers == Mod_Super && event.type() == Event::MouseDown && event.button() == MouseButton::Right && !window.blocking_modal_window()) { + hovered_window = &window; + start_window_resize(window, event); + return; } + } - if (window.frame().hit_test(event.position()).has_value()) { - // We are hitting the frame, pass the event along to WindowFrame. - window.frame().handle_mouse_event(event.translated(-window.frame().rect().location())); - event_window_with_frame = &window; - } else if (window.hit_test(event.position(), false).has_value()) { - // We are hitting the window content - hovered_window = &window; - if (!window.global_cursor_tracking() && !window.blocking_modal_window()) { - auto translated_event = event.translated(-window.position()); - deliver_mouse_event(window, translated_event, true); - received_mouse_event = &window; - if (event.type() == Event::MouseDown) { - m_active_input_tracking_window = window; - } + VERIFY(window.hit_test(event.position()).has_value()); + if (event.type() == Event::MouseDown) { + // We're clicking on something that's blocked by a modal window. + // Flash the modal window to let the user know about it. + if (auto* blocking_modal_window = window.blocking_modal_window()) + blocking_modal_window->frame().start_flash_animation(); + + if (window.type() == WindowType::Normal || window.type() == WindowType::ToolWindow) + move_to_front_and_make_active(window); + else if (window.type() == WindowType::Desktop) + set_active_window(&window); + } + + if (window.frame().hit_test(event.position()).has_value()) { + // We are hitting the frame, pass the event along to WindowFrame. + window.frame().handle_mouse_event(event.translated(-window.frame().rect().location())); + event_window_with_frame = &window; + } else if (window.hit_test(event.position(), false).has_value()) { + // We are hitting the window content + hovered_window = &window; + if (!window.global_cursor_tracking() && !window.blocking_modal_window()) { + auto translated_event = event.translated(-window.position()); + deliver_mouse_event(window, translated_event, true); + received_mouse_event = &window; + if (event.type() == Event::MouseDown) { + m_active_input_tracking_window = window; } } - }; - - if (auto* fullscreen_window = active_fullscreen_window()) { - process_mouse_event_for_window(*fullscreen_window); - } else { - m_window_stack.for_each_visible_window_from_front_to_back([&](Window& window) { - if (!window.hit_test(event.position()).has_value()) - return IterationDecision::Continue; - process_mouse_event_for_window(window); - return IterationDecision::Break; - }); } + }; - // Clicked outside of any window - if (!hovered_window && !event_window_with_frame && event.type() == Event::MouseDown) - set_active_window(nullptr); + if (auto* fullscreen_window = active_fullscreen_window()) { + process_mouse_event_for_window(*fullscreen_window); + } else { + m_window_stack.for_each_visible_window_from_front_to_back([&](Window& window) { + if (!window.hit_test(event.position()).has_value()) + return IterationDecision::Continue; + process_mouse_event_for_window(window); + return IterationDecision::Break; + }); } + // Clicked outside of any window + if (!hovered_window && !event_window_with_frame && event.type() == Event::MouseDown) + set_active_window(nullptr); + auto reverse_iterator = m_window_stack.windows().rbegin(); for (; reverse_iterator != m_window_stack.windows().rend(); ++reverse_iterator) { auto& window = *reverse_iterator; @@ -1620,5 +1625,4 @@ void WindowManager::set_window_with_active_menu(Window* window) else m_window_with_active_menu = nullptr; } - } diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index def645aea2..9ab46fc427 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -239,6 +239,7 @@ private: bool process_ongoing_window_resize(MouseEvent const&, Window*& hovered_window); bool process_ongoing_window_move(MouseEvent&, Window*& hovered_window); bool process_ongoing_drag(MouseEvent&, Window*& hovered_window); + bool process_ongoing_active_input_mouse_event(MouseEvent&, Window*& hovered_window); template<typename Callback> void for_each_window_manager(Callback); |