mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 09:57:34 +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:
parent
f88361fc28
commit
ad828b3cfc
3 changed files with 84 additions and 56 deletions
|
@ -647,50 +647,80 @@ Optional<HitTestResult> WindowFrame::hit_test(Gfx::IntPoint const& position) con
|
||||||
return {};
|
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());
|
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)
|
if (m_window.type() != WindowType::Normal && m_window.type() != WindowType::ToolWindow && m_window.type() != WindowType::Notification)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto& wm = WindowManager::the();
|
||||||
if (m_window.type() == WindowType::Normal || m_window.type() == WindowType::ToolWindow) {
|
if (m_window.type() == WindowType::Normal || m_window.type() == WindowType::ToolWindow) {
|
||||||
if (event.type() == Event::MouseDown)
|
if (event.type() == Event::MouseDown)
|
||||||
wm.move_to_front_and_make_active(m_window);
|
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,
|
// 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
|
// so that mouse events between the title bar and window contents don't act like
|
||||||
// mouse events on the border.
|
// 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);
|
adjusted_titlebar_rect.set_height(adjusted_titlebar_rect.height() + 2);
|
||||||
|
|
||||||
if (adjusted_titlebar_rect.contains(event.position())) {
|
if (adjusted_titlebar_rect.contains(event.position())) {
|
||||||
wm.clear_resize_candidate();
|
handle_titlebar_mouse_event(event);
|
||||||
|
|
||||||
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()));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,7 +739,17 @@ void WindowFrame::on_mouse_event(const MouseEvent& event)
|
||||||
return;
|
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] = {
|
constexpr ResizeDirection direction_for_hot_area[3][3] = {
|
||||||
{ ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight },
|
{ ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight },
|
||||||
{ ResizeDirection::Left, ResizeDirection::None, ResizeDirection::Right },
|
{ ResizeDirection::Left, ResizeDirection::None, ResizeDirection::Right },
|
||||||
|
@ -743,7 +766,7 @@ void WindowFrame::on_mouse_event(const MouseEvent& event)
|
||||||
return;
|
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()));
|
wm.start_window_resize(m_window, event.translated(rect().location()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,12 @@ public:
|
||||||
void paint(Gfx::Painter&, const Gfx::IntRect&);
|
void paint(Gfx::Painter&, const Gfx::IntRect&);
|
||||||
void render(Gfx::Painter&);
|
void render(Gfx::Painter&);
|
||||||
void render_to_cache();
|
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 notify_window_rect_changed(const Gfx::IntRect& old_rect, const Gfx::IntRect& new_rect);
|
||||||
void invalidate_titlebar();
|
void invalidate_titlebar();
|
||||||
void invalidate(Gfx::IntRect relative_rect);
|
void invalidate(Gfx::IntRect relative_rect);
|
||||||
|
|
|
@ -1024,7 +1024,7 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind
|
||||||
|
|
||||||
if (window.frame().hit_test(event.position()).has_value()) {
|
if (window.frame().hit_test(event.position()).has_value()) {
|
||||||
// We are hitting the frame, pass the event along to WindowFrame.
|
// 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;
|
event_window_with_frame = &window;
|
||||||
} else if (window.hit_test(event.position(), false).has_value()) {
|
} else if (window.hit_test(event.position(), false).has_value()) {
|
||||||
// We are hitting the window content
|
// We are hitting the window content
|
||||||
|
@ -1106,7 +1106,7 @@ void WindowManager::reevaluate_hovered_window(Window* updated_window)
|
||||||
hovered_window->dispatch_event(event);
|
hovered_window->dispatch_event(event);
|
||||||
} else if (!hovered_window->is_frameless()) {
|
} else if (!hovered_window->is_frameless()) {
|
||||||
MouseEvent event(Event::MouseMove, cursor_location.translated(-hovered_window->frame().rect().location()), 0, MouseButton::None, 0);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue