diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.cpp | 129 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.h | 7 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.cpp | 4 |
3 files changed, 84 insertions, 56 deletions
diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index 36b3e30f8b..5c8063f501 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -647,50 +647,80 @@ Optional<HitTestResult> WindowFrame::hit_test(Gfx::IntPoint const& position) con return {}; } -void WindowFrame::on_mouse_event(const MouseEvent& event) +bool WindowFrame::handle_titlebar_icon_mouse_event(MouseEvent const& event) { - VERIFY(!m_window.is_fullscreen()); + auto& wm = WindowManager::the(); + + if (event.type() == Event::MouseDown && (event.button() == MouseButton::Left || event.button() == MouseButton::Right)) { + // Manually start a potential double click. Since we're opening + // a menu, we will only receive the MouseDown event, so we + // need to record that fact. If the user subsequently clicks + // on the same area, the menu will get closed, and we will + // receive a MouseUp event, but because windows have changed + // we don't get a MouseDoubleClick event. We can however record + // this click, and when we receive the MouseUp event check if + // it would have been considered a double click, if it weren't + // for the fact that we opened and closed a window in the meanwhile + wm.start_menu_doubleclick(m_window, event); + + m_window.popup_window_menu(titlebar_rect().bottom_left().translated(rect().location()), WindowMenuDefaultAction::Close); + return true; + } else if (event.type() == Event::MouseUp && event.button() == MouseButton::Left) { + // Since the MouseDown event opened a menu, another MouseUp + // from the second click outside the menu wouldn't be considered + // a double click, so let's manually check if it would otherwise + // have been be considered to be one + if (wm.is_menu_doubleclick(m_window, event)) { + // It is a double click, so perform activate the default item + m_window.window_menu_activate_default(); + } + return true; + } + return false; +} +void WindowFrame::handle_titlebar_mouse_event(MouseEvent const& event) +{ auto& wm = WindowManager::the(); + wm.clear_resize_candidate(); + + if (titlebar_icon_rect().contains(event.position())) { + if (handle_titlebar_icon_mouse_event(event)) + return; + } + + for (auto& button : m_buttons) { + if (button.relative_rect().contains(event.position())) + return button.on_mouse_event(event.translated(-button.relative_rect().location())); + } + + if (event.type() == Event::MouseDown) { + if ((m_window.type() == WindowType::Normal || m_window.type() == WindowType::ToolWindow) && event.button() == MouseButton::Right) { + auto default_action = m_window.is_maximized() ? WindowMenuDefaultAction::Restore : WindowMenuDefaultAction::Maximize; + m_window.popup_window_menu(event.position().translated(rect().location()), default_action); + return; + } + if (m_window.is_movable() && event.button() == MouseButton::Left) + wm.start_window_move(m_window, event.translated(rect().location())); + } +} + +void WindowFrame::handle_mouse_event(MouseEvent const& event) +{ + VERIFY(!m_window.is_fullscreen()); + if (m_window.type() != WindowType::Normal && m_window.type() != WindowType::ToolWindow && m_window.type() != WindowType::Notification) return; + auto& wm = WindowManager::the(); if (m_window.type() == WindowType::Normal || m_window.type() == WindowType::ToolWindow) { if (event.type() == Event::MouseDown) wm.move_to_front_and_make_active(m_window); - - if (m_window.blocking_modal_window()) - return; - - if (titlebar_icon_rect().contains(event.position())) { - if (event.type() == Event::MouseDown && (event.button() == MouseButton::Left || event.button() == MouseButton::Right)) { - // Manually start a potential double click. Since we're opening - // a menu, we will only receive the MouseDown event, so we - // need to record that fact. If the user subsequently clicks - // on the same area, the menu will get closed, and we will - // receive a MouseUp event, but because windows have changed - // we don't get a MouseDoubleClick event. We can however record - // this click, and when we receive the MouseUp event check if - // it would have been considered a double click, if it weren't - // for the fact that we opened and closed a window in the meanwhile - wm.start_menu_doubleclick(m_window, event); - - m_window.popup_window_menu(titlebar_rect().bottom_left().translated(rect().location()), WindowMenuDefaultAction::Close); - return; - } else if (event.type() == Event::MouseUp && event.button() == MouseButton::Left) { - // Since the MouseDown event opened a menu, another MouseUp - // from the second click outside the menu wouldn't be considered - // a double click, so let's manually check if it would otherwise - // have been be considered to be one - if (wm.is_menu_doubleclick(m_window, event)) { - // It is a double click, so perform activate the default item - m_window.window_menu_activate_default(); - } - return; - } - } } + if (m_window.blocking_modal_window()) + return; + // This is slightly hackish, but expand the title bar rect by two pixels downwards, // so that mouse events between the title bar and window contents don't act like // mouse events on the border. @@ -698,24 +728,7 @@ void WindowFrame::on_mouse_event(const MouseEvent& event) adjusted_titlebar_rect.set_height(adjusted_titlebar_rect.height() + 2); if (adjusted_titlebar_rect.contains(event.position())) { - wm.clear_resize_candidate(); - - if (event.type() == Event::MouseDown) - wm.move_to_front_and_make_active(m_window); - - for (auto& button : m_buttons) { - if (button.relative_rect().contains(event.position())) - return button.on_mouse_event(event.translated(-button.relative_rect().location())); - } - if (event.type() == Event::MouseDown) { - if ((m_window.type() == WindowType::Normal || m_window.type() == WindowType::ToolWindow) && event.button() == MouseButton::Right) { - auto default_action = m_window.is_maximized() ? WindowMenuDefaultAction::Restore : WindowMenuDefaultAction::Maximize; - m_window.popup_window_menu(event.position().translated(rect().location()), default_action); - return; - } - if (m_window.is_movable() && event.button() == MouseButton::Left) - wm.start_window_move(m_window, event.translated(rect().location())); - } + handle_titlebar_mouse_event(event); return; } @@ -726,7 +739,17 @@ void WindowFrame::on_mouse_event(const MouseEvent& event) return; } - if (m_window.is_resizable() && event.type() == Event::MouseMove && event.buttons() == 0) { + handle_border_mouse_event(event); +} + +void WindowFrame::handle_border_mouse_event(const MouseEvent& event) +{ + if (!m_window.is_resizable()) + return; + + auto& wm = WindowManager::the(); + + if (event.type() == Event::MouseMove && event.buttons() == 0) { constexpr ResizeDirection direction_for_hot_area[3][3] = { { ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight }, { ResizeDirection::Left, ResizeDirection::None, ResizeDirection::Right }, @@ -743,7 +766,7 @@ void WindowFrame::on_mouse_event(const MouseEvent& event) return; } - if (m_window.is_resizable() && event.type() == Event::MouseDown && event.button() == MouseButton::Left) + if (event.type() == Event::MouseDown && event.button() == MouseButton::Left) wm.start_window_resize(m_window, event.translated(rect().location())); } diff --git a/Userland/Services/WindowServer/WindowFrame.h b/Userland/Services/WindowServer/WindowFrame.h index d32b54f0df..dba13751c2 100644 --- a/Userland/Services/WindowServer/WindowFrame.h +++ b/Userland/Services/WindowServer/WindowFrame.h @@ -35,7 +35,12 @@ public: void paint(Gfx::Painter&, const Gfx::IntRect&); void render(Gfx::Painter&); void render_to_cache(); - void on_mouse_event(const MouseEvent&); + + void handle_mouse_event(MouseEvent const&); + void handle_titlebar_mouse_event(MouseEvent const&); + bool handle_titlebar_icon_mouse_event(MouseEvent const&); + void handle_border_mouse_event(MouseEvent const&); + void notify_window_rect_changed(const Gfx::IntRect& old_rect, const Gfx::IntRect& new_rect); void invalidate_titlebar(); void invalidate(Gfx::IntRect relative_rect); diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index f8f6aebc8f..70bc4fcbe4 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -1024,7 +1024,7 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind if (window.frame().hit_test(event.position()).has_value()) { // We are hitting the frame, pass the event along to WindowFrame. - window.frame().on_mouse_event(event.translated(-window.frame().rect().location())); + 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 @@ -1106,7 +1106,7 @@ void WindowManager::reevaluate_hovered_window(Window* updated_window) hovered_window->dispatch_event(event); } else if (!hovered_window->is_frameless()) { MouseEvent event(Event::MouseMove, cursor_location.translated(-hovered_window->frame().rect().location()), 0, MouseButton::None, 0); - hovered_window->frame().on_mouse_event(event); + hovered_window->frame().handle_mouse_event(event); } } } |