LibGUI/WindowServer: Send window move events

This commit is contained in:
2026-06-23 20:52:12 +03:00
parent 8bc93069be
commit 4ad586552d
5 changed files with 60 additions and 22 deletions

View File

@@ -70,15 +70,21 @@ namespace LibGUI
TRY(create_packet.title.append(title)); TRY(create_packet.title.append(title));
window->send_packet(create_packet, __FUNCTION__); 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; }); 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? // FIXME: timeout?
window->wait_events(); window->wait_events();
window->poll_events(); window->poll_events();
} }
window->set_resize_window_event_callback({}); 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(); server_closer.disable();
epoll_closer.disable(); epoll_closer.disable();
@@ -365,6 +371,10 @@ namespace LibGUI
if (m_window_fullscreen_event_callback) if (m_window_fullscreen_event_callback)
m_window_fullscreen_event_callback(TRY_OR_BREAK(EventPacket::WindowFullscreenEvent::deserialize(packet_span)).event); m_window_fullscreen_event_callback(TRY_OR_BREAK(EventPacket::WindowFullscreenEvent::deserialize(packet_span)).event);
break; 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: case PacketType::KeyEvent:
if (m_key_event_callback) if (m_key_event_callback)
m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_span)).event); m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_span)).event);

View File

@@ -206,6 +206,7 @@ namespace LibGUI
WindowShownEvent, WindowShownEvent,
WindowFocusEvent, WindowFocusEvent,
WindowFullscreenEvent, WindowFullscreenEvent,
WindowMoveEvent,
KeyEvent, KeyEvent,
MouseButtonEvent, MouseButtonEvent,
MouseMoveEvent, MouseMoveEvent,
@@ -346,6 +347,15 @@ namespace LibGUI
event_t, event event_t, event
); );
DEFINE_PACKET_EXTRA(
WindowMoveEvent,
struct event_t {
int32_t x;
int32_t y;
},
event_t, event
);
DEFINE_PACKET_EXTRA( DEFINE_PACKET_EXTRA(
KeyEvent, KeyEvent,
using event_t = LibInput::KeyEvent, using event_t = LibInput::KeyEvent,

View File

@@ -79,6 +79,7 @@ namespace LibGUI
void set_window_shown_event_callback(BAN::Function<void(EventPacket::WindowShownEvent::event_t)> callback) { m_window_shown_event_callback = callback; } void set_window_shown_event_callback(BAN::Function<void(EventPacket::WindowShownEvent::event_t)> callback) { m_window_shown_event_callback = callback; }
void set_window_focus_event_callback(BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> callback) { m_window_focus_event_callback = callback; } void set_window_focus_event_callback(BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> callback) { m_window_focus_event_callback = callback; }
void set_window_fullscreen_event_callback(BAN::Function<void(EventPacket::WindowFullscreenEvent::event_t)> callback) { m_window_fullscreen_event_callback = callback; } void set_window_fullscreen_event_callback(BAN::Function<void(EventPacket::WindowFullscreenEvent::event_t)> callback) { m_window_fullscreen_event_callback = callback; }
void set_window_move_event_callback(BAN::Function<void(EventPacket::WindowMoveEvent::event_t)> callback) { m_window_move_event_callback = callback; }
int server_fd() const { return m_server_fd; } int server_fd() const { return m_server_fd; }
@@ -118,6 +119,7 @@ namespace LibGUI
BAN::Function<void(EventPacket::WindowShownEvent::event_t)> m_window_shown_event_callback; BAN::Function<void(EventPacket::WindowShownEvent::event_t)> m_window_shown_event_callback;
BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> m_window_focus_event_callback; BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> m_window_focus_event_callback;
BAN::Function<void(EventPacket::WindowFullscreenEvent::event_t)> m_window_fullscreen_event_callback; BAN::Function<void(EventPacket::WindowFullscreenEvent::event_t)> m_window_fullscreen_event_callback;
BAN::Function<void(EventPacket::WindowMoveEvent::event_t)> m_window_move_event_callback;
BAN::Function<void(EventPacket::KeyEvent::event_t)> m_key_event_callback; BAN::Function<void(EventPacket::KeyEvent::event_t)> m_key_event_callback;
BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> m_mouse_button_event_callback; BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> m_mouse_button_event_callback;
BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> m_mouse_move_event_callback; BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> m_mouse_move_event_callback;

View File

@@ -75,10 +75,11 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
} }
window->set_attributes(packet.attributes); window->set_attributes(packet.attributes);
window->set_position({ move_window(
static_cast<int32_t>((m_framebuffer.width - window->client_width()) / 2), window,
static_cast<int32_t>((m_framebuffer.height - window->client_height()) / 2), (m_framebuffer.width - window->client_width()) / 2,
}); (m_framebuffer.height - window->client_height()) / 2
);
const LibGUI::EventPacket::ResizeWindowEvent event_packet { const LibGUI::EventPacket::ResizeWindowEvent event_packet {
.width = static_cast<uint32_t>(window->client_width()), .width = static_cast<uint32_t>(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(); const auto old_client_area = target_window->full_area();
target_window->set_position({ move_window(target_window, packet.x, packet.y);
.x = packet.x,
.y = packet.y,
});
if (!target_window->get_attributes().shown) if (!target_window->get_attributes().shown)
return; 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())) if (!resize_window(m_focused_window, m_non_full_screen_rect.width(), m_non_full_screen_rect.height()))
return; 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; 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())) if (!resize_window(m_focused_window, m_non_full_screen_rect.width(), m_non_full_screen_rect.height()))
return; 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 = { 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(); const auto old_area = target_window->client_area();
if (!resize_window(target_window, m_framebuffer.width, m_framebuffer.height)) if (!resize_window(target_window, m_framebuffer.width, m_framebuffer.height))
return; return;
target_window->set_position({ 0, 0 }); move_window(target_window, 0, 0);
m_non_full_screen_rect = old_area; 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())) if (!resize_window(m_focused_window, m_non_full_screen_rect.width(), m_non_full_screen_rect.height()))
return; 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; 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(); const auto old_area = m_focused_window->client_area();
if (!resize_window(m_focused_window, m_framebuffer.width, m_framebuffer.height)) if (!resize_window(m_focused_window, m_framebuffer.width, m_framebuffer.height))
return; return;
m_focused_window->set_position({ 0, 0 }); move_window(m_focused_window, 0, 0);
m_non_full_screen_rect = old_area; m_non_full_screen_rect = old_area;
} }
m_state = State::Fullscreen; m_state = State::Fullscreen;
@@ -656,7 +654,7 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
dwarnln("could not resize client window {}", ret.error()); dwarnln("could not resize client window {}", ret.error());
return; 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 { const LibGUI::EventPacket::ResizeWindowEvent event_packet {
.width = static_cast<uint32_t>(m_focused_window->client_width()), .width = static_cast<uint32_t>(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: case State::Moving:
{ {
const auto old_window_area = m_focused_window->full_area(); 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_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(old_window_area);
add_damaged_area(m_focused_window->full_area()); add_damaged_area(m_focused_window->full_area());
break; break;
@@ -1579,11 +1578,14 @@ void WindowServer::sync()
{ {
static int32_t dir_x = 7; static int32_t dir_x = 7;
static int32_t dir_y = 4; static int32_t dir_y = 4;
auto old_window = m_focused_window->full_area(); 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_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(old_window);
add_damaged_area(m_focused_window->full_area()); add_damaged_area(m_focused_window->full_area());
@@ -1717,6 +1719,19 @@ bool WindowServer::resize_window(BAN::RefPtr<Window> window, uint32_t width, uin
return true; return true;
} }
void WindowServer::move_window(BAN::RefPtr<Window> 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<void> WindowServer::add_client_fd(int fd) BAN::ErrorOr<void> WindowServer::add_client_fd(int fd)
{ {
TRY(m_client_data.emplace(fd)); TRY(m_client_data.emplace(fd));

View File

@@ -71,6 +71,7 @@ private:
void add_damaged_area_impl(Rectangle area); void add_damaged_area_impl(Rectangle area);
bool resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height); bool resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height);
void move_window(BAN::RefPtr<Window> window, int32_t x, int32_t y);
BAN::RefPtr<Window> find_window_with_fd(int fd) const; BAN::RefPtr<Window> find_window_with_fd(int fd) const;
BAN::RefPtr<Window> find_hovered_window() const; BAN::RefPtr<Window> find_hovered_window() const;