From 4ad586552dc8c60c52a75c06dfa9a8be382d77e6 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 23 Jun 2026 20:52:12 +0300 Subject: [PATCH] LibGUI/WindowServer: Send window move events --- userspace/libraries/LibGUI/Window.cpp | 14 ++++- .../libraries/LibGUI/include/LibGUI/Packet.h | 10 ++++ .../libraries/LibGUI/include/LibGUI/Window.h | 2 + .../programs/WindowServer/WindowServer.cpp | 55 ++++++++++++------- .../programs/WindowServer/WindowServer.h | 1 + 5 files changed, 60 insertions(+), 22 deletions(-) diff --git a/userspace/libraries/LibGUI/Window.cpp b/userspace/libraries/LibGUI/Window.cpp index c9929c09..36c413b9 100644 --- a/userspace/libraries/LibGUI/Window.cpp +++ b/userspace/libraries/LibGUI/Window.cpp @@ -70,15 +70,21 @@ namespace LibGUI TRY(create_packet.title.append(title)); window->send_packet(create_packet, __FUNCTION__); - bool resized = false; + int32_t x, y; + bool resized { false }, moved { false }; window->set_resize_window_event_callback([&]() { resized = true; }); - while (!resized) + window->set_window_move_event_callback([&](auto event) { x = event.x; y = event.y; moved = true; }); + while (!resized || !moved) { // FIXME: timeout? window->wait_events(); window->poll_events(); } window->set_resize_window_event_callback({}); + window->set_window_move_event_callback({}); + + // hack to resend move event :^) + window->set_position(x, y); server_closer.disable(); epoll_closer.disable(); @@ -365,6 +371,10 @@ namespace LibGUI if (m_window_fullscreen_event_callback) m_window_fullscreen_event_callback(TRY_OR_BREAK(EventPacket::WindowFullscreenEvent::deserialize(packet_span)).event); break; + case PacketType::WindowMoveEvent: + if (m_window_move_event_callback) + m_window_move_event_callback(TRY_OR_BREAK(EventPacket::WindowMoveEvent::deserialize(packet_span)).event); + break; case PacketType::KeyEvent: if (m_key_event_callback) m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_span)).event); diff --git a/userspace/libraries/LibGUI/include/LibGUI/Packet.h b/userspace/libraries/LibGUI/include/LibGUI/Packet.h index cd3b0eab..d701df81 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Packet.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Packet.h @@ -206,6 +206,7 @@ namespace LibGUI WindowShownEvent, WindowFocusEvent, WindowFullscreenEvent, + WindowMoveEvent, KeyEvent, MouseButtonEvent, MouseMoveEvent, @@ -346,6 +347,15 @@ namespace LibGUI event_t, event ); + DEFINE_PACKET_EXTRA( + WindowMoveEvent, + struct event_t { + int32_t x; + int32_t y; + }, + event_t, event + ); + DEFINE_PACKET_EXTRA( KeyEvent, using event_t = LibInput::KeyEvent, diff --git a/userspace/libraries/LibGUI/include/LibGUI/Window.h b/userspace/libraries/LibGUI/include/LibGUI/Window.h index 700df18e..b9cf8c65 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Window.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Window.h @@ -79,6 +79,7 @@ namespace LibGUI void set_window_shown_event_callback(BAN::Function callback) { m_window_shown_event_callback = callback; } void set_window_focus_event_callback(BAN::Function callback) { m_window_focus_event_callback = callback; } void set_window_fullscreen_event_callback(BAN::Function callback) { m_window_fullscreen_event_callback = callback; } + void set_window_move_event_callback(BAN::Function callback) { m_window_move_event_callback = callback; } int server_fd() const { return m_server_fd; } @@ -118,6 +119,7 @@ namespace LibGUI BAN::Function m_window_shown_event_callback; BAN::Function m_window_focus_event_callback; BAN::Function m_window_fullscreen_event_callback; + BAN::Function m_window_move_event_callback; BAN::Function m_key_event_callback; BAN::Function m_mouse_button_event_callback; BAN::Function m_mouse_move_event_callback; diff --git a/userspace/programs/WindowServer/WindowServer.cpp b/userspace/programs/WindowServer/WindowServer.cpp index 2c67d6c0..3620b3f1 100644 --- a/userspace/programs/WindowServer/WindowServer.cpp +++ b/userspace/programs/WindowServer/WindowServer.cpp @@ -75,10 +75,11 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr } window->set_attributes(packet.attributes); - window->set_position({ - static_cast((m_framebuffer.width - window->client_width()) / 2), - static_cast((m_framebuffer.height - window->client_height()) / 2), - }); + move_window( + window, + (m_framebuffer.width - window->client_width()) / 2, + (m_framebuffer.height - window->client_height()) / 2 + ); const LibGUI::EventPacket::ResizeWindowEvent event_packet { .width = static_cast(window->client_width()), @@ -151,10 +152,7 @@ void WindowServer::on_window_set_position(int fd, const LibGUI::WindowPacket::Wi } const auto old_client_area = target_window->full_area(); - target_window->set_position({ - .x = packet.x, - .y = packet.y, - }); + move_window(target_window, packet.x, packet.y); if (!target_window->get_attributes().shown) return; @@ -186,7 +184,7 @@ void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket:: { if (!resize_window(m_focused_window, m_non_full_screen_rect.width(), m_non_full_screen_rect.height())) return; - m_focused_window->set_position({ m_non_full_screen_rect.min_x, m_non_full_screen_rect.min_y }); + move_window(m_focused_window, m_non_full_screen_rect.min_x, m_non_full_screen_rect.min_y); } m_focused_window = nullptr; @@ -310,7 +308,7 @@ void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket:: { if (!resize_window(m_focused_window, m_non_full_screen_rect.width(), m_non_full_screen_rect.height())) return; - m_focused_window->set_position({ m_non_full_screen_rect.min_x, m_non_full_screen_rect.min_y }); + move_window(m_focused_window, m_non_full_screen_rect.min_x, m_non_full_screen_rect.min_y); } const LibGUI::EventPacket::WindowFullscreenEvent event_packet { .event = { @@ -344,7 +342,7 @@ void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket:: const auto old_area = target_window->client_area(); if (!resize_window(target_window, m_framebuffer.width, m_framebuffer.height)) return; - target_window->set_position({ 0, 0 }); + move_window(target_window, 0, 0); m_non_full_screen_rect = old_area; } @@ -510,7 +508,7 @@ void WindowServer::on_key_event(LibInput::KeyEvent event) { if (!resize_window(m_focused_window, m_non_full_screen_rect.width(), m_non_full_screen_rect.height())) return; - m_focused_window->set_position({ m_non_full_screen_rect.min_x, m_non_full_screen_rect.min_y }); + move_window(m_focused_window, m_non_full_screen_rect.min_x, m_non_full_screen_rect.min_y); } m_state = State::Normal; } @@ -521,7 +519,7 @@ void WindowServer::on_key_event(LibInput::KeyEvent event) const auto old_area = m_focused_window->client_area(); if (!resize_window(m_focused_window, m_framebuffer.width, m_framebuffer.height)) return; - m_focused_window->set_position({ 0, 0 }); + move_window(m_focused_window, 0, 0); m_non_full_screen_rect = old_area; } m_state = State::Fullscreen; @@ -656,7 +654,7 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event) dwarnln("could not resize client window {}", ret.error()); return; } - m_focused_window->set_position({ resize_area.min_x, resize_area.min_y + m_focused_window->title_bar_height() }); + move_window(m_focused_window, resize_area.min_x, resize_area.min_y + m_focused_window->title_bar_height()); const LibGUI::EventPacket::ResizeWindowEvent event_packet { .width = static_cast(m_focused_window->client_width()), @@ -723,10 +721,11 @@ void WindowServer::on_mouse_move_impl(int32_t new_x, int32_t new_y) case State::Moving: { const auto old_window_area = m_focused_window->full_area(); - m_focused_window->set_position({ + move_window( + m_focused_window, m_focused_window->client_x() + event.rel_x, - m_focused_window->client_y() + event.rel_y, - }); + m_focused_window->client_y() + event.rel_y + ); add_damaged_area(old_window_area); add_damaged_area(m_focused_window->full_area()); break; @@ -1579,11 +1578,14 @@ void WindowServer::sync() { static int32_t dir_x = 7; static int32_t dir_y = 4; + auto old_window = m_focused_window->full_area(); - m_focused_window->set_position({ + + move_window( + m_focused_window, m_focused_window->client_x() + dir_x, - m_focused_window->client_y() + dir_y, - }); + m_focused_window->client_y() + dir_y + ); add_damaged_area(old_window); add_damaged_area(m_focused_window->full_area()); @@ -1717,6 +1719,19 @@ bool WindowServer::resize_window(BAN::RefPtr window, uint32_t width, uin return true; } +void WindowServer::move_window(BAN::RefPtr window, int32_t x, int32_t y) +{ + window->set_position({ x, y }); + + const LibGUI::EventPacket::WindowMoveEvent event_packet { + .event = { + .x = window->client_x(), + .y = window->client_y(), + }, + }; + (void)append_serialized_packet(event_packet, window->client_fd()); +} + BAN::ErrorOr WindowServer::add_client_fd(int fd) { TRY(m_client_data.emplace(fd)); diff --git a/userspace/programs/WindowServer/WindowServer.h b/userspace/programs/WindowServer/WindowServer.h index 94fbc774..51ef8450 100644 --- a/userspace/programs/WindowServer/WindowServer.h +++ b/userspace/programs/WindowServer/WindowServer.h @@ -71,6 +71,7 @@ private: void add_damaged_area_impl(Rectangle area); bool resize_window(BAN::RefPtr window, uint32_t width, uint32_t height); + void move_window(BAN::RefPtr window, int32_t x, int32_t y); BAN::RefPtr find_window_with_fd(int fd) const; BAN::RefPtr find_hovered_window() const;