summaryrefslogtreecommitdiff
path: root/Servers/WindowServer
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-05-01 22:59:38 +0200
committerAndreas Kling <kling@serenityos.org>2020-05-02 01:29:55 +0200
commit6228f72b87a87e6ce50bef75eb1bb947acff6e10 (patch)
treed157a8fad567489b1488ef41bb884665292995fa /Servers/WindowServer
parente9b7a51a9ad76decf118a7c0399dd49bc517f120 (diff)
downloadserenity-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.cpp20
-rw-r--r--Servers/WindowServer/ClientConnection.h2
-rw-r--r--Servers/WindowServer/Window.cpp12
-rw-r--r--Servers/WindowServer/Window.h11
-rw-r--r--Servers/WindowServer/WindowServer.ipc3
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) => ()