diff options
author | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2021-01-22 21:46:59 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-23 08:34:17 +0100 |
commit | 399908e53cfc7803d71a6916154f60db1838b185 (patch) | |
tree | 5c57141dedbcb2c86fe176f3378181766cf8c817 /Userland/Services | |
parent | 345909c009679f5edf10cefca78089b4d1fe7eba (diff) | |
download | serenity-399908e53cfc7803d71a6916154f60db1838b185.zip |
WindowServer: Normalize preferred rect before applying
Previously, SetWindowRect and SetWindowRect could supply basically arbitrary
x and y coordinates. This could happen either due to a malicious or malfunctioning
program, or even due to the auto-centering feature.
This patch also moves the 'normalization' code out of ClientConnection to Window,
where it belongs better.
Fixes #4135.
Fixes #5052.
Diffstat (limited to 'Userland/Services')
-rw-r--r-- | Userland/Services/WindowServer/ClientConnection.cpp | 21 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Window.cpp | 26 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Window.h | 1 |
3 files changed, 33 insertions, 15 deletions
diff --git a/Userland/Services/WindowServer/ClientConnection.cpp b/Userland/Services/WindowServer/ClientConnection.cpp index 0693bf9c6d..947b25c8f5 100644 --- a/Userland/Services/WindowServer/ClientConnection.cpp +++ b/Userland/Services/WindowServer/ClientConnection.cpp @@ -48,15 +48,6 @@ namespace WindowServer { HashMap<int, NonnullRefPtr<ClientConnection>>* s_connections; -static Gfx::IntRect normalize_window_rect(Gfx::IntRect rect, WindowType window_type) -{ - auto min_size = 1; - if (window_type == WindowType::Normal) - min_size = 50; - Gfx::IntRect normalized_rect = { rect.x(), rect.y(), max(rect.width(), min_size), max(rect.height(), min_size) }; - return normalized_rect; -} - void ClientConnection::for_each_client(Function<void(ClientConnection&)> callback) { if (!s_connections) @@ -403,10 +394,10 @@ OwnPtr<Messages::WindowServer::SetWindowRectResponse> ClientConnection::handle(c if (message.rect().location() != window.rect().location()) { window.set_default_positioned(false); } - auto normalized_rect = normalize_window_rect(message.rect(), window.type()); - window.set_rect(normalized_rect); - window.request_update(normalized_rect); - return make<Messages::WindowServer::SetWindowRectResponse>(normalized_rect); + window.set_rect(message.rect()); + window.normalize_rect(); + window.request_update(window.rect()); + return make<Messages::WindowServer::SetWindowRectResponse>(window.rect()); } OwnPtr<Messages::WindowServer::GetWindowRectResponse> ClientConnection::handle(const Messages::WindowServer::GetWindowRect& message) @@ -461,8 +452,8 @@ OwnPtr<Messages::WindowServer::CreateWindowResponse> ClientConnection::handle(co rect = { WindowManager::the().get_recommended_window_position({ 100, 100 }), message.rect().size() }; window->set_default_positioned(true); } - auto normalized_rect = normalize_window_rect(rect, window->type()); - window->set_rect(normalized_rect); + window->set_rect(rect); + window->normalize_rect(); } if (window->type() == WindowType::Desktop) { window->set_rect(WindowManager::the().desktop_rect()); diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 1d0497c1c6..f4a028093b 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -176,6 +176,32 @@ void Window::set_rect_without_repaint(const Gfx::IntRect& rect) m_frame.notify_window_rect_changed(old_rect, rect); // recomputes occlusions } +void Window::normalize_rect() +{ + auto min_size = 1; + // Must be -1 to allow windows just outside the desktop rect. + // For example, the windows that make the desktop rect smaller + // than the display resolution (e.g. the TaskBar). + auto min_visible = -1; + auto desktop = WindowManager::the().desktop_rect(); + auto min_y = 0; + if (type() == WindowType::Normal) { + min_size = 50; + min_visible = 50; + // 5 pixels is the amount of frame decoration that can be sacrificed before starting to become an issue. + min_y = desktop.top() - 5; + } + auto new_width = max(width(), min_size); + auto new_height = max(height(), min_size); + Gfx::IntRect normalized_rect = { + clamp(x(), -new_width + min_visible, desktop.width() - min_visible), + clamp(y(), min_y, desktop.bottom() - min_visible), + new_width, + new_height, + }; + set_rect(normalized_rect); +} + void Window::handle_mouse_event(const MouseEvent& event) { set_automatic_cursor_tracking_enabled(event.buttons() != 0); diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h index c2c54311d5..662fdb6314 100644 --- a/Userland/Services/WindowServer/Window.h +++ b/Userland/Services/WindowServer/Window.h @@ -158,6 +158,7 @@ public: void set_rect(const Gfx::IntRect&); void set_rect(int x, int y, int width, int height) { set_rect({ x, y, width, height }); } void set_rect_without_repaint(const Gfx::IntRect&); + void normalize_rect(); void set_taskbar_rect(const Gfx::IntRect&); const Gfx::IntRect& taskbar_rect() const { return m_taskbar_rect; } |