diff options
-rw-r--r-- | Userland/Libraries/LibGUI/ResizeCorner.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/ResizeDirection.h | 15 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/Window.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/Window.h | 3 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Compositor.cpp | 3 | ||||
-rw-r--r-- | Userland/Services/WindowServer/ConnectionFromClient.cpp | 8 | ||||
-rw-r--r-- | Userland/Services/WindowServer/ConnectionFromClient.h | 2 | ||||
-rw-r--r-- | Userland/Services/WindowServer/ResizeDirection.h | 24 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WMConnectionFromClient.cpp | 4 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WMConnectionFromClient.h | 2 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.cpp | 31 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.cpp | 50 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.h | 17 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManagerServer.ipc | 2 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowServer.ipc | 2 |
15 files changed, 107 insertions, 62 deletions
diff --git a/Userland/Libraries/LibGUI/ResizeCorner.cpp b/Userland/Libraries/LibGUI/ResizeCorner.cpp index 2b37546363..8818a1a4ad 100644 --- a/Userland/Libraries/LibGUI/ResizeCorner.cpp +++ b/Userland/Libraries/LibGUI/ResizeCorner.cpp @@ -76,7 +76,7 @@ void ResizeCorner::paint_event(PaintEvent& event) void ResizeCorner::mousedown_event(MouseEvent& event) { if (event.button() == MouseButton::Primary) - window()->start_interactive_resize(); + window()->start_interactive_resize(ResizeDirection::DownRight); Widget::mousedown_event(event); } diff --git a/Userland/Libraries/LibGUI/ResizeDirection.h b/Userland/Libraries/LibGUI/ResizeDirection.h new file mode 100644 index 0000000000..fdf8d6a0b2 --- /dev/null +++ b/Userland/Libraries/LibGUI/ResizeDirection.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, Mart G <martg_@hotmail.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <Services/WindowServer/ResizeDirection.h> + +namespace GUI { + +using ResizeDirection = WindowServer::ResizeDirection; + +} diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index 99097112e5..a7f642b1ba 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -938,9 +938,9 @@ void Window::apply_icon() ConnectionToWindowServer::the().async_set_window_icon_bitmap(m_window_id, m_icon->to_shareable_bitmap()); } -void Window::start_interactive_resize() +void Window::start_interactive_resize(ResizeDirection resize_direction) { - ConnectionToWindowServer::the().async_start_window_resize(m_window_id); + ConnectionToWindowServer::the().async_start_window_resize(m_window_id, (i32)resize_direction); } Vector<Widget&> Window::focusable_widgets(FocusSource source) const diff --git a/Userland/Libraries/LibGUI/Window.h b/Userland/Libraries/LibGUI/Window.h index fddab1f195..4a45d3d299 100644 --- a/Userland/Libraries/LibGUI/Window.h +++ b/Userland/Libraries/LibGUI/Window.h @@ -14,6 +14,7 @@ #include <LibCore/Object.h> #include <LibGUI/FocusSource.h> #include <LibGUI/Forward.h> +#include <LibGUI/ResizeDirection.h> #include <LibGUI/WindowMode.h> #include <LibGUI/WindowType.h> #include <LibGfx/Forward.h> @@ -131,7 +132,7 @@ public: virtual void close(); void move_to_front(); - void start_interactive_resize(); + void start_interactive_resize(ResizeDirection resize_direction); Widget* main_widget() { return m_main_widget; } Widget const* main_widget() const { return m_main_widget; } diff --git a/Userland/Services/WindowServer/Compositor.cpp b/Userland/Services/WindowServer/Compositor.cpp index 848cae499e..0baa88a656 100644 --- a/Userland/Services/WindowServer/Compositor.cpp +++ b/Userland/Services/WindowServer/Compositor.cpp @@ -426,6 +426,9 @@ void Compositor::compose() backing_rect.set_right_without_resize(window_rect.right()); backing_rect.set_top(window_rect.top()); break; + default: + VERIFY_NOT_REACHED(); + break; } Gfx::IntRect dirty_rect_in_backing_coordinates = rect.intersected(window_rect) diff --git a/Userland/Services/WindowServer/ConnectionFromClient.cpp b/Userland/Services/WindowServer/ConnectionFromClient.cpp index 3b2706909f..ec43090927 100644 --- a/Userland/Services/WindowServer/ConnectionFromClient.cpp +++ b/Userland/Services/WindowServer/ConnectionFromClient.cpp @@ -800,13 +800,17 @@ void ConnectionFromClient::set_window_alpha_hit_threshold(i32 window_id, float t it->value->set_alpha_hit_threshold(threshold); } -void ConnectionFromClient::start_window_resize(i32 window_id) +void ConnectionFromClient::start_window_resize(i32 window_id, i32 resize_direction) { auto it = m_windows.find(window_id); if (it == m_windows.end()) { did_misbehave("WM_StartWindowResize: Bad window ID"); return; } + if (resize_direction < 0 || resize_direction >= (i32)ResizeDirection::__Count) { + did_misbehave("WM_StartWindowResize: Bad resize direction"); + return; + } auto& window = *(*it).value; if (!window.is_resizable()) { dbgln("Client wants to start resizing a non-resizable window"); @@ -814,7 +818,7 @@ void ConnectionFromClient::start_window_resize(i32 window_id) } // FIXME: We are cheating a bit here by using the current cursor location and hard-coding the left button. // Maybe the client should be allowed to specify what initiated this request? - WindowManager::the().start_window_resize(window, ScreenInput::the().cursor_location(), MouseButton::Primary); + WindowManager::the().start_window_resize(window, ScreenInput::the().cursor_location(), MouseButton::Primary, (ResizeDirection)resize_direction); } Messages::WindowServer::StartDragResponse ConnectionFromClient::start_drag(String const& text, HashMap<String, ByteBuffer> const& mime_data, Gfx::ShareableBitmap const& drag_bitmap) diff --git a/Userland/Services/WindowServer/ConnectionFromClient.h b/Userland/Services/WindowServer/ConnectionFromClient.h index 085f23f975..7f431dbbd1 100644 --- a/Userland/Services/WindowServer/ConnectionFromClient.h +++ b/Userland/Services/WindowServer/ConnectionFromClient.h @@ -109,7 +109,7 @@ private: virtual Messages::WindowServer::GetWindowTitleResponse get_window_title(i32) override; virtual Messages::WindowServer::IsMaximizedResponse is_maximized(i32) override; virtual void set_maximized(i32, bool) override; - virtual void start_window_resize(i32) override; + virtual void start_window_resize(i32, i32) override; virtual Messages::WindowServer::SetWindowRectResponse set_window_rect(i32, Gfx::IntRect const&) override; virtual Messages::WindowServer::GetWindowRectResponse get_window_rect(i32) override; virtual void set_window_minimum_size(i32, Gfx::IntSize const&) override; diff --git a/Userland/Services/WindowServer/ResizeDirection.h b/Userland/Services/WindowServer/ResizeDirection.h new file mode 100644 index 0000000000..f900fe3079 --- /dev/null +++ b/Userland/Services/WindowServer/ResizeDirection.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022, Mart G <martg_@hotmail.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace WindowServer { + +enum class ResizeDirection { + None, + Left, + UpLeft, + Up, + UpRight, + Right, + DownRight, + Down, + DownLeft, + __Count +}; + +} diff --git a/Userland/Services/WindowServer/WMConnectionFromClient.cpp b/Userland/Services/WindowServer/WMConnectionFromClient.cpp index f74cf6b037..d80fa70ba6 100644 --- a/Userland/Services/WindowServer/WMConnectionFromClient.cpp +++ b/Userland/Services/WindowServer/WMConnectionFromClient.cpp @@ -86,7 +86,7 @@ void WMConnectionFromClient::popup_window_menu(i32 client_id, i32 window_id, Gfx } } -void WMConnectionFromClient::start_window_resize(i32 client_id, i32 window_id) +void WMConnectionFromClient::start_window_resize(i32 client_id, i32 window_id, i32 resize_direction) { auto* client = WindowServer::ConnectionFromClient::from_client_id(client_id); if (!client) { @@ -101,7 +101,7 @@ void WMConnectionFromClient::start_window_resize(i32 client_id, i32 window_id) auto& window = *(*it).value; // FIXME: We are cheating a bit here by using the current cursor location and hard-coding the left button. // Maybe the client should be allowed to specify what initiated this request? - WindowManager::the().start_window_resize(window, ScreenInput::the().cursor_location(), MouseButton::Primary); + WindowManager::the().start_window_resize(window, ScreenInput::the().cursor_location(), MouseButton::Primary, (ResizeDirection)resize_direction); } void WMConnectionFromClient::set_window_minimized(i32 client_id, i32 window_id, bool minimized) diff --git a/Userland/Services/WindowServer/WMConnectionFromClient.h b/Userland/Services/WindowServer/WMConnectionFromClient.h index ba93603fad..b3bb43dff9 100644 --- a/Userland/Services/WindowServer/WMConnectionFromClient.h +++ b/Userland/Services/WindowServer/WMConnectionFromClient.h @@ -24,7 +24,7 @@ public: virtual void set_active_window(i32, i32) override; virtual void set_window_minimized(i32, i32, bool) override; virtual void toggle_show_desktop() override; - virtual void start_window_resize(i32, i32) override; + virtual void start_window_resize(i32, i32, i32) override; virtual void popup_window_menu(i32, i32, Gfx::IntPoint const&) override; virtual void set_window_taskbar_rect(i32, i32, Gfx::IntRect const&) override; virtual void set_applet_area_position(Gfx::IntPoint const&) override; diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index 9c3953f406..241340e767 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -845,25 +845,30 @@ void WindowFrame::handle_border_mouse_event(MouseEvent const& event) auto& wm = WindowManager::the(); + constexpr ResizeDirection direction_for_hot_area[3][3] = { + { ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight }, + { ResizeDirection::Left, ResizeDirection::None, ResizeDirection::Right }, + { ResizeDirection::DownLeft, ResizeDirection::Down, ResizeDirection::DownRight }, + }; + Gfx::IntRect outer_rect = { {}, rect().size() }; + VERIFY(outer_rect.contains(event.position())); + int window_relative_x = event.x() - outer_rect.x(); + int window_relative_y = event.y() - outer_rect.y(); + int corner_size = titlebar_rect().height(); + int hot_area_row = (window_relative_y < corner_size) ? 0 : (window_relative_y > outer_rect.height() - corner_size) ? 2 + : 1; + int hot_area_column = (window_relative_x < corner_size) ? 0 : (window_relative_x > outer_rect.width() - corner_size) ? 2 + : 1; + ResizeDirection resize_direction = direction_for_hot_area[hot_area_row][hot_area_column]; + 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 }, - { ResizeDirection::DownLeft, ResizeDirection::Down, ResizeDirection::DownRight }, - }; - Gfx::IntRect outer_rect = { {}, rect().size() }; - VERIFY(outer_rect.contains(event.position())); - int window_relative_x = event.x() - outer_rect.x(); - int window_relative_y = event.y() - outer_rect.y(); - int hot_area_row = min(2, window_relative_y / (outer_rect.height() / 3)); - int hot_area_column = min(2, window_relative_x / (outer_rect.width() / 3)); - wm.set_resize_candidate(m_window, direction_for_hot_area[hot_area_row][hot_area_column]); + wm.set_resize_candidate(m_window, resize_direction); Compositor::the().invalidate_cursor(); return; } if (event.type() == Event::MouseDown && event.button() == MouseButton::Primary) - wm.start_window_resize(m_window, event.translated(rect().location())); + wm.start_window_resize(m_window, event.translated(rect().location()), resize_direction); } void WindowFrame::handle_menubar_mouse_event(MouseEvent const& event) diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index e89aa6dca6..576194d0a5 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -699,26 +699,12 @@ void WindowManager::start_window_move(Window& window, MouseEvent const& event) start_window_move(window, event.position()); } -void WindowManager::start_window_resize(Window& window, Gfx::IntPoint const& position, MouseButton button) +void WindowManager::start_window_resize(Window& window, Gfx::IntPoint const& position, MouseButton button, ResizeDirection resize_direction) { MenuManager::the().close_everyone(); move_to_front_and_make_active(window); - constexpr ResizeDirection direction_for_hot_area[3][3] = { - { ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight }, - { ResizeDirection::Left, ResizeDirection::None, ResizeDirection::Right }, - { ResizeDirection::DownLeft, ResizeDirection::Down, ResizeDirection::DownRight }, - }; - Gfx::IntRect outer_rect = window.frame().rect(); - if (!outer_rect.contains(position)) { - // FIXME: This used to be an VERIFY but crashing WindowServer over this seems silly. - dbgln("FIXME: !outer_rect.contains(position): outer_rect={}, position={}", outer_rect, position); - } - int window_relative_x = position.x() - outer_rect.x(); - int window_relative_y = position.y() - outer_rect.y(); - int hot_area_row = min(2, window_relative_y / (outer_rect.height() / 3)); - int hot_area_column = min(2, window_relative_x / (outer_rect.width() / 3)); - m_resize_direction = direction_for_hot_area[hot_area_row][hot_area_column]; + m_resize_direction = resize_direction; if (m_resize_direction == ResizeDirection::None) { VERIFY(!m_resize_window); return; @@ -738,15 +724,11 @@ void WindowManager::start_window_resize(Window& window, Gfx::IntPoint const& pos set_automatic_cursor_tracking_window(nullptr); window.invalidate(true, true); - - if (hot_area_row == 0 || hot_area_column == 0) { - m_resize_window->set_default_positioned(false); - } } -void WindowManager::start_window_resize(Window& window, MouseEvent const& event) +void WindowManager::start_window_resize(Window& window, MouseEvent const& event, ResizeDirection resize_direction) { - start_window_resize(window, event.position(), event.button()); + start_window_resize(window, event.position(), event.button(), resize_direction); } bool WindowManager::process_ongoing_window_move(MouseEvent& event) @@ -1005,6 +987,10 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event) } dbgln_if(RESIZE_DEBUG, "[WM] Resizing, original: {}, now: {}", m_resize_window_original_rect, new_rect); + if (m_resize_window->rect().location() != m_resize_window_original_rect.location()) { + m_resize_window->set_default_positioned(false); + } + m_resize_window->set_rect(new_rect); if (system_effects().geometry() == ShowGeometry::OnMoveAndResize || system_effects().geometry() == ShowGeometry::OnResizeOnly) { m_geometry_overlay->window_rect_changed(); @@ -1240,7 +1226,22 @@ void WindowManager::process_mouse_event_for_window(HitTestResult& result, MouseE return; } if (window.is_resizable() && m_keyboard_modifiers == Mod_Super && event.type() == Event::MouseDown && event.button() == MouseButton::Secondary && !window.blocking_modal_window()) { - start_window_resize(window, event); + constexpr ResizeDirection direction_for_hot_area[3][3] = { + { ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight }, + { ResizeDirection::Left, ResizeDirection::None, ResizeDirection::Right }, + { ResizeDirection::DownLeft, ResizeDirection::Down, ResizeDirection::DownRight }, + }; + Gfx::IntRect outer_rect = window.frame().rect(); + if (!outer_rect.contains(event.position())) { + // FIXME: This used to be an VERIFY but crashing WindowServer over this seems silly. + dbgln("FIXME: !outer_rect.contains(position): outer_rect={}, position={}", outer_rect, event.position()); + } + int window_relative_x = event.position().x() - outer_rect.x(); + int window_relative_y = event.position().y() - outer_rect.y(); + int hot_area_row = min(2, window_relative_y / (outer_rect.height() / 3)); + int hot_area_column = min(2, window_relative_x / (outer_rect.width() / 3)); + ResizeDirection resize_direction = direction_for_hot_area[hot_area_row][hot_area_column]; + start_window_resize(window, event, resize_direction); return; } } @@ -1949,6 +1950,9 @@ Cursor const& WindowManager::active_cursor() const return *m_resize_diagonally_bltr_cursor; case ResizeDirection::None: break; + default: + VERIFY_NOT_REACHED(); + break; } } diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index 632520cf6d..d8ed8fd620 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -21,6 +21,7 @@ #include <WindowServer/Event.h> #include <WindowServer/KeymapSwitcher.h> #include <WindowServer/MenuManager.h> +#include <WindowServer/ResizeDirection.h> #include <WindowServer/ScreenLayout.h> #include <WindowServer/SystemEffects.h> #include <WindowServer/WMConnectionFromClient.h> @@ -41,18 +42,6 @@ class Button; class DndOverlay; class WindowGeometryOverlay; -enum class ResizeDirection { - None, - Left, - UpLeft, - Up, - UpRight, - Right, - DownRight, - Down, - DownLeft -}; - class WindowManager : public Core::Object { C_OBJECT(WindowManager) @@ -202,8 +191,8 @@ public: void check_hide_geometry_overlay(Window&); - void start_window_resize(Window&, Gfx::IntPoint const&, MouseButton); - void start_window_resize(Window&, MouseEvent const&); + void start_window_resize(Window&, Gfx::IntPoint const&, MouseButton, ResizeDirection); + void start_window_resize(Window&, MouseEvent const&, ResizeDirection); void start_window_move(Window&, MouseEvent const&); void start_window_move(Window&, Gfx::IntPoint const&); diff --git a/Userland/Services/WindowServer/WindowManagerServer.ipc b/Userland/Services/WindowServer/WindowManagerServer.ipc index cb7e215e75..8e35e1fa1c 100644 --- a/Userland/Services/WindowServer/WindowManagerServer.ipc +++ b/Userland/Services/WindowServer/WindowManagerServer.ipc @@ -8,7 +8,7 @@ endpoint WindowManagerServer set_active_window(i32 client_id, i32 window_id) =| set_window_minimized(i32 client_id, i32 window_id, bool minimized) =| toggle_show_desktop() =| - start_window_resize(i32 client_id, i32 window_id) =| + start_window_resize(i32 client_id, i32 window_id, i32 resize_direction) =| popup_window_menu(i32 client_id, i32 window_id, Gfx::IntPoint screen_position) =| set_window_taskbar_rect(i32 client_id, i32 window_id, Gfx::IntRect rect) =| set_applet_area_position(Gfx::IntPoint position) =| diff --git a/Userland/Services/WindowServer/WindowServer.ipc b/Userland/Services/WindowServer/WindowServer.ipc index b4aa09c431..867586b897 100644 --- a/Userland/Services/WindowServer/WindowServer.ipc +++ b/Userland/Services/WindowServer/WindowServer.ipc @@ -80,7 +80,7 @@ endpoint WindowServer get_applet_rect_on_screen(i32 window_id) => (Gfx::IntRect rect) - start_window_resize(i32 window_id) =| + start_window_resize(i32 window_id, i32 resize_direction) =| is_maximized(i32 window_id) => (bool maximized) set_maximized(i32 window_id, bool maximized) =| |