diff options
author | Andreas Kling <kling@serenityos.org> | 2020-05-01 22:59:38 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-02 01:29:55 +0200 |
commit | 6228f72b87a87e6ce50bef75eb1bb947acff6e10 (patch) | |
tree | d157a8fad567489b1488ef41bb884665292995fa /Servers/WindowServer | |
parent | e9b7a51a9ad76decf118a7c0399dd49bc517f120 (diff) | |
download | serenity-6228f72b87a87e6ce50bef75eb1bb947acff6e10.zip |
LibGUI+WindowServer: Inform WindowServer about parent/child windows
If a window has another window in its Core::Object ancestor chain,
we now communicate that relationship to WindowServer so that it can
act with awareness of parent/child windows.
Diffstat (limited to 'Servers/WindowServer')
-rw-r--r-- | Servers/WindowServer/ClientConnection.cpp | 20 | ||||
-rw-r--r-- | Servers/WindowServer/ClientConnection.h | 2 | ||||
-rw-r--r-- | Servers/WindowServer/Window.cpp | 12 | ||||
-rw-r--r-- | Servers/WindowServer/Window.h | 11 | ||||
-rw-r--r-- | Servers/WindowServer/WindowServer.ipc | 3 |
5 files changed, 47 insertions, 1 deletions
diff --git a/Servers/WindowServer/ClientConnection.cpp b/Servers/WindowServer/ClientConnection.cpp index c951754350..6b79c33bb5 100644 --- a/Servers/WindowServer/ClientConnection.cpp +++ b/Servers/WindowServer/ClientConnection.cpp @@ -451,10 +451,30 @@ OwnPtr<Messages::WindowServer::GetClipboardContentsResponse> ClientConnection::h return make<Messages::WindowServer::GetClipboardContentsResponse>(shbuf_id, clipboard.size(), clipboard.data_type()); } +Window* ClientConnection::window_from_id(i32 window_id) +{ + auto it = m_windows.find(window_id); + if (it == m_windows.end()) + return nullptr; + return it->value.ptr(); +} + OwnPtr<Messages::WindowServer::CreateWindowResponse> ClientConnection::handle(const Messages::WindowServer::CreateWindow& message) { int window_id = m_next_window_id++; auto window = Window::construct(*this, (WindowType)message.type(), window_id, message.modal(), message.minimizable(), message.resizable(), message.fullscreen()); + + dbg() << "Constructing window with parent_window_id=" << message.parent_window_id(); + + if (message.parent_window_id()) { + auto* parent_window = window_from_id(message.parent_window_id()); + if (!parent_window) { + did_misbehave("CreateWindow with bad parent_window_id"); + return nullptr; + } + window->set_parent_window(*parent_window); + } + window->set_has_alpha_channel(message.has_alpha_channel()); window->set_title(message.title()); if (!message.fullscreen()) { diff --git a/Servers/WindowServer/ClientConnection.h b/Servers/WindowServer/ClientConnection.h index ebbcb3d282..1c11bb2711 100644 --- a/Servers/WindowServer/ClientConnection.h +++ b/Servers/WindowServer/ClientConnection.h @@ -127,6 +127,8 @@ private: virtual void handle(const Messages::WindowServer::EnableDisplayLink&) override; virtual void handle(const Messages::WindowServer::DisableDisplayLink&) override; + Window* window_from_id(i32 window_id); + HashMap<int, NonnullRefPtr<Window>> m_windows; HashMap<int, NonnullOwnPtr<MenuBar>> m_menubars; HashMap<int, NonnullRefPtr<Menu>> m_menus; diff --git a/Servers/WindowServer/Window.cpp b/Servers/WindowServer/Window.cpp index 2bc92c35b3..84fcc92a22 100644 --- a/Servers/WindowServer/Window.cpp +++ b/Servers/WindowServer/Window.cpp @@ -482,4 +482,16 @@ void Window::recalculate_rect() Core::EventLoop::current().post_event(*this, make<ResizeEvent>(old_rect, m_rect)); } +void Window::add_child_window(Window& child_window) +{ + m_child_windows.append(child_window.make_weak_ptr()); +} + +void Window::set_parent_window(Window& parent_window) +{ + ASSERT(!m_parent_window); + m_parent_window = parent_window.make_weak_ptr(); + parent_window.add_child_window(*this); +} + } diff --git a/Servers/WindowServer/Window.h b/Servers/WindowServer/Window.h index ce796b602f..71e8d6bfc0 100644 --- a/Servers/WindowServer/Window.h +++ b/Servers/WindowServer/Window.h @@ -28,6 +28,7 @@ #include <AK/InlineLinkedList.h> #include <AK/String.h> +#include <AK/WeakPtr.h> #include <LibCore/Object.h> #include <LibGfx/Bitmap.h> #include <LibGfx/DisjointRectSet.h> @@ -229,12 +230,22 @@ public: void detach_client(Badge<ClientConnection>); + Window* parent_window() { return m_parent_window; } + const Window* parent_window() const { return m_parent_window; } + + void set_parent_window(Window&); + private: void handle_mouse_event(const MouseEvent&); void update_menu_item_text(PopupMenuItem item); void update_menu_item_enabled(PopupMenuItem item); + void add_child_window(Window&); ClientConnection* m_client { nullptr }; + + WeakPtr<Window> m_parent_window; + Vector<WeakPtr<Window>> m_child_windows; + String m_title; Gfx::Rect m_rect; Gfx::Rect m_saved_nonfullscreen_rect; diff --git a/Servers/WindowServer/WindowServer.ipc b/Servers/WindowServer/WindowServer.ipc index ab73161f90..34d9e8db6c 100644 --- a/Servers/WindowServer/WindowServer.ipc +++ b/Servers/WindowServer/WindowServer.ipc @@ -41,7 +41,8 @@ endpoint WindowServer = 2 Gfx::Size base_size, Gfx::Size size_increment, i32 type, - String title) => (i32 window_id) + String title, + i32 parent_window_id) => (i32 window_id) DestroyWindow(i32 window_id) => () |