diff options
author | Peter Elliott <pelliott@ualberta.ca> | 2020-08-21 14:19:10 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-23 01:05:22 +0200 |
commit | 45ed58865ed7ae26a61f8710dc2bba4a667221a3 (patch) | |
tree | 38f94e2c99995aece462cb91b6e217e78923ec54 | |
parent | c68537271ca4430baa27f677511637e8648502c1 (diff) | |
download | serenity-45ed58865ed7ae26a61f8710dc2bba4a667221a3.zip |
LibGUI+WindowServer: Add resize_aspect_ratio()
When a resize_aspect_ratio is specified, and window will only be resized
to a multiple of that ratio. When resize_aspect_ratio is set, windows
cannot be tiled.
-rw-r--r-- | Libraries/LibGUI/Window.cpp | 11 | ||||
-rw-r--r-- | Libraries/LibGUI/Window.h | 5 | ||||
-rw-r--r-- | Services/WindowServer/ClientConnection.cpp | 15 | ||||
-rw-r--r-- | Services/WindowServer/ClientConnection.h | 1 | ||||
-rw-r--r-- | Services/WindowServer/Window.cpp | 5 | ||||
-rw-r--r-- | Services/WindowServer/Window.h | 4 | ||||
-rw-r--r-- | Services/WindowServer/WindowManager.cpp | 9 | ||||
-rw-r--r-- | Services/WindowServer/WindowServer.ipc | 2 |
8 files changed, 51 insertions, 1 deletions
diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp index de1206b918..72a6885b54 100644 --- a/Libraries/LibGUI/Window.cpp +++ b/Libraries/LibGUI/Window.cpp @@ -107,6 +107,7 @@ void Window::show() m_opacity_when_windowless, m_base_size, m_size_increment, + m_resize_aspect_ratio, (i32)m_window_type, m_title_when_windowless, parent_window ? parent_window->window_id() : 0); @@ -837,6 +838,16 @@ void Window::set_size_increment(const Gfx::IntSize& size_increment) WindowServerConnection::the().send_sync<Messages::WindowServer::SetWindowBaseSizeAndSizeIncrement>(m_window_id, m_base_size, m_size_increment); } +void Window::set_resize_aspect_ratio(const Optional<Gfx::IntSize>& ratio) +{ + if (m_resize_aspect_ratio == ratio) + return; + + m_resize_aspect_ratio = ratio; + if (is_visible()) + WindowServerConnection::the().send_sync<Messages::WindowServer::SetWindowResizeAspectRatio>(m_window_id, m_resize_aspect_ratio); +} + void Window::did_add_widget(Badge<Widget>, Widget& widget) { if (!m_focused_widget && widget.accepts_focus()) diff --git a/Libraries/LibGUI/Window.h b/Libraries/LibGUI/Window.h index 4d8f96e4ce..88b7b39fa6 100644 --- a/Libraries/LibGUI/Window.h +++ b/Libraries/LibGUI/Window.h @@ -179,6 +179,10 @@ public: void set_size_increment(const Gfx::IntSize&); Gfx::IntSize base_size() const { return m_base_size; } void set_base_size(const Gfx::IntSize&); + const Optional<Gfx::IntSize>& resize_aspect_ratio() const { return m_resize_aspect_ratio; } + void set_resize_aspect_ratio(int width, int height) { set_resize_aspect_ratio(Gfx::IntSize(width, height)); } + void set_no_resize_aspect_ratio() { set_resize_aspect_ratio({}); } + void set_resize_aspect_ratio(const Optional<Gfx::IntSize>& ratio); void set_override_cursor(StandardCursor); void set_override_cursor(const Gfx::Bitmap&); @@ -260,6 +264,7 @@ private: bool m_double_buffering_enabled { true }; bool m_modal { false }; bool m_resizable { true }; + Optional<Gfx::IntSize> m_resize_aspect_ratio {}; bool m_minimizable { true }; bool m_fullscreen { false }; bool m_frameless { false }; diff --git a/Services/WindowServer/ClientConnection.cpp b/Services/WindowServer/ClientConnection.cpp index 0af1a8f184..1c6937e76f 100644 --- a/Services/WindowServer/ClientConnection.cpp +++ b/Services/WindowServer/ClientConnection.cpp @@ -479,6 +479,7 @@ OwnPtr<Messages::WindowServer::CreateWindowResponse> ClientConnection::handle(co window->set_opacity(message.opacity()); window->set_size_increment(message.size_increment()); window->set_base_size(message.base_size()); + window->set_resize_aspect_ratio(message.resize_aspect_ratio()); window->invalidate(); if (window->type() == WindowType::MenuApplet) AppletManager::the().add_applet(*window); @@ -816,6 +817,20 @@ OwnPtr<Messages::WindowServer::SetWindowBaseSizeAndSizeIncrementResponse> Client return make<Messages::WindowServer::SetWindowBaseSizeAndSizeIncrementResponse>(); } +OwnPtr<Messages::WindowServer::SetWindowResizeAspectRatioResponse> ClientConnection::handle(const Messages::WindowServer::SetWindowResizeAspectRatio& message) +{ + auto it = m_windows.find(message.window_id()); + if (it == m_windows.end()) { + did_misbehave("SetWindowResizeAspectRatioResponse: Bad window ID"); + return nullptr; + } + + auto& window = *it->value; + window.set_resize_aspect_ratio(message.resize_aspect_ratio()); + + return make<Messages::WindowServer::SetWindowResizeAspectRatioResponse>(); +} + void ClientConnection::handle(const Messages::WindowServer::EnableDisplayLink&) { if (m_has_display_link) diff --git a/Services/WindowServer/ClientConnection.h b/Services/WindowServer/ClientConnection.h index d5b261329b..e45438cd2f 100644 --- a/Services/WindowServer/ClientConnection.h +++ b/Services/WindowServer/ClientConnection.h @@ -138,6 +138,7 @@ private: virtual OwnPtr<Messages::WindowServer::SetSystemThemeResponse> handle(const Messages::WindowServer::SetSystemTheme&) override; virtual OwnPtr<Messages::WindowServer::GetSystemThemeResponse> handle(const Messages::WindowServer::GetSystemTheme&) override; virtual OwnPtr<Messages::WindowServer::SetWindowBaseSizeAndSizeIncrementResponse> handle(const Messages::WindowServer::SetWindowBaseSizeAndSizeIncrement&) override; + virtual OwnPtr<Messages::WindowServer::SetWindowResizeAspectRatioResponse> handle(const Messages::WindowServer::SetWindowResizeAspectRatio&) override; virtual void handle(const Messages::WindowServer::EnableDisplayLink&) override; virtual void handle(const Messages::WindowServer::DisableDisplayLink&) override; virtual void handle(const Messages::WindowServer::SetWindowProgress&) override; diff --git a/Services/WindowServer/Window.cpp b/Services/WindowServer/Window.cpp index f089b10a75..df7886bb1c 100644 --- a/Services/WindowServer/Window.cpp +++ b/Services/WindowServer/Window.cpp @@ -297,7 +297,7 @@ void Window::set_maximized(bool maximized) { if (m_maximized == maximized) return; - if (maximized && !is_resizable()) + if (maximized && (!is_resizable() || resize_aspect_ratio().has_value())) return; set_tiled(WindowTileType::None); m_maximized = maximized; @@ -616,6 +616,9 @@ void Window::set_tiled(WindowTileType tiled) if (m_tiled == tiled) return; + if (resize_aspect_ratio().has_value()) + return; + m_tiled = tiled; if (tiled != WindowTileType::None) m_untiled_rect = m_rect; diff --git a/Services/WindowServer/Window.h b/Services/WindowServer/Window.h index cdf7c0ce05..8d6d245185 100644 --- a/Services/WindowServer/Window.h +++ b/Services/WindowServer/Window.h @@ -207,6 +207,9 @@ public: Gfx::IntSize size_increment() const { return m_size_increment; } void set_size_increment(const Gfx::IntSize& increment) { m_size_increment = increment; } + const Optional<Gfx::IntSize>& resize_aspect_ratio() const { return m_resize_aspect_ratio; } + void set_resize_aspect_ratio(const Optional<Gfx::IntSize>& ratio) { m_resize_aspect_ratio = ratio; } + Gfx::IntSize base_size() const { return m_base_size; } void set_base_size(const Gfx::IntSize& size) { m_base_size = size; } @@ -314,6 +317,7 @@ private: bool m_minimizable { false }; bool m_frameless { false }; bool m_resizable { false }; + Optional<Gfx::IntSize> m_resize_aspect_ratio {}; bool m_listens_to_wm_events { false }; bool m_minimized { false }; bool m_maximized { false }; diff --git a/Services/WindowServer/WindowManager.cpp b/Services/WindowServer/WindowManager.cpp index 2d860dea60..3ab32955bc 100644 --- a/Services/WindowServer/WindowManager.cpp +++ b/Services/WindowServer/WindowManager.cpp @@ -643,6 +643,15 @@ bool WindowManager::process_ongoing_window_resize(const MouseEvent& event, Windo new_rect.set_height(m_resize_window->base_size().height() + vertical_incs * m_resize_window->size_increment().height()); } + if (m_resize_window->resize_aspect_ratio().has_value()) { + auto& ratio = m_resize_window->resize_aspect_ratio().value(); + if (abs(change_w) > abs(change_h)) { + new_rect.set_height(new_rect.width() * ratio.height() / ratio.width()); + } else { + new_rect.set_width(new_rect.height() * ratio.width() / ratio.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 diff --git a/Services/WindowServer/WindowServer.ipc b/Services/WindowServer/WindowServer.ipc index 6f472cbab3..871898db81 100644 --- a/Services/WindowServer/WindowServer.ipc +++ b/Services/WindowServer/WindowServer.ipc @@ -43,6 +43,7 @@ endpoint WindowServer = 2 float opacity, Gfx::IntSize base_size, Gfx::IntSize size_increment, + Optional<Gfx::IntSize> resize_aspect_ratio, i32 type, [UTF8] String title, i32 parent_window_id) => (i32 window_id) @@ -99,6 +100,7 @@ endpoint WindowServer = 2 GetSystemTheme() => ([UTF8] String theme_name) SetWindowBaseSizeAndSizeIncrement(i32 window_id, Gfx::IntSize base_size, Gfx::IntSize size_increment) => () + SetWindowResizeAspectRatio(i32 window_id, Optional<Gfx::IntSize> resize_aspect_ratio) => () EnableDisplayLink() =| DisableDisplayLink() =| |