forked from Bananymous/banan-os
LibGUI: Implement attributes for windows
Windows can now change whether they have title bar, rounded corners, alpha channel and whether they are movable. Also windows can also change their own position
This commit is contained in:
parent
d7e5c56e94
commit
d266c7f93b
|
@ -65,9 +65,6 @@ namespace LibGUI
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
BAN::Vector<uint32_t> framebuffer;
|
|
||||||
TRY(framebuffer.resize(width * height, 0xFF000000));
|
|
||||||
|
|
||||||
int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (server_fd == -1)
|
if (server_fd == -1)
|
||||||
return BAN::Error::from_errno(errno);
|
return BAN::Error::from_errno(errno);
|
||||||
|
@ -113,6 +110,11 @@ namespace LibGUI
|
||||||
void* framebuffer_addr = smo_map(create_response.smo_key);
|
void* framebuffer_addr = smo_map(create_response.smo_key);
|
||||||
if (framebuffer_addr == nullptr)
|
if (framebuffer_addr == nullptr)
|
||||||
return BAN::Error::from_errno(errno);
|
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(
|
auto window = TRY(BAN::UniqPtr<Window>::create(
|
||||||
server_fd,
|
server_fd,
|
||||||
|
@ -258,13 +260,46 @@ namespace LibGUI
|
||||||
|
|
||||||
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
||||||
{
|
{
|
||||||
dprintln("Failed to send packet: {}", ret.error().get_message());
|
dprintln("failed to invalidate window: {}", ret.error());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Window::set_position(int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
WindowPacket::WindowSetPosition packet;
|
||||||
|
packet.x = x;
|
||||||
|
packet.y = y;
|
||||||
|
|
||||||
|
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
||||||
|
{
|
||||||
|
dprintln("failed to set window position: {}", ret.error());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::set_attributes(Attributes attributes)
|
||||||
|
{
|
||||||
|
WindowPacket::WindowSetAttributes packet;
|
||||||
|
packet.title_bar = attributes.title_bar;
|
||||||
|
packet.movable = attributes.movable;
|
||||||
|
packet.rounded_corners = attributes.rounded_corners;
|
||||||
|
packet.alpha_channel = attributes.alpha_channel;
|
||||||
|
|
||||||
|
if (auto ret = packet.send_serialized(m_server_fd); ret.is_error())
|
||||||
|
{
|
||||||
|
dprintln("failed to set window attributes: {}", ret.error());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_attributes = attributes;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#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(); })
|
||||||
|
|
||||||
void Window::poll_events()
|
void Window::poll_events()
|
||||||
|
|
|
@ -160,6 +160,8 @@ namespace LibGUI
|
||||||
WindowCreate,
|
WindowCreate,
|
||||||
WindowCreateResponse,
|
WindowCreateResponse,
|
||||||
WindowInvalidate,
|
WindowInvalidate,
|
||||||
|
WindowSetPosition,
|
||||||
|
WindowSetAttributes,
|
||||||
|
|
||||||
DestroyWindowEvent,
|
DestroyWindowEvent,
|
||||||
CloseWindowEvent,
|
CloseWindowEvent,
|
||||||
|
@ -179,6 +181,8 @@ namespace LibGUI
|
||||||
);
|
);
|
||||||
|
|
||||||
DEFINE_PACKET(WindowCreateResponse,
|
DEFINE_PACKET(WindowCreateResponse,
|
||||||
|
uint32_t, width,
|
||||||
|
uint32_t, height,
|
||||||
long, smo_key
|
long, smo_key
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -189,6 +193,18 @@ namespace LibGUI
|
||||||
uint32_t, height
|
uint32_t, height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DEFINE_PACKET(WindowSetPosition,
|
||||||
|
int32_t, x,
|
||||||
|
int32_t, y
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_PACKET(WindowSetAttributes,
|
||||||
|
bool, title_bar,
|
||||||
|
bool, rounded_corners,
|
||||||
|
bool, movable,
|
||||||
|
bool, alpha_channel
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace EventPacket
|
namespace EventPacket
|
||||||
|
|
|
@ -13,6 +13,15 @@ namespace LibGUI
|
||||||
|
|
||||||
class Window
|
class Window
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
struct Attributes
|
||||||
|
{
|
||||||
|
bool title_bar { true };
|
||||||
|
bool movable { true };
|
||||||
|
bool rounded_corners { true };
|
||||||
|
bool alpha_channel { false };
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
|
@ -49,6 +58,11 @@ namespace LibGUI
|
||||||
bool invalidate(int32_t x, int32_t y, uint32_t width, uint32_t height);
|
bool invalidate(int32_t x, int32_t y, uint32_t width, uint32_t height);
|
||||||
bool invalidate() { return invalidate(0, 0, width(), height()); }
|
bool invalidate() { return invalidate(0, 0, width(), height()); }
|
||||||
|
|
||||||
|
bool set_position(int32_t x, int32_t y);
|
||||||
|
|
||||||
|
Attributes get_attributes() const { return m_attributes; }
|
||||||
|
bool 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; }
|
||||||
|
|
||||||
|
@ -75,6 +89,8 @@ namespace LibGUI
|
||||||
private:
|
private:
|
||||||
int m_server_fd;
|
int m_server_fd;
|
||||||
|
|
||||||
|
Attributes m_attributes;
|
||||||
|
|
||||||
BAN::Vector<uint32_t> m_framebuffer;
|
BAN::Vector<uint32_t> m_framebuffer;
|
||||||
uint32_t* m_framebuffer_smo;
|
uint32_t* m_framebuffer_smo;
|
||||||
uint32_t m_width;
|
uint32_t m_width;
|
||||||
|
|
|
@ -111,6 +111,11 @@ void Terminal::run()
|
||||||
m_fg_color = s_colors_bright[7];
|
m_fg_color = s_colors_bright[7];
|
||||||
|
|
||||||
m_window = MUST(LibGUI::Window::create(600, 400, "Terminal"_sv));
|
m_window = MUST(LibGUI::Window::create(600, 400, "Terminal"_sv));
|
||||||
|
|
||||||
|
auto attributes = m_window->get_attributes();
|
||||||
|
attributes.alpha_channel = true;
|
||||||
|
m_window->set_attributes(attributes);
|
||||||
|
|
||||||
m_window->fill(m_bg_color);
|
m_window->fill(m_bg_color);
|
||||||
m_window->invalidate();
|
m_window->invalidate();
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ struct Rectangle
|
||||||
|
|
||||||
BAN::Optional<Rectangle> get_overlap(Rectangle other) const
|
BAN::Optional<Rectangle> get_overlap(Rectangle other) const
|
||||||
{
|
{
|
||||||
|
if (height == 0 || width == 0 || other.width == 0 || other.height == 0)
|
||||||
|
return {};
|
||||||
const auto min_x = BAN::Math::max(x, other.x);
|
const auto min_x = BAN::Math::max(x, other.x);
|
||||||
const auto min_y = BAN::Math::max(y, other.y);
|
const auto min_y = BAN::Math::max(y, other.y);
|
||||||
const auto max_x = BAN::Math::min(x + width, other.x + other.width);
|
const auto max_x = BAN::Math::min(x + width, other.x + other.width);
|
||||||
|
|
|
@ -19,7 +19,8 @@ Window::Window(int fd, Rectangle area, long smo_key, BAN::StringView title, cons
|
||||||
|
|
||||||
m_fb_addr = static_cast<uint32_t*>(smo_map(smo_key));
|
m_fb_addr = static_cast<uint32_t*>(smo_map(smo_key));
|
||||||
ASSERT(m_fb_addr);
|
ASSERT(m_fb_addr);
|
||||||
memset(m_fb_addr, 0, client_width() * client_height() * 4);
|
|
||||||
|
memset(m_fb_addr, 0xFF, client_width() * client_height() * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::~Window()
|
Window::~Window()
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <BAN/String.h>
|
#include <BAN/String.h>
|
||||||
|
|
||||||
#include <LibFont/Font.h>
|
#include <LibFont/Font.h>
|
||||||
|
#include <LibGUI/Window.h>
|
||||||
|
|
||||||
class Window : public BAN::RefCounted<Window>
|
class Window : public BAN::RefCounted<Window>
|
||||||
{
|
{
|
||||||
|
@ -29,9 +30,9 @@ public:
|
||||||
Rectangle client_area() const { return m_client_area; }
|
Rectangle client_area() const { return m_client_area; }
|
||||||
|
|
||||||
int32_t title_bar_x() const { return client_x(); }
|
int32_t title_bar_x() const { return client_x(); }
|
||||||
int32_t title_bar_y() const { return client_y() - title_bar_height(); }
|
int32_t title_bar_y() const { return m_attributes.title_bar ? client_y() - title_bar_height() : client_y(); }
|
||||||
int32_t title_bar_width() const { return client_width(); }
|
int32_t title_bar_width() const { return client_width(); }
|
||||||
int32_t title_bar_height() const { return m_title_bar_height; }
|
int32_t title_bar_height() const { return m_attributes.title_bar ? m_title_bar_height : 0; }
|
||||||
Rectangle title_bar_size() const { return { 0, 0, title_bar_width(), title_bar_height() }; }
|
Rectangle title_bar_size() const { return { 0, 0, title_bar_width(), title_bar_height() }; }
|
||||||
Rectangle title_bar_area() const { return { title_bar_x(), title_bar_y(), title_bar_width(), title_bar_height() }; }
|
Rectangle title_bar_area() const { return { title_bar_x(), title_bar_y(), title_bar_width(), title_bar_height() }; }
|
||||||
|
|
||||||
|
@ -42,6 +43,9 @@ public:
|
||||||
Rectangle full_size() const { return { 0, 0, full_width(), full_height() }; }
|
Rectangle full_size() const { return { 0, 0, full_width(), full_height() }; }
|
||||||
Rectangle full_area() const { return { full_x(), full_y(), full_width(), full_height() }; }
|
Rectangle full_area() const { return { full_x(), full_y(), full_width(), full_height() }; }
|
||||||
|
|
||||||
|
LibGUI::Window::Attributes get_attributes() const { return m_attributes; };
|
||||||
|
void set_attributes(LibGUI::Window::Attributes attributes) { m_attributes = attributes; };
|
||||||
|
|
||||||
const uint32_t* framebuffer() const { return m_fb_addr; }
|
const uint32_t* framebuffer() const { return m_fb_addr; }
|
||||||
|
|
||||||
uint32_t title_bar_pixel(int32_t abs_x, int32_t abs_y, Position cursor) const
|
uint32_t title_bar_pixel(int32_t abs_x, int32_t abs_y, Position cursor) const
|
||||||
|
@ -72,5 +76,7 @@ private:
|
||||||
uint32_t* m_title_bar_data { nullptr };
|
uint32_t* m_title_bar_data { nullptr };
|
||||||
BAN::String m_title;
|
BAN::String m_title;
|
||||||
|
|
||||||
|
LibGUI::Window::Attributes m_attributes;
|
||||||
|
|
||||||
friend class BAN::RefPtr<Window>;
|
friend class BAN::RefPtr<Window>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@ WindowServer::WindowServer(Framebuffer& framebuffer, int32_t corner_radius)
|
||||||
BAN::ErrorOr<void> WindowServer::set_background_image(BAN::UniqPtr<LibImage::Image> image)
|
BAN::ErrorOr<void> WindowServer::set_background_image(BAN::UniqPtr<LibImage::Image> image)
|
||||||
{
|
{
|
||||||
if (image->width() != (uint64_t)m_framebuffer.width || image->height() != (uint64_t)m_framebuffer.height)
|
if (image->width() != (uint64_t)m_framebuffer.width || image->height() != (uint64_t)m_framebuffer.height)
|
||||||
image = TRY(image->resize(m_framebuffer.width, m_framebuffer.height, LibImage::Image::ResizeAlgorithm::Linear));
|
image = TRY(image->resize(m_framebuffer.width, m_framebuffer.height));
|
||||||
m_background_image = BAN::move(image);
|
m_background_image = BAN::move(image);
|
||||||
invalidate(m_framebuffer.area());
|
invalidate(m_framebuffer.area());
|
||||||
return {};
|
return {};
|
||||||
|
@ -43,7 +43,10 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t window_fb_bytes = packet.width * packet.height * 4;
|
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);
|
long smo_key = smo_create(window_fb_bytes, PROT_READ | PROT_WRITE);
|
||||||
if (smo_key == -1)
|
if (smo_key == -1)
|
||||||
|
@ -54,10 +57,10 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
|
||||||
BAN::ScopeGuard smo_deleter([smo_key] { smo_delete(smo_key); });
|
BAN::ScopeGuard smo_deleter([smo_key] { smo_delete(smo_key); });
|
||||||
|
|
||||||
Rectangle window_area {
|
Rectangle window_area {
|
||||||
static_cast<int32_t>((m_framebuffer.width - packet.width) / 2),
|
static_cast<int32_t>((m_framebuffer.width - width) / 2),
|
||||||
static_cast<int32_t>((m_framebuffer.height - packet.height) / 2),
|
static_cast<int32_t>((m_framebuffer.height - height) / 2),
|
||||||
static_cast<int32_t>(packet.width),
|
static_cast<int32_t>(width),
|
||||||
static_cast<int32_t>(packet.height)
|
static_cast<int32_t>(height)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Window::Window(int fd, Rectangle area, long smo_key, BAN::StringView title, const LibFont::Font& font)
|
// Window::Window(int fd, Rectangle area, long smo_key, BAN::StringView title, const LibFont::Font& font)
|
||||||
|
@ -83,6 +86,8 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
|
||||||
BAN::ScopeGuard window_popper([&] { m_client_windows.pop_back(); });
|
BAN::ScopeGuard window_popper([&] { m_client_windows.pop_back(); });
|
||||||
|
|
||||||
LibGUI::WindowPacket::WindowCreateResponse response;
|
LibGUI::WindowPacket::WindowCreateResponse response;
|
||||||
|
response.width = width;
|
||||||
|
response.height = height;
|
||||||
response.smo_key = smo_key;
|
response.smo_key = smo_key;
|
||||||
if (auto ret = response.send_serialized(fd); ret.is_error())
|
if (auto ret = response.send_serialized(fd); ret.is_error())
|
||||||
{
|
{
|
||||||
|
@ -132,6 +137,60 @@ void WindowServer::on_window_invalidate(int fd, const LibGUI::WindowPacket::Wind
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowServer::on_window_set_position(int fd, const LibGUI::WindowPacket::WindowSetPosition& 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 position while not owning a window");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto old_client_area = target_window->full_area();
|
||||||
|
target_window->set_position({
|
||||||
|
.x = packet.x,
|
||||||
|
.y = packet.y,
|
||||||
|
});
|
||||||
|
const auto new_client_area = target_window->full_area();
|
||||||
|
invalidate(new_client_area.get_bounding_box(old_client_area));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket::WindowSetAttributes& 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 attributes while not owning a window");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto old_client_area = target_window->full_area();
|
||||||
|
target_window->set_attributes({
|
||||||
|
.title_bar = packet.title_bar,
|
||||||
|
.movable = packet.movable,
|
||||||
|
.rounded_corners = packet.rounded_corners,
|
||||||
|
.alpha_channel = packet.alpha_channel,
|
||||||
|
});
|
||||||
|
const auto new_client_area = target_window->full_area();
|
||||||
|
invalidate(new_client_area.get_bounding_box(old_client_area));
|
||||||
|
}
|
||||||
|
|
||||||
void WindowServer::on_key_event(LibInput::KeyEvent event)
|
void WindowServer::on_key_event(LibInput::KeyEvent event)
|
||||||
{
|
{
|
||||||
// Mod key is not passed to clients
|
// Mod key is not passed to clients
|
||||||
|
@ -204,7 +263,7 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
|
||||||
// Handle window moving when mod key is held or mouse press on title bar
|
// Handle window moving when mod key is held or mouse press on title bar
|
||||||
const bool can_start_move = m_is_mod_key_held || target_window->title_text_area().contains(m_cursor);
|
const bool can_start_move = m_is_mod_key_held || target_window->title_text_area().contains(m_cursor);
|
||||||
if (event.pressed && event.button == LibInput::MouseButton::Left && !m_is_moving_window && can_start_move)
|
if (event.pressed && event.button == LibInput::MouseButton::Left && !m_is_moving_window && can_start_move)
|
||||||
m_is_moving_window = true;
|
m_is_moving_window = target_window->get_attributes().movable;
|
||||||
else if (m_is_moving_window && !event.pressed)
|
else if (m_is_moving_window && !event.pressed)
|
||||||
m_is_moving_window = false;
|
m_is_moving_window = false;
|
||||||
else if (!event.pressed && event.button == LibInput::MouseButton::Left && target_window->close_button_area().contains(m_cursor))
|
else if (!event.pressed && event.button == LibInput::MouseButton::Left && target_window->close_button_area().contains(m_cursor))
|
||||||
|
@ -354,6 +413,8 @@ void WindowServer::invalidate(Rectangle area)
|
||||||
m_framebuffer.mmap[y * m_framebuffer.width + x] = 0xFF101010;
|
m_framebuffer.mmap[y * m_framebuffer.width + x] = 0xFF101010;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: this loop should be inverse order and terminate
|
||||||
|
// after window without alpha channel is found
|
||||||
for (auto& pwindow : m_client_windows)
|
for (auto& pwindow : m_client_windows)
|
||||||
{
|
{
|
||||||
auto& window = *pwindow;
|
auto& window = *pwindow;
|
||||||
|
@ -426,8 +487,10 @@ void WindowServer::invalidate(Rectangle area)
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto is_rounded_off =
|
const auto is_rounded_off =
|
||||||
[&](Position pos) -> bool
|
[&](const Window& window, Position pos) -> bool
|
||||||
{
|
{
|
||||||
|
if (!window.get_attributes().rounded_corners)
|
||||||
|
return false;
|
||||||
for (int32_t i = 0; i < 4; i++)
|
for (int32_t i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (!corner_areas[i].contains(pos))
|
if (!corner_areas[i].contains(pos))
|
||||||
|
@ -451,7 +514,7 @@ void WindowServer::invalidate(Rectangle area)
|
||||||
{
|
{
|
||||||
const int32_t abs_x = title_overlap->x + x_off;
|
const int32_t abs_x = title_overlap->x + x_off;
|
||||||
const int32_t abs_y = title_overlap->y + y_off;
|
const int32_t abs_y = title_overlap->y + y_off;
|
||||||
if (is_rounded_off({ abs_x, abs_y }))
|
if (is_rounded_off(window, { abs_x, abs_y }))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const uint32_t color = window.title_bar_pixel(abs_x, abs_y, m_cursor);
|
const uint32_t color = window.title_bar_pixel(abs_x, abs_y, m_cursor);
|
||||||
|
@ -479,12 +542,14 @@ void WindowServer::invalidate(Rectangle area)
|
||||||
auto* window_row = &window.framebuffer()[src_row_y * window.client_width() + src_row_x];
|
auto* window_row = &window.framebuffer()[src_row_y * window.client_width() + src_row_x];
|
||||||
auto* frameb_row = &m_framebuffer.mmap[ abs_row_y * m_framebuffer.width + abs_row_x];
|
auto* frameb_row = &m_framebuffer.mmap[ abs_row_y * m_framebuffer.width + abs_row_x];
|
||||||
|
|
||||||
|
const bool should_alpha_blend = window.get_attributes().alpha_channel;
|
||||||
for (int32_t i = 0; i < fast_overlap->width; i++)
|
for (int32_t i = 0; i < fast_overlap->width; i++)
|
||||||
{
|
{
|
||||||
const uint32_t color_a = *window_row;
|
const uint32_t color_a = *window_row;
|
||||||
const uint32_t color_b = *frameb_row;
|
const uint32_t color_b = *frameb_row;
|
||||||
*frameb_row = alpha_blend(color_a, color_b);
|
*frameb_row = should_alpha_blend
|
||||||
|
? alpha_blend(color_a, color_b)
|
||||||
|
: color_a;
|
||||||
window_row++;
|
window_row++;
|
||||||
frameb_row++;
|
frameb_row++;
|
||||||
}
|
}
|
||||||
|
@ -502,7 +567,7 @@ void WindowServer::invalidate(Rectangle area)
|
||||||
{
|
{
|
||||||
const int32_t abs_x = corner_overlap->x + x_off;
|
const int32_t abs_x = corner_overlap->x + x_off;
|
||||||
const int32_t abs_y = corner_overlap->y + y_off;
|
const int32_t abs_y = corner_overlap->y + y_off;
|
||||||
if (is_rounded_off({ abs_x, abs_y }))
|
if (is_rounded_off(window, { abs_x, abs_y }))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const int32_t src_x = abs_x - window.client_x();
|
const int32_t src_x = abs_x - window.client_x();
|
||||||
|
@ -511,7 +576,10 @@ void WindowServer::invalidate(Rectangle area)
|
||||||
const uint32_t color_a = window.framebuffer()[src_y * window.client_width() + src_x];
|
const uint32_t color_a = window.framebuffer()[src_y * window.client_width() + src_x];
|
||||||
const uint32_t color_b = m_framebuffer.mmap[abs_y * m_framebuffer.width + abs_x];
|
const uint32_t color_b = m_framebuffer.mmap[abs_y * m_framebuffer.width + abs_x];
|
||||||
|
|
||||||
m_framebuffer.mmap[abs_y * m_framebuffer.width + abs_x] = alpha_blend(color_a, color_b);
|
const bool should_alpha_blend = window.get_attributes().alpha_channel;
|
||||||
|
m_framebuffer.mmap[abs_y * m_framebuffer.width + abs_x] = should_alpha_blend
|
||||||
|
? alpha_blend(color_a, color_b)
|
||||||
|
: color_a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ public:
|
||||||
|
|
||||||
void on_window_create(int fd, const LibGUI::WindowPacket::WindowCreate&);
|
void on_window_create(int fd, const LibGUI::WindowPacket::WindowCreate&);
|
||||||
void on_window_invalidate(int fd, const LibGUI::WindowPacket::WindowInvalidate&);
|
void on_window_invalidate(int fd, const LibGUI::WindowPacket::WindowInvalidate&);
|
||||||
|
void on_window_set_position(int fd, const LibGUI::WindowPacket::WindowSetPosition&);
|
||||||
|
void on_window_set_attributes(int fd, const LibGUI::WindowPacket::WindowSetAttributes&);
|
||||||
|
|
||||||
void on_key_event(LibInput::KeyEvent event);
|
void on_key_event(LibInput::KeyEvent event);
|
||||||
void on_mouse_button(LibInput::MouseButtonEvent event);
|
void on_mouse_button(LibInput::MouseButtonEvent event);
|
||||||
|
|
|
@ -335,15 +335,21 @@ int main()
|
||||||
switch (*reinterpret_cast<LibGUI::PacketType*>(client_data.packet_buffer.data()))
|
switch (*reinterpret_cast<LibGUI::PacketType*>(client_data.packet_buffer.data()))
|
||||||
{
|
{
|
||||||
case LibGUI::PacketType::WindowCreate:
|
case LibGUI::PacketType::WindowCreate:
|
||||||
{
|
|
||||||
if (auto ret = LibGUI::WindowPacket::WindowCreate::deserialize(client_data.packet_buffer.span()); !ret.is_error())
|
if (auto ret = LibGUI::WindowPacket::WindowCreate::deserialize(client_data.packet_buffer.span()); !ret.is_error())
|
||||||
window_server.on_window_create(fd, ret.release_value());
|
window_server.on_window_create(fd, ret.release_value());
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case LibGUI::PacketType::WindowInvalidate:
|
case LibGUI::PacketType::WindowInvalidate:
|
||||||
if (auto ret = LibGUI::WindowPacket::WindowInvalidate::deserialize(client_data.packet_buffer.span()); !ret.is_error())
|
if (auto ret = LibGUI::WindowPacket::WindowInvalidate::deserialize(client_data.packet_buffer.span()); !ret.is_error())
|
||||||
window_server.on_window_invalidate(fd, ret.release_value());
|
window_server.on_window_invalidate(fd, ret.release_value());
|
||||||
break;
|
break;
|
||||||
|
case LibGUI::PacketType::WindowSetPosition:
|
||||||
|
if (auto ret = LibGUI::WindowPacket::WindowSetPosition::deserialize(client_data.packet_buffer.span()); !ret.is_error())
|
||||||
|
window_server.on_window_set_position(fd, ret.release_value());
|
||||||
|
break;
|
||||||
|
case LibGUI::PacketType::WindowSetAttributes:
|
||||||
|
if (auto ret = LibGUI::WindowPacket::WindowSetAttributes::deserialize(client_data.packet_buffer.span()); !ret.is_error())
|
||||||
|
window_server.on_window_set_attributes(fd, ret.release_value());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dprintln("unhandled packet type: {}", *reinterpret_cast<uint32_t*>(client_data.packet_buffer.data()));
|
dprintln("unhandled packet type: {}", *reinterpret_cast<uint32_t*>(client_data.packet_buffer.data()));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue