LibGUI: Client window now exits if it loses connection from server
This can be prevented by installing callback for socket errors.
This commit is contained in:
parent
cf21eb4b39
commit
6bd51ac345
|
@ -59,8 +59,7 @@ namespace LibGUI
|
||||||
|
|
||||||
Window::~Window()
|
Window::~Window()
|
||||||
{
|
{
|
||||||
munmap(m_framebuffer_smo, m_width * m_height * 4);
|
clear();
|
||||||
close(m_server_fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::UniqPtr<Window>> Window::create(uint32_t width, uint32_t height, BAN::StringView title)
|
BAN::ErrorOr<BAN::UniqPtr<Window>> Window::create(uint32_t width, uint32_t height, BAN::StringView title)
|
||||||
|
@ -244,10 +243,10 @@ namespace LibGUI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::invalidate(int32_t x, int32_t y, uint32_t width, uint32_t height)
|
void Window::invalidate(int32_t x, int32_t y, uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
if (!clamp_to_framebuffer(x, y, width, height))
|
if (!clamp_to_framebuffer(x, y, width, height))
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < height; i++)
|
for (uint32_t i = 0; i < height; i++)
|
||||||
memcpy(&m_framebuffer_smo[(y + i) * m_width + x], &m_framebuffer[(y + i) * m_width + x], width * sizeof(uint32_t));
|
memcpy(&m_framebuffer_smo[(y + i) * m_width + x], &m_framebuffer[(y + i) * m_width + x], width * sizeof(uint32_t));
|
||||||
|
@ -259,56 +258,59 @@ namespace LibGUI
|
||||||
packet.height = height;
|
packet.height = height;
|
||||||
|
|
||||||
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
||||||
{
|
return on_socket_error(__FUNCTION__);
|
||||||
dprintln("failed to invalidate window: {}", ret.error());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::set_mouse_capture(bool captured)
|
void Window::set_mouse_capture(bool captured)
|
||||||
{
|
{
|
||||||
WindowPacket::WindowSetMouseCapture packet;
|
WindowPacket::WindowSetMouseCapture packet;
|
||||||
packet.captured = captured;
|
packet.captured = captured;
|
||||||
|
|
||||||
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
||||||
{
|
return on_socket_error(__FUNCTION__);
|
||||||
dprintln("failed to set mouse capture: {}", ret.error());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::set_position(int32_t x, int32_t y)
|
void Window::set_position(int32_t x, int32_t y)
|
||||||
{
|
{
|
||||||
WindowPacket::WindowSetPosition packet;
|
WindowPacket::WindowSetPosition packet;
|
||||||
packet.x = x;
|
packet.x = x;
|
||||||
packet.y = y;
|
packet.y = y;
|
||||||
|
|
||||||
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
||||||
{
|
return on_socket_error(__FUNCTION__);
|
||||||
dprintln("failed to set window position: {}", ret.error());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::set_attributes(Attributes attributes)
|
void Window::set_attributes(Attributes attributes)
|
||||||
{
|
{
|
||||||
WindowPacket::WindowSetAttributes packet;
|
WindowPacket::WindowSetAttributes packet;
|
||||||
packet.attributes = attributes;
|
packet.attributes = attributes;
|
||||||
|
|
||||||
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
||||||
{
|
return on_socket_error(__FUNCTION__);
|
||||||
dprintln("failed to set window attributes: {}", ret.error());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_attributes = attributes;
|
m_attributes = attributes;
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
void Window::on_socket_error(BAN::StringView function)
|
||||||
|
{
|
||||||
|
if (m_handling_socket_error)
|
||||||
|
return;
|
||||||
|
m_handling_socket_error = true;
|
||||||
|
|
||||||
|
dprintln("Socket error while running Window::{}", function);
|
||||||
|
|
||||||
|
if (!m_socket_error_callback)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
m_socket_error_callback();
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::clear()
|
||||||
|
{
|
||||||
|
munmap(m_framebuffer_smo, m_width * m_height * 4);
|
||||||
|
close(m_server_fd);
|
||||||
|
m_server_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TRY_OR_BREAK(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) break; e.release_value(); })
|
#define TRY_OR_BREAK(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) break; e.release_value(); })
|
||||||
|
@ -328,7 +330,7 @@ namespace LibGUI
|
||||||
|
|
||||||
auto packet_or_error = recv_packet(m_server_fd);
|
auto packet_or_error = recv_packet(m_server_fd);
|
||||||
if (packet_or_error.is_error())
|
if (packet_or_error.is_error())
|
||||||
break;
|
return on_socket_error(__FUNCTION__);
|
||||||
|
|
||||||
const auto [packet_type, packet_data] = packet_or_error.release_value();
|
const auto [packet_type, packet_data] = packet_or_error.release_value();
|
||||||
switch (packet_type)
|
switch (packet_type)
|
||||||
|
|
|
@ -57,20 +57,21 @@ namespace LibGUI
|
||||||
// fill_color is used when copying data outside of window bounds
|
// fill_color is used when copying data outside of window bounds
|
||||||
void copy_horizontal_slice(int32_t dst_y, int32_t src_y, uint32_t amount, uint32_t fill_color);
|
void copy_horizontal_slice(int32_t dst_y, int32_t src_y, uint32_t amount, uint32_t fill_color);
|
||||||
|
|
||||||
bool invalidate(int32_t x, int32_t y, uint32_t width, uint32_t height);
|
void invalidate(int32_t x, int32_t y, uint32_t width, uint32_t height);
|
||||||
bool invalidate() { return invalidate(0, 0, width(), height()); }
|
void invalidate() { return invalidate(0, 0, width(), height()); }
|
||||||
|
|
||||||
bool set_mouse_capture(bool captured);
|
void set_mouse_capture(bool captured);
|
||||||
|
|
||||||
bool set_position(int32_t x, int32_t y);
|
void set_position(int32_t x, int32_t y);
|
||||||
|
|
||||||
Attributes get_attributes() const { return m_attributes; }
|
Attributes get_attributes() const { return m_attributes; }
|
||||||
bool set_attributes(Attributes attributes);
|
void set_attributes(Attributes attributes);
|
||||||
|
|
||||||
uint32_t width() const { return m_width; }
|
uint32_t width() const { return m_width; }
|
||||||
uint32_t height() const { return m_height; }
|
uint32_t height() const { return m_height; }
|
||||||
|
|
||||||
void poll_events();
|
void poll_events();
|
||||||
|
void set_socket_error_callback(BAN::Function<void()> callback) { m_socket_error_callback = callback; }
|
||||||
void set_close_window_event_callback(BAN::Function<void()> callback) { m_close_window_event_callback = callback; }
|
void set_close_window_event_callback(BAN::Function<void()> callback) { m_close_window_event_callback = callback; }
|
||||||
void set_key_event_callback(BAN::Function<void(EventPacket::KeyEvent::event_t)> callback) { m_key_event_callback = callback; }
|
void set_key_event_callback(BAN::Function<void(EventPacket::KeyEvent::event_t)> callback) { m_key_event_callback = callback; }
|
||||||
void set_mouse_button_event_callback(BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> callback) { m_mouse_button_event_callback = callback; }
|
void set_mouse_button_event_callback(BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> callback) { m_mouse_button_event_callback = callback; }
|
||||||
|
@ -90,9 +91,14 @@ namespace LibGUI
|
||||||
|
|
||||||
bool clamp_to_framebuffer(int32_t& x, int32_t& y, uint32_t& width, uint32_t& height) const;
|
bool clamp_to_framebuffer(int32_t& x, int32_t& y, uint32_t& width, uint32_t& height) const;
|
||||||
|
|
||||||
|
void on_socket_error(BAN::StringView function);
|
||||||
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_server_fd;
|
int m_server_fd;
|
||||||
|
|
||||||
|
bool m_handling_socket_error { false };
|
||||||
|
|
||||||
Attributes m_attributes;
|
Attributes m_attributes;
|
||||||
|
|
||||||
BAN::Vector<uint32_t> m_framebuffer;
|
BAN::Vector<uint32_t> m_framebuffer;
|
||||||
|
@ -100,6 +106,7 @@ namespace LibGUI
|
||||||
uint32_t m_width;
|
uint32_t m_width;
|
||||||
uint32_t m_height;
|
uint32_t m_height;
|
||||||
|
|
||||||
|
BAN::Function<void()> m_socket_error_callback;
|
||||||
BAN::Function<void()> m_close_window_event_callback;
|
BAN::Function<void()> m_close_window_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;
|
||||||
|
|
|
@ -53,8 +53,7 @@ int main()
|
||||||
|
|
||||||
window->fill_rect(text_x, text_y, text_w, text_h, bg_color);
|
window->fill_rect(text_x, text_y, text_w, text_h, bg_color);
|
||||||
window->draw_text(text, font, text_x, text_y, fg_color);
|
window->draw_text(text, font, text_x, text_y, fg_color);
|
||||||
if (!window->invalidate(text_x, text_y, text_w, text_h))
|
window->invalidate(text_x, text_y, text_w, text_h);
|
||||||
is_running = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
while (is_running)
|
while (is_running)
|
||||||
|
|
Loading…
Reference in New Issue