From f7e747b68e5f5dd44f4fb9462ff8bf16a5630c0c Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 1 Nov 2022 14:23:22 -0400 Subject: [PATCH] LibGUI+WindowServer: Create and broadcast an event when a window moves LibWeb's Window object will need to know the OS-level position and size of the GUI::Window for e.g. screenX, screenY, outerWidth, outerHeight. It will also need to know about changes to that data. --- .../Libraries/LibGUI/ConnectionToWindowServer.cpp | 6 ++++++ .../Libraries/LibGUI/ConnectionToWindowServer.h | 1 + Userland/Libraries/LibGUI/Event.h | 15 +++++++++++++++ Userland/Services/WindowServer/Event.h | 15 +++++++++++++++ Userland/Services/WindowServer/Window.cpp | 7 +++++++ Userland/Services/WindowServer/WindowClient.ipc | 1 + Userland/Services/WindowServer/WindowManager.cpp | 2 ++ 7 files changed, 47 insertions(+) diff --git a/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp b/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp index 3aa4771321..6a29e66a62 100644 --- a/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp +++ b/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp @@ -102,6 +102,12 @@ void ConnectionToWindowServer::window_resized(i32 window_id, Gfx::IntRect const& } } +void ConnectionToWindowServer::window_moved(i32 window_id, Gfx::IntRect const& new_rect) +{ + if (auto* window = Window::from_window_id(window_id)) + Core::EventLoop::current().post_event(*window, make(new_rect.location())); +} + void ConnectionToWindowServer::window_activated(i32 window_id) { if (auto* window = Window::from_window_id(window_id)) diff --git a/Userland/Libraries/LibGUI/ConnectionToWindowServer.h b/Userland/Libraries/LibGUI/ConnectionToWindowServer.h index 893b0bac17..6b2970bd0a 100644 --- a/Userland/Libraries/LibGUI/ConnectionToWindowServer.h +++ b/Userland/Libraries/LibGUI/ConnectionToWindowServer.h @@ -41,6 +41,7 @@ private: virtual void window_input_left(i32) override; virtual void window_close_request(i32) override; virtual void window_resized(i32, Gfx::IntRect const&) override; + virtual void window_moved(i32, Gfx::IntRect const&) override; virtual void menu_item_activated(i32, u32) override; virtual void menu_item_entered(i32, u32) override; virtual void menu_item_left(i32, u32) override; diff --git a/Userland/Libraries/LibGUI/Event.h b/Userland/Libraries/LibGUI/Event.h index a3366122ef..9d9597df12 100644 --- a/Userland/Libraries/LibGUI/Event.h +++ b/Userland/Libraries/LibGUI/Event.h @@ -28,6 +28,7 @@ public: Paint, MultiPaint, Resize, + Move, MouseMove, MouseDown, MouseDoubleClick, @@ -310,6 +311,20 @@ private: Gfx::IntSize m_size; }; +class MoveEvent final : public Event { +public: + explicit MoveEvent(Gfx::IntPoint const& size) + : Event(Event::Move) + , m_position(size) + { + } + + Gfx::IntPoint const& position() const { return m_position; } + +private: + Gfx::IntPoint m_position; +}; + class ContextMenuEvent final : public Event { public: explicit ContextMenuEvent(Gfx::IntPoint const& position, Gfx::IntPoint const& screen_position) diff --git a/Userland/Services/WindowServer/Event.h b/Userland/Services/WindowServer/Event.h index f3fb5ebab1..9114db8ad4 100644 --- a/Userland/Services/WindowServer/Event.h +++ b/Userland/Services/WindowServer/Event.h @@ -35,6 +35,7 @@ public: WindowInputLeft, WindowCloseRequest, WindowResized, + WindowMoved, }; Event() = default; @@ -157,4 +158,18 @@ private: Gfx::IntRect m_rect; }; +class MoveEvent final : public Event { +public: + MoveEvent(Gfx::IntRect const& rect) + : Event(Event::WindowMoved) + , m_rect(rect) + { + } + + Gfx::IntRect const& rect() const { return m_rect; } + +private: + Gfx::IntRect m_rect; +}; + } diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 0ed9464faf..e03b1bd811 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -408,6 +408,7 @@ void Window::set_maximized(bool maximized) set_rect(m_floating_rect); m_frame.did_set_maximized({}, maximized); Core::EventLoop::current().post_event(*this, make(m_rect)); + Core::EventLoop::current().post_event(*this, make(m_rect)); set_default_positioned(false); WindowManager::the().notify_minimization_state_changed(*this); @@ -486,6 +487,9 @@ void Window::event(Core::Event& event) case Event::WindowResized: m_client->async_window_resized(m_window_id, static_cast(event).rect()); break; + case Event::WindowMoved: + m_client->async_window_moved(m_window_id, static_cast(event).rect()); + break; default: break; } @@ -826,6 +830,7 @@ void Window::set_fullscreen(bool fullscreen) } Core::EventLoop::current().post_event(*this, make(new_window_rect)); + Core::EventLoop::current().post_event(*this, make(new_window_rect)); set_rect(new_window_rect); } @@ -896,6 +901,7 @@ bool Window::set_untiled() set_rect(m_floating_rect); Core::EventLoop::current().post_event(*this, make(m_rect)); + Core::EventLoop::current().post_event(*this, make(m_rect)); return true; } @@ -917,6 +923,7 @@ void Window::set_tiled(WindowTileType tile_type) set_rect(WindowManager::the().tiled_window_rect(*this, tile_type)); Core::EventLoop::current().post_event(*this, make(m_rect)); + Core::EventLoop::current().post_event(*this, make(m_rect)); } void Window::detach_client(Badge) diff --git a/Userland/Services/WindowServer/WindowClient.ipc b/Userland/Services/WindowServer/WindowClient.ipc index 4688b052f9..ec902f17b3 100644 --- a/Userland/Services/WindowServer/WindowClient.ipc +++ b/Userland/Services/WindowServer/WindowClient.ipc @@ -23,6 +23,7 @@ endpoint WindowClient window_input_preempted(i32 window_id, i32 preemptor) =| window_close_request(i32 window_id) =| window_resized(i32 window_id, Gfx::IntRect new_rect) =| + window_moved(i32 window_id, Gfx::IntRect new_rect) =| menu_item_activated(i32 menu_id, u32 identifier) =| menu_item_entered(i32 menu_id, u32 identifier) =| diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 5d52ae38e8..196ce52cf6 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -742,6 +742,7 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event) if (!m_move_window->is_tiled()) m_move_window->set_floating_rect(m_move_window->rect()); + Core::EventLoop::current().post_event(*m_move_window, make(m_move_window->rect())); m_move_window->invalidate(true, true); if (m_move_window->is_resizable()) { process_event_for_doubleclick(*m_move_window, event); @@ -816,6 +817,7 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event) m_geometry_overlay->window_rect_changed(); } } + Core::EventLoop::current().post_event(*m_move_window, make(m_move_window->rect())); return true; }