WindowServer: Implement partial window resizing
This patch adds support for client side resizing, so clients can request the server to resize their windows. WindowServer will respond with resize event when and if the resizing is complete.
This commit is contained in:
parent
64c52012df
commit
d19264eea8
|
@ -59,7 +59,7 @@ namespace LibGUI
|
|||
|
||||
Window::~Window()
|
||||
{
|
||||
clear();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::UniqPtr<Window>> Window::create(uint32_t width, uint32_t height, BAN::StringView title)
|
||||
|
@ -101,27 +101,13 @@ namespace LibGUI
|
|||
TRY(create_packet.title.append(title));
|
||||
TRY(create_packet.send_serialized(server_fd));
|
||||
|
||||
const auto [response_type, response_data ] = TRY(recv_packet(server_fd));
|
||||
if (response_type != PacketType::WindowCreateResponse)
|
||||
return BAN::Error::from_literal("Server responded with invalid packet");
|
||||
auto window = TRY(BAN::UniqPtr<Window>::create(server_fd));
|
||||
|
||||
const auto create_response = TRY(WindowPacket::WindowCreateResponse::deserialize(response_data.span()));
|
||||
void* framebuffer_addr = smo_map(create_response.smo_key);
|
||||
if (framebuffer_addr == nullptr)
|
||||
return BAN::Error::from_errno(errno);
|
||||
width = create_response.width;
|
||||
height = create_response.height;
|
||||
|
||||
BAN::Vector<uint32_t> framebuffer;
|
||||
TRY(framebuffer.resize(width * height, 0xFFFFFFFF));
|
||||
|
||||
auto window = TRY(BAN::UniqPtr<Window>::create(
|
||||
server_fd,
|
||||
static_cast<uint32_t*>(framebuffer_addr),
|
||||
BAN::move(framebuffer),
|
||||
width,
|
||||
height
|
||||
));
|
||||
bool resized = false;
|
||||
window->set_resize_window_event_callback([&]() { resized = true; });
|
||||
while (!resized)
|
||||
window->poll_events();
|
||||
window->set_resize_window_event_callback({});
|
||||
|
||||
server_closer.disable();
|
||||
|
||||
|
@ -291,6 +277,16 @@ namespace LibGUI
|
|||
m_attributes = attributes;
|
||||
}
|
||||
|
||||
void Window::request_resize(uint32_t width, uint32_t height)
|
||||
{
|
||||
WindowPacket::WindowSetSize packet;
|
||||
packet.width = width;
|
||||
packet.height = height;
|
||||
|
||||
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
||||
return on_socket_error(__FUNCTION__);
|
||||
}
|
||||
|
||||
void Window::on_socket_error(BAN::StringView function)
|
||||
{
|
||||
if (m_handling_socket_error)
|
||||
|
@ -303,14 +299,42 @@ namespace LibGUI
|
|||
exit(1);
|
||||
|
||||
m_socket_error_callback();
|
||||
clear();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void Window::clear()
|
||||
void Window::cleanup()
|
||||
{
|
||||
munmap(m_framebuffer_smo, m_width * m_height * 4);
|
||||
close(m_server_fd);
|
||||
m_server_fd = -1;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Window::handle_resize_event(const EventPacket::ResizeWindowEvent& event)
|
||||
{
|
||||
if (m_framebuffer_smo)
|
||||
munmap(m_framebuffer_smo, m_width * m_height * 4);
|
||||
m_framebuffer_smo = nullptr;
|
||||
|
||||
BAN::Vector<uint32_t> framebuffer;
|
||||
TRY(framebuffer.resize(event.width * event.height, 0xFFFFFFFF));
|
||||
|
||||
void* framebuffer_addr = smo_map(event.smo_key);
|
||||
if (framebuffer_addr == nullptr)
|
||||
return BAN::Error::from_errno(errno);
|
||||
|
||||
const uint32_t min_x = BAN::Math::min(m_width, event.width);
|
||||
const uint32_t min_y = BAN::Math::min(m_height, event.height);
|
||||
for (uint32_t y = 0; y < min_y; y++)
|
||||
for (uint32_t x = 0; x < min_x; x++)
|
||||
framebuffer[y * event.width + x] = m_framebuffer[y * m_width + x];
|
||||
|
||||
m_framebuffer_smo = static_cast<uint32_t*>(framebuffer_addr);
|
||||
m_framebuffer = BAN::move(framebuffer);
|
||||
m_width = event.width;
|
||||
m_height = event.height;
|
||||
|
||||
invalidate();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
#define TRY_OR_BREAK(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) break; e.release_value(); })
|
||||
|
@ -343,6 +367,13 @@ namespace LibGUI
|
|||
else
|
||||
exit(0);
|
||||
break;
|
||||
case PacketType::ResizeWindowEvent:
|
||||
{
|
||||
MUST(handle_resize_event(TRY_OR_BREAK(EventPacket::ResizeWindowEvent::deserialize(packet_data.span()))));
|
||||
if (m_resize_window_event_callback)
|
||||
m_resize_window_event_callback();
|
||||
break;
|
||||
}
|
||||
case PacketType::KeyEvent:
|
||||
if (m_key_event_callback)
|
||||
m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_data.span())).event);
|
||||
|
|
|
@ -163,9 +163,11 @@ namespace LibGUI
|
|||
WindowSetPosition,
|
||||
WindowSetAttributes,
|
||||
WindowSetMouseCapture,
|
||||
WindowSetSize,
|
||||
|
||||
DestroyWindowEvent,
|
||||
CloseWindowEvent,
|
||||
ResizeWindowEvent,
|
||||
KeyEvent,
|
||||
MouseButtonEvent,
|
||||
MouseMoveEvent,
|
||||
|
@ -182,13 +184,6 @@ namespace LibGUI
|
|||
BAN::String, title
|
||||
);
|
||||
|
||||
DEFINE_PACKET(
|
||||
WindowCreateResponse,
|
||||
uint32_t, width,
|
||||
uint32_t, height,
|
||||
long, smo_key
|
||||
);
|
||||
|
||||
DEFINE_PACKET(
|
||||
WindowInvalidate,
|
||||
uint32_t, x,
|
||||
|
@ -220,6 +215,12 @@ namespace LibGUI
|
|||
bool, captured
|
||||
);
|
||||
|
||||
DEFINE_PACKET(
|
||||
WindowSetSize,
|
||||
uint32_t, width,
|
||||
uint32_t, height
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
namespace EventPacket
|
||||
|
@ -233,6 +234,13 @@ namespace LibGUI
|
|||
CloseWindowEvent
|
||||
);
|
||||
|
||||
DEFINE_PACKET(
|
||||
ResizeWindowEvent,
|
||||
uint32_t, width,
|
||||
uint32_t, height,
|
||||
long, smo_key
|
||||
);
|
||||
|
||||
DEFINE_PACKET_EXTRA(
|
||||
KeyEvent,
|
||||
using event_t = LibInput::KeyEvent,
|
||||
|
|
|
@ -67,12 +67,17 @@ namespace LibGUI
|
|||
Attributes get_attributes() const { return m_attributes; }
|
||||
void set_attributes(Attributes attributes);
|
||||
|
||||
// send resize request to window server
|
||||
// actual resize is only done after resize callback is called
|
||||
void request_resize(uint32_t width, uint32_t height);
|
||||
|
||||
uint32_t width() const { return m_width; }
|
||||
uint32_t height() const { return m_height; }
|
||||
|
||||
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_resize_window_event_callback(BAN::Function<void()> callback) { m_resize_window_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_move_event_callback(BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> callback) { m_mouse_move_event_callback = callback; }
|
||||
|
@ -81,33 +86,32 @@ namespace LibGUI
|
|||
int server_fd() const { return m_server_fd; }
|
||||
|
||||
private:
|
||||
Window(int server_fd, uint32_t* framebuffer_smo, BAN::Vector<uint32_t>&& framebuffer, uint32_t width, uint32_t height)
|
||||
Window(int server_fd)
|
||||
: m_server_fd(server_fd)
|
||||
, m_framebuffer(framebuffer)
|
||||
, m_framebuffer_smo(framebuffer_smo)
|
||||
, m_width(width)
|
||||
, m_height(height)
|
||||
{ }
|
||||
|
||||
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();
|
||||
void cleanup();
|
||||
|
||||
BAN::ErrorOr<void> handle_resize_event(const EventPacket::ResizeWindowEvent&);
|
||||
|
||||
private:
|
||||
int m_server_fd;
|
||||
const int m_server_fd;
|
||||
|
||||
bool m_handling_socket_error { false };
|
||||
|
||||
Attributes m_attributes;
|
||||
|
||||
BAN::Vector<uint32_t> m_framebuffer;
|
||||
uint32_t* m_framebuffer_smo;
|
||||
uint32_t m_width;
|
||||
uint32_t m_height;
|
||||
uint32_t* m_framebuffer_smo { nullptr };
|
||||
uint32_t m_width { 0 };
|
||||
uint32_t m_height { 0 };
|
||||
|
||||
BAN::Function<void()> m_socket_error_callback;
|
||||
BAN::Function<void()> m_close_window_event_callback;
|
||||
BAN::Function<void()> m_resize_window_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;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "Window.h"
|
||||
|
||||
#include <BAN/Debug.h>
|
||||
#include <BAN/ScopeGuard.h>
|
||||
|
||||
#include <LibGUI/Window.h>
|
||||
|
||||
|
@ -9,20 +10,6 @@
|
|||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
Window::Window(int fd, Rectangle area, long smo_key, BAN::StringView title, const LibFont::Font& font)
|
||||
: m_client_fd(fd)
|
||||
, m_client_area(area)
|
||||
, m_smo_key(smo_key)
|
||||
{
|
||||
MUST(m_title.append(title));
|
||||
prepare_title_bar(font);
|
||||
|
||||
m_fb_addr = static_cast<uint32_t*>(smo_map(smo_key));
|
||||
ASSERT(m_fb_addr);
|
||||
|
||||
memset(m_fb_addr, 0xFF, client_width() * client_height() * 4);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
munmap(m_fb_addr, client_width() * client_height() * 4);
|
||||
|
@ -33,40 +20,91 @@ Window::~Window()
|
|||
close(m_client_fd);
|
||||
}
|
||||
|
||||
void Window::prepare_title_bar(const LibFont::Font& font)
|
||||
BAN::ErrorOr<void> Window::initialize(BAN::StringView title, uint32_t width, uint32_t height)
|
||||
{
|
||||
const size_t title_bar_bytes = title_bar_width() * title_bar_height() * 4;
|
||||
uint32_t* title_bar_data = new uint32_t[title_bar_bytes];
|
||||
ASSERT(title_bar_data);
|
||||
for (size_t i = 0; i < title_bar_bytes; i++)
|
||||
title_bar_data[i] = 0xFFFFFFFF;
|
||||
m_title.clear();
|
||||
TRY(m_title.append(title));
|
||||
TRY(resize(width, height));
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Window::resize(uint32_t width, uint32_t height)
|
||||
{
|
||||
const size_t fb_bytes = width * height * 4;
|
||||
|
||||
long smo_key = smo_create(fb_bytes, PROT_READ | PROT_WRITE);
|
||||
if (smo_key == -1)
|
||||
return BAN::Error::from_errno(errno);
|
||||
BAN::ScopeGuard smo_deleter([&]() { smo_delete(smo_key); });
|
||||
|
||||
uint32_t* fb_addr = static_cast<uint32_t*>(smo_map(smo_key));
|
||||
if (fb_addr == nullptr)
|
||||
return BAN::Error::from_errno(errno);
|
||||
memset(fb_addr, 0xFF, fb_bytes);
|
||||
BAN::ScopeGuard smo_unmapper([&]() { munmap(fb_addr, fb_bytes); });
|
||||
|
||||
{
|
||||
const auto old_area = m_client_area;
|
||||
|
||||
m_client_area.width = width;
|
||||
m_client_area.height = height;
|
||||
auto title_bar_ret = prepare_title_bar();
|
||||
m_client_area = old_area;
|
||||
|
||||
if (title_bar_ret.is_error())
|
||||
return title_bar_ret.release_error();
|
||||
}
|
||||
|
||||
smo_deleter.disable();
|
||||
smo_unmapper.disable();
|
||||
|
||||
if (m_fb_addr)
|
||||
munmap(m_fb_addr, client_width() * client_height() * 4);
|
||||
if (m_smo_key)
|
||||
smo_delete(m_smo_key);
|
||||
|
||||
m_fb_addr = fb_addr;
|
||||
m_smo_key = smo_key;
|
||||
m_client_area.width = width;
|
||||
m_client_area.height = height;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Window::prepare_title_bar()
|
||||
{
|
||||
const uint32_t font_w = m_font.width();
|
||||
const uint32_t font_h = m_font.height();
|
||||
const uint32_t font_p = m_font.pitch();
|
||||
|
||||
TRY(m_title_bar_data.resize(title_bar_width() * title_bar_height()));
|
||||
for (auto& pixel : m_title_bar_data)
|
||||
pixel = 0xFFFFFFFF;
|
||||
|
||||
const auto text_area = title_text_area();
|
||||
|
||||
for (size_t i = 0; i < m_title.size() && (i + 1) * font.width() < static_cast<uint32_t>(text_area.width); i++)
|
||||
for (size_t i = 0; i < m_title.size() && (i + 1) * font_w < static_cast<uint32_t>(text_area.width); i++)
|
||||
{
|
||||
const auto* glyph = font.glyph(m_title[i]);
|
||||
const auto* glyph = m_font.glyph(m_title[i]);
|
||||
if (glyph == nullptr)
|
||||
continue;
|
||||
|
||||
const int32_t y_off = (font.height() < (uint32_t)title_bar_height()) ? (title_bar_height() - font.height()) / 2 : 0;
|
||||
const int32_t x_off = y_off + i * font.width();
|
||||
for (int32_t y = 0; (uint32_t)y < font.height(); y++)
|
||||
const int32_t y_off = (font_h < (uint32_t)title_bar_height()) ? (title_bar_height() - font_h) / 2 : 0;
|
||||
const int32_t x_off = y_off + i * font_w;
|
||||
for (int32_t y = 0; (uint32_t)y < font_h; y++)
|
||||
{
|
||||
if (y + y_off >= title_bar_height())
|
||||
break;
|
||||
for (int32_t x = 0; (uint32_t)x < font.width(); x++)
|
||||
for (int32_t x = 0; (uint32_t)x < font_w; x++)
|
||||
{
|
||||
if (x + x_off >= text_area.width)
|
||||
break;
|
||||
const uint8_t bitmask = 1 << (font.width() - x - 1);
|
||||
if (glyph[y * font.pitch()] & bitmask)
|
||||
title_bar_data[(y_off + y) * title_bar_width() + (x_off + x)] = 0xFF000000;
|
||||
const uint8_t bitmask = 1 << (font_w - x - 1);
|
||||
if (glyph[y * font_p] & bitmask)
|
||||
m_title_bar_data[(y_off + y) * title_bar_width() + (x_off + x)] = 0xFF000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_title_bar_data)
|
||||
delete[] m_title_bar_data;
|
||||
m_title_bar_data = title_bar_data;
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <BAN/RefPtr.h>
|
||||
#include <BAN/String.h>
|
||||
#include <BAN/Vector.h>
|
||||
|
||||
#include <LibFont/Font.h>
|
||||
#include <LibGUI/Window.h>
|
||||
|
@ -11,7 +12,11 @@
|
|||
class Window : public BAN::RefCounted<Window>
|
||||
{
|
||||
public:
|
||||
Window(int fd, Rectangle area, long smo_key, BAN::StringView title, const LibFont::Font& font);
|
||||
Window(int fd, const LibFont::Font& font)
|
||||
: m_font(font)
|
||||
, m_client_fd(fd)
|
||||
{ }
|
||||
|
||||
~Window();
|
||||
|
||||
void set_position(Position position)
|
||||
|
@ -21,6 +26,7 @@ public:
|
|||
}
|
||||
|
||||
int client_fd() const { return m_client_fd; }
|
||||
long smo_key() const { return m_smo_key; }
|
||||
|
||||
int32_t client_x() const { return m_client_area.x; }
|
||||
int32_t client_y() const { return m_client_area.y; }
|
||||
|
@ -63,19 +69,25 @@ public:
|
|||
Circle close_button_area() const { return { title_bar_x() + title_bar_width() - title_bar_height() / 2, title_bar_y() + title_bar_height() / 2, title_bar_height() * 3 / 8 }; }
|
||||
Rectangle title_text_area() const { return { title_bar_x(), title_bar_y(), title_bar_width() - title_bar_height(), title_bar_height() }; }
|
||||
|
||||
BAN::ErrorOr<void> initialize(BAN::StringView title, uint32_t width, uint32_t height);
|
||||
BAN::ErrorOr<void> resize(uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
void prepare_title_bar(const LibFont::Font& font);
|
||||
BAN::ErrorOr<void> prepare_title_bar();
|
||||
|
||||
private:
|
||||
static constexpr int32_t m_title_bar_height { 20 };
|
||||
|
||||
const LibFont::Font& m_font;
|
||||
|
||||
const int m_client_fd { -1 };
|
||||
Rectangle m_client_area { 0, 0, 0, 0 };
|
||||
long m_smo_key { 0 };
|
||||
uint32_t* m_fb_addr { nullptr };
|
||||
uint32_t* m_title_bar_data { nullptr };
|
||||
BAN::String m_title;
|
||||
|
||||
BAN::Vector<uint32_t> m_title_bar_data;
|
||||
|
||||
LibGUI::Window::Attributes m_attributes { LibGUI::Window::default_attributes };
|
||||
|
||||
friend class BAN::RefPtr<Window>;
|
||||
|
|
|
@ -43,34 +43,10 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
|
|||
return;
|
||||
}
|
||||
|
||||
const uint32_t width = packet.width ? packet.width : m_framebuffer.width;
|
||||
const uint32_t width = packet.width ? packet.width : m_framebuffer.width;
|
||||
const uint32_t height = packet.height ? packet.height : m_framebuffer.height;
|
||||
|
||||
const size_t window_fb_bytes = width * height * 4;
|
||||
|
||||
long smo_key = smo_create(window_fb_bytes, PROT_READ | PROT_WRITE);
|
||||
if (smo_key == -1)
|
||||
{
|
||||
dwarnln("smo_create: {}", strerror(errno));
|
||||
return;
|
||||
}
|
||||
BAN::ScopeGuard smo_deleter([smo_key] { smo_delete(smo_key); });
|
||||
|
||||
Rectangle window_area {
|
||||
static_cast<int32_t>((m_framebuffer.width - width) / 2),
|
||||
static_cast<int32_t>((m_framebuffer.height - height) / 2),
|
||||
static_cast<int32_t>(width),
|
||||
static_cast<int32_t>(height)
|
||||
};
|
||||
|
||||
// Window::Window(int fd, Rectangle area, long smo_key, BAN::StringView title, const LibFont::Font& font)
|
||||
auto window_or_error = (BAN::RefPtr<Window>::create(
|
||||
fd,
|
||||
window_area,
|
||||
smo_key,
|
||||
packet.title,
|
||||
m_font
|
||||
));
|
||||
auto window_or_error = BAN::RefPtr<Window>::create(fd, m_font);
|
||||
if (window_or_error.is_error())
|
||||
{
|
||||
dwarnln("could not create window for client: {}", window_or_error.error());
|
||||
|
@ -85,17 +61,27 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
|
|||
}
|
||||
BAN::ScopeGuard window_popper([&] { m_client_windows.pop_back(); });
|
||||
|
||||
LibGUI::WindowPacket::WindowCreateResponse response;
|
||||
response.width = width;
|
||||
response.height = height;
|
||||
response.smo_key = smo_key;
|
||||
if (auto ret = window->initialize(packet.title, width, height); ret.is_error())
|
||||
{
|
||||
dwarnln("could not create window for client: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
||||
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),
|
||||
});
|
||||
|
||||
LibGUI::EventPacket::ResizeWindowEvent response;
|
||||
response.width = window->client_width();
|
||||
response.height = window->client_height();
|
||||
response.smo_key = window->smo_key();
|
||||
if (auto ret = response.send_serialized(fd); ret.is_error())
|
||||
{
|
||||
dwarnln("could not respond to window create request: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
||||
smo_deleter.disable();
|
||||
window_popper.disable();
|
||||
|
||||
set_focused_window(window);
|
||||
|
@ -232,6 +218,47 @@ void WindowServer::on_window_set_mouse_capture(int fd, const LibGUI::WindowPacke
|
|||
invalidate(cursor_area());
|
||||
}
|
||||
|
||||
void WindowServer::on_window_set_size(int fd, const LibGUI::WindowPacket::WindowSetSize& packet)
|
||||
{
|
||||
BAN::RefPtr<Window> target_window;
|
||||
for (auto& window : m_client_windows)
|
||||
{
|
||||
if (window->client_fd() != fd)
|
||||
continue;
|
||||
target_window = window;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!target_window)
|
||||
{
|
||||
dwarnln("client tried to set window size while not owning a window");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto old_area = target_window->full_area();
|
||||
|
||||
const uint32_t width = packet.width ? packet.width : m_framebuffer.width;
|
||||
const uint32_t height = packet.height ? packet.height : m_framebuffer.height;
|
||||
|
||||
if (auto ret = target_window->resize(width, height); ret.is_error())
|
||||
{
|
||||
dwarnln("could not resize client window {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
||||
LibGUI::EventPacket::ResizeWindowEvent response;
|
||||
response.width = target_window->client_width();
|
||||
response.height = target_window->client_height();
|
||||
response.smo_key = target_window->smo_key();
|
||||
if (auto ret = response.send_serialized(fd); ret.is_error())
|
||||
{
|
||||
dwarnln("could not respond to window resize request: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
||||
invalidate(target_window->full_area().get_bounding_box(old_area));
|
||||
}
|
||||
|
||||
void WindowServer::on_key_event(LibInput::KeyEvent event)
|
||||
{
|
||||
// Mod key is not passed to clients
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
void on_window_set_position(int fd, const LibGUI::WindowPacket::WindowSetPosition&);
|
||||
void on_window_set_attributes(int fd, const LibGUI::WindowPacket::WindowSetAttributes&);
|
||||
void on_window_set_mouse_capture(int fd, const LibGUI::WindowPacket::WindowSetMouseCapture&);
|
||||
void on_window_set_size(int fd, const LibGUI::WindowPacket::WindowSetSize&);
|
||||
|
||||
void on_key_event(LibInput::KeyEvent event);
|
||||
void on_mouse_button(LibInput::MouseButtonEvent event);
|
||||
|
|
|
@ -354,6 +354,10 @@ int main()
|
|||
if (auto ret = LibGUI::WindowPacket::WindowSetMouseCapture::deserialize(client_data.packet_buffer.span()); !ret.is_error())
|
||||
window_server.on_window_set_mouse_capture(fd, ret.release_value());
|
||||
break;
|
||||
case LibGUI::PacketType::WindowSetSize:
|
||||
if (auto ret = LibGUI::WindowPacket::WindowSetSize::deserialize(client_data.packet_buffer.span()); !ret.is_error())
|
||||
window_server.on_window_set_size(fd, ret.release_value());
|
||||
break;
|
||||
default:
|
||||
dprintln("unhandled packet type: {}", *reinterpret_cast<uint32_t*>(client_data.packet_buffer.data()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue