add xdg decoration, scene/tree factories, geometry + seat focus

more wrapper soup. xdg decoration manager, scene/tree node factories so
callers stop touching raw wlr_scene_*_create, a box geometry helper, and
seat pointer/keyboard focus clearing. dragging myself through it.
This commit is contained in:
AstralZX
2026-08-29 10:04:50 +02:00
parent 89cbf733b3
commit 5bd1c6561c
9 changed files with 197 additions and 43 deletions
+40
View File
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: AGPL-3.0-only
#pragma once
#include <wlr/util/box.h>
#include "wlr/wlr.hpp"
namespace wlr {
class Geometry {
public:
Geometry() = default;
Geometry(int x, int y, int w, int h) : m_box{x, y, w, h} {}
explicit Geometry(const struct wlr_box& b) : m_box(b) {}
struct wlr_box* raw() { return &m_box; }
const struct wlr_box* raw() const { return &m_box; }
int x() const { return m_box.x; }
int y() const { return m_box.y; }
int width() const { return m_box.width; }
int height() const { return m_box.height; }
void set(int x, int y, int w, int h) {
m_box.x = x; m_box.y = y; m_box.width = w; m_box.height = h;
}
bool contains(double px, double py) const {
return wlr_box_contains_point(&m_box, px, py);
}
bool intersects(const Geometry& o) const {
struct wlr_box dest;
return wlr_box_intersection(&dest, &m_box, &o.m_box);
}
private:
struct wlr_box m_box{};
};
}
+41
View File
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: AGPL-3.0-only
#pragma once
#include <pixman.h>
#include "wlr/wlr.hpp"
namespace wlr {
struct Box {
int x = 0, y = 0, width = 0, height = 0;
pixman_box32 to_box() const { return {x, y, x + width, y + height}; }
static Box from_box(pixman_box32 b) {
return {b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1};
}
};
struct Color {
float r = 1.0f, g = 1.0f, b = 1.0f, a = 1.0f;
void apply(float out[4]) const {
out[0] = r; out[1] = g; out[2] = b; out[3] = a;
}
};
struct CornerRadii {
uint16_t top_left = 0, top_right = 0, bottom_right = 0, bottom_left = 0;
CornerRadii() = default;
CornerRadii(uint16_t all) : top_left(all), top_right(all), bottom_right(all), bottom_left(all) {}
CornerRadii(uint16_t tl, uint16_t tr, uint16_t br, uint16_t bl)
: top_left(tl), top_right(tr), bottom_right(br), bottom_left(bl) {}
fx_corner_radii raw() const {
return fx_corner_radii{top_left, top_right, bottom_right, bottom_left};
}
static CornerRadii from_radii(fx_corner_radii r) {
return {r.top_left, r.top_right, r.bottom_right, r.bottom_left};
}
};
}
+19 -11
View File
@@ -4,7 +4,7 @@
#include <utility> #include <utility>
#include "wlr/wlr.hpp" #include "wlr/wlr.hpp"
#include "wlr/scene.hpp" #include "wlr/color.hpp"
namespace wlr { namespace wlr {
@@ -36,16 +36,6 @@ protected:
struct wlr_scene_node* m_node; struct wlr_scene_node* m_node;
}; };
class Tree : public Node {
public:
Tree(struct wlr_scene_tree* tree) : Node(&tree->node), m_tree(tree) {}
struct wlr_scene_tree* raw() const { return m_tree; }
void reparent(Node& n) { wlr_scene_node_reparent(n.raw(), m_tree); }
private:
struct wlr_scene_tree* m_tree;
};
class Rect : public Node { class Rect : public Node {
public: public:
Rect(struct wlr_scene_rect* rect) : Node(&rect->node), m_rect(rect) {} Rect(struct wlr_scene_rect* rect) : Node(&rect->node), m_rect(rect) {}
@@ -127,4 +117,22 @@ private:
struct wlr_scene_surface* m_surface; struct wlr_scene_surface* m_surface;
}; };
class Tree : public Node {
public:
Tree(struct wlr_scene_tree* tree) : Node(&tree->node), m_tree(tree) {}
struct wlr_scene_tree* raw() const { return m_tree; }
void reparent(Node& n) { wlr_scene_node_reparent(n.raw(), m_tree); }
Tree add_tree() { return Tree{wlr_scene_tree_create(m_tree)}; }
Rect add_rect(int w, int h, const Color& c) {
float col[4]; c.apply(col);
return Rect{wlr_scene_rect_create(m_tree, w, h, col)};
}
Buffer add_buffer() { return Buffer{wlr_scene_buffer_create(m_tree, nullptr)}; }
Surface add_surface(struct wlr_surface* s) { return Surface{wlr_scene_surface_create(m_tree, s)}; }
private:
struct wlr_scene_tree* m_tree;
};
} }
+14
View File
@@ -19,6 +19,11 @@ public:
const char* make() const { return m_output->make; } const char* make() const { return m_output->make; }
const char* model() const { return m_output->model; } const char* model() const { return m_output->model; }
int width() const { return m_output->width; }
int height() const { return m_output->height; }
enum wl_output_transform transform() const { return m_output->transform; }
struct wlr_output_mode* current_mode() const { return m_output->current_mode; }
struct wlr_output_mode* preferred_mode() const { struct wlr_output_mode* preferred_mode() const {
return wlr_output_preferred_mode(m_output); return wlr_output_preferred_mode(m_output);
} }
@@ -32,6 +37,15 @@ public:
wlr_output_state_finish(&state); wlr_output_state_finish(&state);
return ok; return ok;
} }
bool set_mode(struct wlr_output_mode* mode) {
if (!mode) return false;
struct wlr_output_state state;
wlr_output_state_init(&state);
wlr_output_state_set_mode(&state, mode);
bool ok = wlr_output_commit_state(m_output, &state);
wlr_output_state_finish(&state);
return ok;
}
private: private:
struct wlr_output* m_output; struct wlr_output* m_output;
+10 -32
View File
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
#pragma once #pragma once
#include <pixman.h>
#include <string> #include <string>
#include "wlr/wlr.hpp" #include "wlr/wlr.hpp"
#include "wlr/color.hpp"
#include "wlr/node.hpp"
namespace wlr { namespace wlr {
@@ -36,39 +37,16 @@ public:
void set_blur_saturation(float saturation) { wlr_scene_set_blur_saturation(m_scene, saturation); } void set_blur_saturation(float saturation) { wlr_scene_set_blur_saturation(m_scene, saturation); }
struct wlr_scene_tree* root() { return &m_scene->tree; } struct wlr_scene_tree* root() { return &m_scene->tree; }
Tree add_tree() { return Tree{wlr_scene_tree_create(&m_scene->tree)}; }
Rect add_rect(int w, int h, const Color& c) {
float col[4]; c.apply(col);
return Rect{wlr_scene_rect_create(&m_scene->tree, w, h, col)};
}
Buffer add_buffer() { return Buffer{wlr_scene_buffer_create(&m_scene->tree, nullptr)}; }
Surface add_surface(struct wlr_surface* s) { return Surface{wlr_scene_surface_create(&m_scene->tree, s)}; }
private: private:
struct wlr_scene* m_scene; struct wlr_scene* m_scene;
}; };
struct Box {
int x = 0, y = 0, width = 0, height = 0;
pixman_box32 to_box() const { return {x, y, x + width, y + height}; }
static Box from_box(pixman_box32 b) {
return {b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1};
}
};
struct Color {
float r = 1.0f, g = 1.0f, b = 1.0f, a = 1.0f;
void apply(float out[4]) const {
out[0] = r; out[1] = g; out[2] = b; out[3] = a;
}
};
struct CornerRadii {
uint16_t top_left = 0, top_right = 0, bottom_right = 0, bottom_left = 0;
CornerRadii() = default;
CornerRadii(uint16_t all) : top_left(all), top_right(all), bottom_right(all), bottom_left(all) {}
CornerRadii(uint16_t tl, uint16_t tr, uint16_t br, uint16_t bl)
: top_left(tl), top_right(tr), bottom_right(br), bottom_left(bl) {}
fx_corner_radii raw() const {
return fx_corner_radii{top_left, top_right, bottom_right, bottom_left};
}
static CornerRadii from_radii(fx_corner_radii r) {
return {r.top_left, r.top_right, r.bottom_right, r.bottom_left};
}
};
} }
+10
View File
@@ -71,6 +71,16 @@ public:
void keyboard_notify_key(uint32_t time, uint32_t keycode, enum wl_keyboard_key_state state) { void keyboard_notify_key(uint32_t time, uint32_t keycode, enum wl_keyboard_key_state state) {
wlr_seat_keyboard_notify_key(m_seat, time, keycode, state); wlr_seat_keyboard_notify_key(m_seat, time, keycode, state);
} }
void keyboard_notify_enter(struct wlr_surface* surface,
uint32_t* keycodes = nullptr, size_t num_keycodes = 0,
struct wlr_keyboard_modifiers* modifiers = nullptr) {
wlr_seat_keyboard_notify_enter(m_seat, surface, keycodes, num_keycodes, modifiers);
}
void keyboard_clear_focus() { wlr_seat_keyboard_clear_focus(m_seat); }
void pointer_notify_enter(struct wlr_surface* surface, double sx, double sy) {
wlr_seat_pointer_notify_enter(m_seat, surface, sx, sy);
}
void pointer_clear_focus() { wlr_seat_pointer_clear_focus(m_seat); }
void pointer_notify_motion(uint32_t time, double sx, double sy) { void pointer_notify_motion(uint32_t time, double sx, double sy) {
wlr_seat_pointer_notify_motion(m_seat, time, sx, sy); wlr_seat_pointer_notify_motion(m_seat, time, sx, sy);
} }
+2
View File
@@ -20,7 +20,9 @@ extern "C" {
#include <wlr/types/wlr_pointer.h> #include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_xdg_shell.h> #include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_data_device.h>
#include <wlr/util/box.h>
#include <wlr/backend.h> #include <wlr/backend.h>
#include <wlr/render/wlr_renderer.h> #include <wlr/render/wlr_renderer.h>
#include <wlr/render/allocator.h> #include <wlr/render/allocator.h>
+59
View File
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: AGPL-3.0-only
#pragma once
#include <functional>
#include "wlr/wlr.hpp"
#include "wlr/display.hpp"
#include "wlr/signals.hpp"
#include "wlr/xdg_shell.hpp"
namespace wlr {
class XdgToplevelDecoration {
public:
enum Mode { None = 0, ClientSide = 1, ServerSide = 2 };
XdgToplevelDecoration(struct wlr_xdg_toplevel_decoration_v1* d) : m_dec(d) {}
struct wlr_xdg_toplevel_decoration_v1* raw() const { return m_dec; }
explicit operator bool() const { return m_dec != nullptr; }
Mode current_mode() const { return static_cast<Mode>(m_dec->current.mode); }
Mode requested_mode() const { return static_cast<Mode>(m_dec->requested_mode); }
void set_mode(Mode m) {
wlr_xdg_toplevel_decoration_v1_set_mode(m_dec,
static_cast<enum wlr_xdg_toplevel_decoration_v1_mode>(m));
}
Toplevel toplevel() const { return Toplevel{m_dec->toplevel}; }
void on_request_mode(std::function<void(void*)> cb) {
m_request.connect(&m_dec->events.request_mode, std::move(cb));
}
void on_destroy(std::function<void(void*)> cb) {
m_destroy.connect(&m_dec->events.destroy, std::move(cb));
}
private:
struct wlr_xdg_toplevel_decoration_v1* m_dec;
SignalSink m_request;
SignalSink m_destroy;
};
class XdgDecorationManager {
public:
XdgDecorationManager(Display& d)
: m_mgr(wlr_xdg_decoration_manager_v1_create(d.raw())) {}
struct wlr_xdg_decoration_manager_v1* raw() const { return m_mgr; }
explicit operator bool() const { return m_mgr != nullptr; }
void on_new_toplevel_decoration(std::function<void(void*)> cb) {
m_new.connect(&m_mgr->events.new_toplevel_decoration, std::move(cb));
}
private:
struct wlr_xdg_decoration_manager_v1* m_mgr;
SignalSink m_new;
};
}
+2
View File
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
#include "wlr/node.hpp" #include "wlr/node.hpp"
#include "wlr/box.hpp"
#include "wlr/xdg_decoration.hpp"
#include <string> #include <string>
#include <wlr/version.h> #include <wlr/version.h>