LibGUI: Cleanup window initialization

This commit is contained in:
2026-07-04 08:41:58 +03:00
parent b2169cbce6
commit a2691bd70d
2 changed files with 68 additions and 23 deletions

View File

@@ -24,6 +24,12 @@ namespace LibGUI
BAN::ErrorOr<BAN::UniqPtr<Window>> Window::create(uint32_t width, uint32_t height, BAN::StringView title, Attributes attributes)
{
const auto get_current_ms = []() -> uint64_t {
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1'000 + ts.tv_nsec / 1'000'000;
};
int server_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (server_fd == -1)
return BAN::Error::from_errno(errno);
@@ -38,8 +44,7 @@ namespace LibGUI
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &epoll_event) == -1)
return BAN::Error::from_errno(errno);
timespec start_time;
clock_gettime(CLOCK_MONOTONIC, &start_time);
const uint64_t timeout_ms = get_current_ms() + 1000;
for (;;)
{
@@ -49,15 +54,14 @@ namespace LibGUI
if (connect(server_fd, (sockaddr*)&server_address, sizeof(server_address)) == 0)
break;
timespec current_time;
clock_gettime(CLOCK_MONOTONIC, &current_time);
time_t duration_s = (current_time.tv_sec - start_time.tv_sec) + (current_time.tv_nsec >= start_time.tv_nsec);
if (duration_s > 1)
const uint64_t current_ms = get_current_ms();
if (current_ms > timeout_ms)
return BAN::Error::from_errno(ETIMEDOUT);
timespec sleep_time;
sleep_time.tv_sec = 0;
sleep_time.tv_nsec = 1'000'000;
const timespec sleep_time {
.tv_sec = 0,
.tv_nsec = 1'000'000,
};
nanosleep(&sleep_time, nullptr);
}
@@ -72,21 +76,25 @@ namespace LibGUI
TRY(create_packet.title.append(title));
window->send_packet(create_packet, __FUNCTION__);
int32_t x, y;
bool resized { false }, moved { false };
window->set_resize_window_event_callback([&]() { resized = true; });
window->set_window_move_event_callback([&](auto event) { x = event.x; y = event.y; moved = true; });
while (!resized || !moved)
window->m_initializing = true;
while (window->m_initializing)
{
// FIXME: timeout?
window->wait_events();
window->poll_events();
}
window->set_resize_window_event_callback({});
window->set_window_move_event_callback({});
const uint64_t current_ms = get_current_ms();
if (current_ms > timeout_ms)
return BAN::Error::from_errno(ETIMEDOUT);
// hack to resend move event :^)
window->set_position(x, y);
const uint64_t wait_ms = timeout_ms - current_ms;
const timespec timeout {
.tv_sec = static_cast<time_t>(wait_ms / 1000),
.tv_nsec = static_cast<long>((wait_ms % 1000) * 1'000'000),
};
window->wait_events(&timeout);
window->poll_events();
if (window->m_init_failed)
return BAN::Error::from_literal("failed to initialize window");
}
server_closer.disable();
epoll_closer.disable();
@@ -361,7 +369,40 @@ namespace LibGUI
break;
const auto packet_span = in_span.slice(0, header.size);
switch (header.type)
if (m_initializing)
{
if (header.type == PacketType::ResizeWindowEvent)
{
if (auto event_or_error = EventPacket::ResizeWindowEvent::deserialize(packet_span); event_or_error.is_error())
m_init_failed = true;
else if (handle_resize_event(event_or_error.release_value()).is_error())
m_init_failed = true;
else if (m_temp_buffer.size() + m_in_buffer_size > m_in_buffer.size())
m_init_failed = true;
else
{
memmove(m_in_buffer.data() + m_temp_buffer.size(), m_in_buffer.data(), m_in_buffer.size());
memcpy(m_in_buffer.data(), m_temp_buffer.data(), m_temp_buffer.size());
m_in_buffer_size += m_temp_buffer.size();
m_temp_buffer.clear();
m_initializing = false;
}
return;
}
else if (header.type == PacketType::DestroyWindowEvent || header.type == PacketType::CloseWindowEvent)
{
m_init_failed = true;
return;
}
else
{
const size_t old_size = m_temp_buffer.size();
MUST(m_temp_buffer.resize(old_size + packet_span.size()));
memcpy(m_temp_buffer.data() + old_size, packet_span.data(), packet_span.size());
}
}
else switch (header.type)
{
#define TRY_OR_BREAK(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) break; e.release_value(); })
case PacketType::DestroyWindowEvent:

View File

@@ -105,6 +105,10 @@ namespace LibGUI
const int m_server_fd;
const int m_epoll_fd;
bool m_initializing { false };
bool m_init_failed { false };
BAN::Vector<uint8_t> m_temp_buffer;
bool m_handling_socket_error { false };
Attributes m_attributes;