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));
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);

View File

@@ -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,

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_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_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; }
@@ -118,6 +119,7 @@ namespace LibGUI
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::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::MouseButtonEvent::event_t)> m_mouse_button_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_position({
static_cast<int32_t>((m_framebuffer.width - window->client_width()) / 2),
static_cast<int32_t>((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<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();
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<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:
{
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> window, uint32_t width, uin
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)
{
TRY(m_client_data.emplace(fd));

View File

@@ -71,6 +71,7 @@ private:
void add_damaged_area_impl(Rectangle area);
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_hovered_window() const;