mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-11 17:00:37 +00:00
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.
This commit is contained in:
parent
e9b7a51a9a
commit
6228f72b87
Notes:
sideshowbarker
2024-07-19 07:07:28 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/6228f72b87a
7 changed files with 63 additions and 2 deletions
|
@ -89,6 +89,9 @@ void Window::show()
|
|||
{
|
||||
if (is_visible())
|
||||
return;
|
||||
|
||||
auto* parent_window = find_parent_window();
|
||||
|
||||
m_override_cursor = StandardCursor::None;
|
||||
auto response = WindowServerConnection::the().send_sync<Messages::WindowServer::CreateWindow>(
|
||||
m_rect_when_windowless,
|
||||
|
@ -102,7 +105,8 @@ void Window::show()
|
|||
m_base_size,
|
||||
m_size_increment,
|
||||
(i32)m_window_type,
|
||||
m_title_when_windowless);
|
||||
m_title_when_windowless,
|
||||
parent_window ? parent_window->window_id() : 0);
|
||||
m_window_id = response->window_id();
|
||||
m_visible = true;
|
||||
|
||||
|
@ -113,6 +117,15 @@ void Window::show()
|
|||
update();
|
||||
}
|
||||
|
||||
Window* Window::find_parent_window()
|
||||
{
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (ancestor->is_window())
|
||||
return static_cast<Window*>(ancestor);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Window::hide()
|
||||
{
|
||||
if (!is_visible())
|
||||
|
|
|
@ -182,6 +182,8 @@ public:
|
|||
|
||||
void did_remove_widget(Badge<Widget>, const Widget&);
|
||||
|
||||
Window* find_parent_window();
|
||||
|
||||
protected:
|
||||
Window(Core::Object* parent = nullptr);
|
||||
virtual void wm_event(WMEvent&);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) => ()
|
||||
|
||||
|
|
Loading…
Reference in a new issue