diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index 74777c1d58..42948d3299 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -868,6 +869,12 @@ void WindowFrame::handle_border_mouse_event(MouseEvent const& event) : 1; ResizeDirection resize_direction = direction_for_hot_area[hot_area_row][hot_area_column]; + // Double click latches a window's edge to the screen's edge + if (event.type() == Event::MouseDoubleClick) { + latch_window_to_screen_edge(resize_direction); + return; + } + if (event.type() == Event::MouseMove && event.buttons() == 0) { wm.set_resize_candidate(m_window, resize_direction); Compositor::the().invalidate_cursor(); @@ -966,4 +973,37 @@ int WindowFrame::menu_row_count() const return m_window.menubar().has_menus() ? 1 : 0; } +void WindowFrame::latch_window_to_screen_edge(ResizeDirection resize_direction) +{ + auto window_rect = m_window.rect(); + auto frame_rect = rect(); + auto& screen = Screen::closest_to_rect(window_rect); + auto screen_rect = screen.rect(); + + if (screen.is_main_screen()) + screen_rect.shrink(0, 0, TaskbarWindow::taskbar_height(), 0); + + if (resize_direction == ResizeDirection::UpLeft + || resize_direction == ResizeDirection::Up + || resize_direction == ResizeDirection::UpRight) + window_rect.inflate(frame_rect.top() - screen_rect.top(), 0, 0, 0); + + if (resize_direction == ResizeDirection::UpRight + || resize_direction == ResizeDirection::Right + || resize_direction == ResizeDirection::DownRight) + window_rect.inflate(0, screen_rect.right() - frame_rect.right(), 0, 0); + + if (resize_direction == ResizeDirection::DownLeft + || resize_direction == ResizeDirection::Down + || resize_direction == ResizeDirection::DownRight) + window_rect.inflate(0, 0, screen_rect.bottom() - frame_rect.bottom(), 0); + + if (resize_direction == ResizeDirection::UpLeft + || resize_direction == ResizeDirection::Left + || resize_direction == ResizeDirection::DownLeft) + window_rect.inflate(0, 0, 0, frame_rect.left() - screen_rect.left()); + + m_window.set_rect(window_rect); +} + } diff --git a/Userland/Services/WindowServer/WindowFrame.h b/Userland/Services/WindowServer/WindowFrame.h index 3aee699f23..1f5cd91835 100644 --- a/Userland/Services/WindowServer/WindowFrame.h +++ b/Userland/Services/WindowServer/WindowFrame.h @@ -6,13 +6,14 @@ #pragma once -#include "HitTestResult.h" #include #include #include #include #include #include +#include +#include namespace WindowServer { @@ -125,6 +126,7 @@ private: void paint_menubar(Gfx::Painter&); MultiScaleBitmaps const* shadow_bitmap() const; Gfx::IntRect inflated_for_shadow(Gfx::IntRect const&) const; + void latch_window_to_screen_edge(ResizeDirection); void handle_menubar_mouse_event(MouseEvent const&); void handle_menu_mouse_event(Menu&, MouseEvent const&); diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 9783b2a799..9741d815b5 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -860,6 +860,15 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event) if (!m_resize_window) return false; + // Deliver MouseDoubleClick events to the frame + if (event.type() == Event::MouseUp) { + auto& frame = m_resize_window->frame(); + auto frame_event = event.translated(-frame.rect().location()); + process_event_for_doubleclick(*m_resize_window, frame_event); + if (frame_event.type() == Event::MouseDoubleClick) + frame.handle_mouse_event(frame_event); + } + if (event.type() == Event::MouseUp && event.button() == m_resizing_mouse_button) { dbgln_if(RESIZE_DEBUG, "[WM] Finish resizing Window({})", m_resize_window);