From bbb490b24fbdfa12a1d788a492daf33c8a42cb33 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 25 Jun 2025 13:31:54 +0300 Subject: [PATCH] LibGUI: Implement set_max_size I already support set_min_size so why not this :) --- userspace/libraries/LibGUI/Window.cpp | 10 ++++++ .../libraries/LibGUI/include/LibGUI/Packet.h | 7 ++++ .../libraries/LibGUI/include/LibGUI/Window.h | 1 + userspace/programs/WindowServer/Window.h | 4 +++ .../programs/WindowServer/WindowServer.cpp | 33 +++++++++++++++++-- .../programs/WindowServer/WindowServer.h | 1 + userspace/programs/WindowServer/main.cpp | 4 +++ 7 files changed, 58 insertions(+), 2 deletions(-) diff --git a/userspace/libraries/LibGUI/Window.cpp b/userspace/libraries/LibGUI/Window.cpp index 87aa7fa6..0b3339e8 100644 --- a/userspace/libraries/LibGUI/Window.cpp +++ b/userspace/libraries/LibGUI/Window.cpp @@ -178,6 +178,16 @@ namespace LibGUI return on_socket_error(__FUNCTION__); } + void Window::set_max_size(uint32_t width, uint32_t height) + { + WindowPacket::WindowSetMaxSize packet; + packet.width = width; + packet.height = height; + + if (auto ret = packet.send_serialized(m_server_fd); ret.is_error()) + return on_socket_error(__FUNCTION__); + } + void Window::set_attributes(Attributes attributes) { WindowPacket::WindowSetAttributes packet; diff --git a/userspace/libraries/LibGUI/include/LibGUI/Packet.h b/userspace/libraries/LibGUI/include/LibGUI/Packet.h index 0ce2820a..59cb5206 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Packet.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Packet.h @@ -165,6 +165,7 @@ namespace LibGUI WindowSetMouseCapture, WindowSetSize, WindowSetMinSize, + WindowSetMaxSize, WindowSetFullscreen, WindowSetTitle, @@ -234,6 +235,12 @@ namespace LibGUI uint32_t, height ); + DEFINE_PACKET( + WindowSetMaxSize, + uint32_t, width, + uint32_t, height + ); + DEFINE_PACKET( WindowSetFullscreen, bool, fullscreen diff --git a/userspace/libraries/LibGUI/include/LibGUI/Window.h b/userspace/libraries/LibGUI/include/LibGUI/Window.h index dcd4b0c7..4ac478a5 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Window.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Window.h @@ -47,6 +47,7 @@ namespace LibGUI void set_attributes(Attributes attributes); void set_min_size(uint32_t width, uint32_t height); + void set_max_size(uint32_t width, uint32_t height); // send resize request to window server // actual resize is only done after resize callback is called diff --git a/userspace/programs/WindowServer/Window.h b/userspace/programs/WindowServer/Window.h index aed9b46c..910a557b 100644 --- a/userspace/programs/WindowServer/Window.h +++ b/userspace/programs/WindowServer/Window.h @@ -55,6 +55,9 @@ public: Rectangle get_min_size() const { return m_min_size; } void set_min_size(Rectangle min_size) { m_min_size = min_size.get_bounding_box({ 0, 0, m_title_bar_height, 0 }); } + Rectangle get_max_size() const { return m_max_size; } + void set_max_size(Rectangle max_size) { m_max_size = max_size; } + BAN::ErrorOr set_title(BAN::StringView title) { m_title.clear(); TRY(m_title.append(title)); TRY(prepare_title_bar()); return {}; } const uint32_t* framebuffer() const { return m_fb_addr; } @@ -88,6 +91,7 @@ private: const int m_client_fd { -1 }; Rectangle m_client_area { 0, 0, 0, 0 }; Rectangle m_min_size { 0, 0, m_title_bar_height, 0 }; + Rectangle m_max_size { 0, 0, 10'000, 10'000 }; long m_smo_key { 0 }; uint32_t* m_fb_addr { nullptr }; BAN::String m_title; diff --git a/userspace/programs/WindowServer/WindowServer.cpp b/userspace/programs/WindowServer/WindowServer.cpp index 3dae0177..56103af6 100644 --- a/userspace/programs/WindowServer/WindowServer.cpp +++ b/userspace/programs/WindowServer/WindowServer.cpp @@ -278,9 +278,31 @@ void WindowServer::on_window_set_min_size(int fd, const LibGUI::WindowPacket::Wi return; } + // FIXME: should this resize window target_window->set_min_size({ 0, 0, static_cast(packet.width), static_cast(packet.height) }); } +void WindowServer::on_window_set_max_size(int fd, const LibGUI::WindowPacket::WindowSetMaxSize& packet) +{ + BAN::RefPtr target_window; + for (auto& window : m_client_windows) + { + if (window->client_fd() != fd) + continue; + target_window = window; + break; + } + + if (!target_window) + { + dwarnln("client tried to set window max size while not owning a window"); + return; + } + + // FIXME: should this resize window + target_window->set_max_size({ 0, 0, static_cast(packet.width), static_cast(packet.height) }); +} + void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket::WindowSetFullscreen& packet) { if (m_state == State::Fullscreen) @@ -1213,16 +1235,23 @@ Rectangle WindowServer::cursor_area() const Rectangle WindowServer::resize_area(Position cursor) const { const auto min_size = m_focused_window->get_min_size(); + const auto max_size = m_focused_window->get_max_size(); int32_t diff_x = m_resize_start.x - cursor.x; if (m_resize_quadrant % 2) diff_x = -diff_x; - diff_x = BAN::Math::max(diff_x, -m_focused_window->client_width() + min_size.width); + diff_x = BAN::Math::clamp(diff_x, + -m_focused_window->client_width() + min_size.width, + -m_focused_window->client_width() + max_size.width + ); int32_t diff_y = m_resize_start.y - cursor.y; if (m_resize_quadrant / 2) diff_y = -diff_y; - diff_y = BAN::Math::max(diff_y, -m_focused_window->client_height() + min_size.height); + diff_y = BAN::Math::clamp(diff_y, + -m_focused_window->client_height() + min_size.height, + -m_focused_window->client_height() + max_size.height + ); int32_t off_x = 0; if (m_resize_quadrant % 2 == 0) diff --git a/userspace/programs/WindowServer/WindowServer.h b/userspace/programs/WindowServer/WindowServer.h index 720a1ac0..e3a385e5 100644 --- a/userspace/programs/WindowServer/WindowServer.h +++ b/userspace/programs/WindowServer/WindowServer.h @@ -38,6 +38,7 @@ public: void on_window_set_mouse_capture(int fd, const LibGUI::WindowPacket::WindowSetMouseCapture&); void on_window_set_size(int fd, const LibGUI::WindowPacket::WindowSetSize&); void on_window_set_min_size(int fd, const LibGUI::WindowPacket::WindowSetMinSize&); + void on_window_set_max_size(int fd, const LibGUI::WindowPacket::WindowSetMaxSize&); void on_window_set_fullscreen(int fd, const LibGUI::WindowPacket::WindowSetFullscreen&); void on_window_set_title(int fd, const LibGUI::WindowPacket::WindowSetTitle&); diff --git a/userspace/programs/WindowServer/main.cpp b/userspace/programs/WindowServer/main.cpp index 04070565..a386edd0 100644 --- a/userspace/programs/WindowServer/main.cpp +++ b/userspace/programs/WindowServer/main.cpp @@ -379,6 +379,10 @@ int main() if (auto ret = LibGUI::WindowPacket::WindowSetMinSize::deserialize(client_data.packet_buffer.span()); !ret.is_error()) window_server.on_window_set_min_size(fd, ret.release_value()); break; + case LibGUI::PacketType::WindowSetMaxSize: + if (auto ret = LibGUI::WindowPacket::WindowSetMaxSize::deserialize(client_data.packet_buffer.span()); !ret.is_error()) + window_server.on_window_set_max_size(fd, ret.release_value()); + break; case LibGUI::PacketType::WindowSetFullscreen: if (auto ret = LibGUI::WindowPacket::WindowSetFullscreen::deserialize(client_data.packet_buffer.span()); !ret.is_error()) window_server.on_window_set_fullscreen(fd, ret.release_value());