1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:17:44 +00:00

WindowServer: Split up WindowFrame::handle_mouse_event()

Break this function into a couple of smaller functions, one for each
of these areas:

- The titlebar
- The titlebar icon
- The menubar
- The border
This commit is contained in:
Andreas Kling 2021-06-18 01:39:18 +02:00
parent f88361fc28
commit ad828b3cfc
3 changed files with 84 additions and 56 deletions

View file

@ -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)
{
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());
auto& wm = WindowManager::the();
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()));
}