summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Services/WindowServer/WindowFrame.cpp129
-rw-r--r--Userland/Services/WindowServer/WindowFrame.h7
-rw-r--r--Userland/Services/WindowServer/WindowManager.cpp4
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);
}
}
}