WindowServer: Double click a window's frame to latch to screen's edge

This commit is contained in:
Jelle Raaijmakers 2023-01-19 00:32:23 +01:00 committed by Sam Atkins
parent 3e70d41c57
commit 83488cd102
Notes: sideshowbarker 2024-07-17 01:20:14 +09:00
3 changed files with 52 additions and 1 deletions

View File

@ -10,6 +10,7 @@
#include <LibGfx/Painter.h>
#include <LibGfx/StylePainter.h>
#include <LibGfx/WindowTheme.h>
#include <Services/Taskbar/TaskbarWindow.h>
#include <WindowServer/Button.h>
#include <WindowServer/Compositor.h>
#include <WindowServer/Event.h>
@ -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);
}
}

View File

@ -6,13 +6,14 @@
#pragma once
#include "HitTestResult.h"
#include <AK/Forward.h>
#include <AK/NonnullOwnPtrVector.h>
#include <AK/RefPtr.h>
#include <LibCore/Forward.h>
#include <LibGfx/Forward.h>
#include <LibGfx/WindowTheme.h>
#include <WindowServer/HitTestResult.h>
#include <WindowServer/ResizeDirection.h>
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&);

View File

@ -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);