diff --git a/Userland/Services/WindowServer/ClientConnection.cpp b/Userland/Services/WindowServer/ClientConnection.cpp index b6edb95a5b7..c4dc7b563a4 100644 --- a/Userland/Services/WindowServer/ClientConnection.cpp +++ b/Userland/Services/WindowServer/ClientConnection.cpp @@ -1129,7 +1129,11 @@ void ClientConnection::set_window_parent_from_client(i32 client_id, i32 parent_i if (!parent_window) did_misbehave("SetWindowParentFromClient: Bad parent window ID"); - child_window->set_parent_window(*parent_window); + if (parent_window->is_stealable_by_client(this->client_id())) { + child_window->set_parent_window(*parent_window); + } else { + did_misbehave("SetWindowParentFromClient: Window is not stealable"); + } } Messages::WindowServer::GetWindowRectFromClientResponse ClientConnection::get_window_rect_from_client(i32 client_id, i32 window_id) @@ -1145,4 +1149,36 @@ Messages::WindowServer::GetWindowRectFromClientResponse ClientConnection::get_wi return window->rect(); } +void ClientConnection::add_window_stealing_for_client(i32 client_id, i32 window_id) +{ + auto window = window_from_id(window_id); + if (!window) + did_misbehave("AddWindowStealingForClient: Bad window ID"); + + if (!from_client_id(client_id)) + did_misbehave("AddWindowStealingForClient: Bad client ID"); + + window->add_stealing_for_client(client_id); +} + +void ClientConnection::remove_window_stealing_for_client(i32 client_id, i32 window_id) +{ + auto window = window_from_id(window_id); + if (!window) + did_misbehave("RemoveWindowStealingForClient: Bad window ID"); + + // Don't check if the client exists, it may have died + + window->remove_stealing_for_client(client_id); +} + +void ClientConnection::remove_window_stealing(i32 window_id) +{ + auto window = window_from_id(window_id); + if (!window) + did_misbehave("RemoveWindowStealing: Bad window ID"); + + window->remove_all_stealing(); +} + } diff --git a/Userland/Services/WindowServer/ClientConnection.h b/Userland/Services/WindowServer/ClientConnection.h index 8967d41ef9f..74c0f29c329 100644 --- a/Userland/Services/WindowServer/ClientConnection.h +++ b/Userland/Services/WindowServer/ClientConnection.h @@ -166,6 +166,9 @@ private: virtual void set_flash_flush(bool) override; virtual void set_window_parent_from_client(i32, i32, i32) override; virtual Messages::WindowServer::GetWindowRectFromClientResponse get_window_rect_from_client(i32, i32) override; + virtual void add_window_stealing_for_client(i32, i32) override; + virtual void remove_window_stealing_for_client(i32, i32) override; + virtual void remove_window_stealing(i32) override; Window* window_from_id(i32 window_id); diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h index 8c473c702f6..b74ca9732a2 100644 --- a/Userland/Services/WindowServer/Window.h +++ b/Userland/Services/WindowServer/Window.h @@ -362,6 +362,16 @@ public: void set_moving_to_another_stack(bool value) { m_moving_to_another_stack = value; } bool is_moving_to_another_stack() const { return m_moving_to_another_stack; } + void add_stealing_for_client(i32 client_id) { m_stealable_by_client_ids.append(move(client_id)); } + void remove_stealing_for_client(i32 client_id) + { + m_stealable_by_client_ids.remove_all_matching([client_id](i32 approved_client_id) { + return approved_client_id == client_id; + }); + } + void remove_all_stealing() { m_stealable_by_client_ids.clear(); } + bool is_stealable_by_client(i32 client_id) const { return m_stealable_by_client_ids.contains_slow(client_id); } + private: Window(ClientConnection&, WindowType, int window_id, bool modal, bool minimizable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window = nullptr); Window(Core::Object&, WindowType); @@ -418,6 +428,7 @@ private: bool m_pinned { false }; bool m_moving_to_another_stack { false }; bool m_invalidate_last_render_rects { false }; + Vector m_stealable_by_client_ids; WindowTileType m_tiled { WindowTileType::None }; Gfx::IntRect m_untiled_rect; bool m_occluded { false }; diff --git a/Userland/Services/WindowServer/WindowServer.ipc b/Userland/Services/WindowServer/WindowServer.ipc index 7a24f47d2a1..38bf959770d 100644 --- a/Userland/Services/WindowServer/WindowServer.ipc +++ b/Userland/Services/WindowServer/WindowServer.ipc @@ -150,4 +150,7 @@ endpoint WindowServer set_window_parent_from_client(i32 client_id, i32 parent_id, i32 child_id) =| get_window_rect_from_client(i32 client_id, i32 window_id) => (Gfx::IntRect rect) + add_window_stealing_for_client(i32 client_id, i32 window_id) =| + remove_window_stealing_for_client(i32 client_id, i32 window_id) =| + remove_window_stealing(i32 window_id) =| }