Files
banan-os/userspace/programs/WindowServer/WindowServer.h
Bananymous 2b97587e9f WindowServer: Rewrite damaged region tracking
Instead of immediately doing rerender of client data and syncing 60 Hz,
we now only keep track of the damaged regions and also do the rerender
step 60 Hz.
2026-04-11 08:26:22 +03:00

122 lines
3.5 KiB
C++

#pragma once
#include "Framebuffer.h"
#include "Window.h"
#include <BAN/Array.h>
#include <BAN/Function.h>
#include <BAN/Iteration.h>
#include <BAN/Vector.h>
#include <BAN/HashMap.h>
#include <LibFont/Font.h>
#include <LibGUI/Window.h>
#include <LibImage/Image.h>
#include <LibInput/KeyEvent.h>
#include <LibInput/MouseEvent.h>
class WindowServer
{
public:
struct ClientData
{
size_t in_buffer_size { 0 };
BAN::Array<uint8_t, 64 * 1024> in_buffer;
size_t out_buffer_size { 0 };
BAN::Array<uint8_t, 64 * 1024> out_buffer;
};
public:
WindowServer(Framebuffer& framebuffer, int32_t corner_radius);
BAN::ErrorOr<void> set_background_image(BAN::UniqPtr<LibImage::Image>);
void on_window_create(int fd, const LibGUI::WindowPacket::WindowCreate&);
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_window_set_mouse_relative(int fd, const LibGUI::WindowPacket::WindowSetMouseRelative&);
void on_window_set_size(int fd, const LibGUI::WindowPacket::WindowSetSize&);
void on_window_set_min_size(int fd, const LibGUI::WindowPacket::WindowSetMinSize&);
void on_window_set_max_size(int fd, const LibGUI::WindowPacket::WindowSetMaxSize&);
void on_window_set_fullscreen(int fd, const LibGUI::WindowPacket::WindowSetFullscreen&);
void on_window_set_title(int fd, const LibGUI::WindowPacket::WindowSetTitle&);
void on_window_set_cursor(int fd, const LibGUI::WindowPacket::WindowSetCursor&);
void on_key_event(LibInput::KeyEvent event);
void on_mouse_button(LibInput::MouseButtonEvent event);
void on_mouse_move(LibInput::MouseMoveEvent event);
void on_mouse_move_abs(LibInput::MouseMoveAbsEvent event);
void on_mouse_scroll(LibInput::MouseScrollEvent event);
void set_focused_window(BAN::RefPtr<Window> window);
void invalidate(Rectangle area);
void sync();
Rectangle cursor_area() const;
Rectangle resize_area(Position cursor) const;
BAN::ErrorOr<void> add_client_fd(int fd);
void remove_client_fd(int fd);
ClientData& get_client_data(int fd);
bool is_stopped() const { return m_is_stopped; }
private:
void on_mouse_move_impl(int32_t new_x, int32_t new_y);
void merge_damaged_areas();
void add_damaged_area(Rectangle area);
void add_damaged_area_impl(Rectangle area);
bool resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height);
BAN::RefPtr<Window> find_window_with_fd(int fd) const;
BAN::RefPtr<Window> find_hovered_window() const;
template<typename T>
BAN::ErrorOr<void> append_serialized_packet(const T& packet, int fd);
private:
enum class State
{
Normal,
Fullscreen,
Moving,
Resizing,
};
private:
Framebuffer& m_framebuffer;
BAN::Vector<BAN::RefPtr<Window>> m_client_windows;
BAN::HashMap<int, ClientData> m_client_data;
const int32_t m_corner_radius;
static constexpr size_t m_max_damaged_areas = 32;
size_t m_damaged_area_count { 0 };
BAN::Array<Rectangle, m_max_damaged_areas> m_damaged_areas;
// NOTE: same size as framebuffer
BAN::Vector<uint32_t> m_background_image;
State m_state { State::Normal };
bool m_is_mod_key_held { false };
BAN::RefPtr<Window> m_focused_window;
BAN::Array<BAN::RefPtr<Window>, 5> m_mouse_button_windows;
Position m_cursor;
Rectangle m_non_full_screen_rect;
uint8_t m_resize_quadrant { 0 };
Position m_resize_start;
bool m_is_mouse_relative { false };
bool m_is_stopped { false };
bool m_is_bouncing_window = false;
LibFont::Font m_font;
};