From 555b4236f8a8f305c70ba2cf710f9d319c4046fc Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Fri, 22 Nov 2019 19:06:25 +0300 Subject: [PATCH] WindowServer: Ensure resized windows move in the expected direction When a window is being interactively resized, there are several rules beyond the actual mouse movement that can impact the new size of the window, such as its size increments and minimum size limit. Move the placement logic after applying all the sizing logic, so that whatever final size the window ends up with, the sides of the window that do move are the ones that the user is dragging. https://github.com/SerenityOS/serenity/issues/52 --- Servers/WindowServer/WSWindowManager.cpp | 37 +++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index f8e4b25b42..1f1a196ae6 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -542,8 +542,6 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W int diff_x = event.x() - m_resize_origin.x(); int diff_y = event.y() - m_resize_origin.y(); - int change_x = 0; - int change_y = 0; int change_w = 0; int change_h = 0; @@ -557,25 +555,19 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W break; case ResizeDirection::UpRight: change_w = diff_x; - change_y = diff_y; change_h = -diff_y; break; case ResizeDirection::Up: - change_y = diff_y; change_h = -diff_y; break; case ResizeDirection::UpLeft: - change_x = diff_x; change_w = -diff_x; - change_y = diff_y; change_h = -diff_y; break; case ResizeDirection::Left: - change_x = diff_x; change_w = -diff_x; break; case ResizeDirection::DownLeft: - change_x = diff_x; change_w = -diff_x; change_h = diff_y; break; @@ -587,10 +579,10 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W } auto new_rect = m_resize_window_original_rect; + + // First, size the new rect. Size minimum_size { 50, 50 }; - new_rect.set_x(new_rect.x() + change_x); - new_rect.set_y(new_rect.y() + change_y); new_rect.set_width(max(minimum_size.width(), new_rect.width() + change_w)); new_rect.set_height(max(minimum_size.height(), new_rect.height() + change_h)); @@ -601,6 +593,31 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W new_rect.set_height(m_resize_window->base_size().height() + vertical_incs * m_resize_window->size_increment().height()); } + // Second, set its position so that the sides of the window + // that end up moving are the same ones as the user is dragging, + // no matter which part of the logic above caused us to decide + // to resize by this much. + switch (m_resize_direction) { + case ResizeDirection::DownRight: + case ResizeDirection::Right: + case ResizeDirection::Down: + break; + case ResizeDirection::Left: + case ResizeDirection::Up: + case ResizeDirection::UpLeft: + new_rect.set_right_without_resize(m_resize_window_original_rect.right()); + new_rect.set_bottom_without_resize(m_resize_window_original_rect.bottom()); + break; + case ResizeDirection::UpRight: + new_rect.set_bottom_without_resize(m_resize_window_original_rect.bottom()); + break; + case ResizeDirection::DownLeft: + new_rect.set_right_without_resize(m_resize_window_original_rect.right()); + break; + default: + ASSERT_NOT_REACHED(); + } + if (new_rect.contains(event.position())) hovered_window = m_resize_window;