This patch replaces the custom renderer logic with wlroot's wlr_scene
API
---
render.c | 130 +++----------------------------------------------------
server.c | 55 +++++++++++++++--------
server.h | 2 +
view.c | 35 +++++++++------
view.h | 1 +
5 files changed, 68 insertions(+), 155 deletions(-)
diff --git a/render.c b/render.c
index f868ca1..c6eaca7 100644
--- a/render.c
+++ b/render.c
@@ -20,137 +20,17 @@ struct render_data {
struct timespec *when;
};
-static void
-render_surface(struct wlr_surface *surface, int x, int y, void *data)
-{
- const struct render_data *rdata = data;
- struct wlr_output *output = rdata->output;
-
- struct wlr_texture *texture = wlr_surface_get_texture(surface);
- if (texture == NULL)
- {
- return;
- }
-
- double ox = 0.0, oy = 0.0;
- wlr_output_layout_output_coords(rdata->layout, output, &ox, &oy);
-
- ox += x + rdata->geometry->x;
- oy += y + rdata->geometry->y;
-
- struct wlr_box box = {
- .x = (int)(ox * (double)output->scale),
- .y = (int)(oy * (double)output->scale),
- .width = surface->current.width * (int)output->scale,
- .height = surface->current.height * (int)output->scale,
- };
-
- enum wl_output_transform transform = wlr_output_transform_invert(
- surface->current.transform);
-
- float matrix[9];
- wlr_matrix_project_box(matrix, &box, transform, 0,
- output->transform_matrix);
-
- wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1);
-
- wlr_surface_send_frame_done(surface, rdata->when);
-}
-
-static void
-render_view(struct kaiju_view *view, struct render_data *rdata)
-{
- if (!view->mapped) {
- return;
- }
-
- wlr_xdg_surface_for_each_surface(view->wlr_xdg_surface, render_surface,
- rdata);
-}
-
-static void
-render_views(struct wl_list *views, struct render_data *rdata)
-{
- struct kaiju_view *view = NULL;
- wl_list_for_each_reverse(view, views, link) {
- struct wlr_box box = {
- .x = view->x,
- .y = view->y,
- };
- kaiju_view_get_geometry(view, &box.width, &box.height);
- rdata->geometry = &box;
- render_view(view, rdata);
- }
-}
-
-static void
-render_layer(struct kaiju_layer *layer, struct render_data *rdata)
-{
- if (!layer->mapped) {
- return;
- }
-
- wlr_layer_surface_v1_for_each_surface(layer->wlr_layer_surface,
- render_surface, rdata);
-}
-
-static void
-render_layers(struct wl_list *layers, struct render_data *rdata)
-{
- struct kaiju_layer *layer = NULL;
- wl_list_for_each(layer, layers, link) {
- rdata->geometry = &layer->geometry;
- render_layer(layer, rdata);
- }
-}
-
void
kaiju_render_frame(struct kaiju_output *output)
{
- struct wlr_output *wlr_output = output->wlr_output;
-
- if (!wlr_output_attach_render(wlr_output, NULL)) {
- return;
- }
+ struct wlr_scene *scene = output->server->scene;
- struct kaiju_server *server = output->server;
- struct wlr_renderer *renderer = server->wlr_renderer;
+ struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(
+ scene, output->wlr_output);
- int width, height;
- wlr_output_effective_resolution(wlr_output, &width, &height);
+ wlr_scene_output_commit(scene_output);
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
-
- wlr_renderer_begin(renderer, width, height);
- {
- static const float color[4] = {0.22f, 0.24f, 0.33f, 1.0f};
- wlr_renderer_clear(renderer, color);
-
- struct render_data rdata = {
- .renderer = renderer,
- .output = wlr_output,
- .layout = output->server->wlr_output_layout,
- .when = &now,
- };
-
- render_layers(&server->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
- &rdata);
-
- render_views(&server->views, &rdata);
-
- render_layers(&server->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
- &rdata);
-
- render_layers(&server->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
- &rdata);
-
- render_layers(&server->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
- &rdata);
-
- wlr_output_render_software_cursors(wlr_output, NULL);
- wlr_renderer_scissor(renderer, NULL);
- }
- wlr_renderer_end(renderer);
- wlr_output_commit(wlr_output);
+ wlr_scene_output_send_frame_done(scene_output, &now);
}
diff --git a/server.c b/server.c
index acaea16..4fd7558 100644
--- a/server.c
+++ b/server.c
@@ -10,28 +10,36 @@
#include <wlr/util/log.h>
#include <stdlib.h>
+#include <assert.h>
struct kaiju_view *kaiju_server_view_at(struct kaiju_server *server, double lx,
double ly, struct wlr_surface **surface, double *sx, double *sy)
{
- struct kaiju_view *view = NULL;
- wl_list_for_each(view, &server->views, link) {
- double view_sx = lx - view->x;
- double view_sy = ly - view->y;
- double tmp_sx, tmp_sy;
- struct wlr_surface *tmp = wlr_xdg_surface_surface_at(
- view->wlr_xdg_surface, view_sx, view_sy,
- &tmp_sx, &tmp_sy);
-
- if (tmp != NULL) {
- *surface = tmp;
- *sx = tmp_sx;
- *sy = tmp_sy;
- return view;
- }
+ struct wlr_scene_node *node = wlr_scene_node_at(&server->scene->tree.node,
+ lx, ly, sx, sy);
+
+ if (node == NULL || node->type != WLR_SCENE_NODE_SURFACE) {
+ return NULL;
+ }
+
+ struct wlr_scene_buffer *scene_buffer =
+ wlr_scene_buffer_from_node(node);
+
+ struct wlr_scene_surface *scene_surface =
+ wlr_scene_surface_from_buffer(scene_buffer);
+
+ if (!scene_surface) {
+ return NULL;
+ }
+
+ *surface = scene_surface->surface;
+
+ struct wlr_scene_tree *tree = node->parent;
+ while (tree != NULL && tree->node.data == NULL) {
+ tree = tree->node.parent;
}
- return NULL;
+ return tree->node.data;
}
bool
@@ -105,10 +113,19 @@ new_xdg_surface_handler(struct wl_listener *listener, void *data)
events.new_xdg_surface);
struct wlr_xdg_surface *surface = data;
- if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
+ if (surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
+ struct wlr_xdg_surface *parent =
+ wlr_xdg_surface_from_wlr_surface(surface->popup->parent);
+
+ struct wlr_scene_tree *parent_tree = parent->data;
+ surface->data = wlr_scene_xdg_surface_create(parent_tree,
+ surface);
+
return;
}
+ assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
+
wlr_log(WLR_DEBUG, "New xdg surface %s", surface->toplevel->app_id);
struct kaiju_view *view = kaiju_view_create(server, surface);
@@ -160,6 +177,10 @@ kaiju_server_init(struct kaiju_server *server)
server->wlr_output_layout = wlr_output_layout_create();
+ server->scene = wlr_scene_create();
+ wlr_scene_attach_output_layout(server->scene,
+ server->wlr_output_layout);
+
server->wlr_input_method_manager = wlr_input_method_manager_v2_create(
server->wl_display);
diff --git a/server.h b/server.h
index 91e20ee..f8e9a4d 100644
--- a/server.h
+++ b/server.h
@@ -9,6 +9,7 @@
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_xdg_shell.h>
+#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_input_method_v2.h>
@@ -23,6 +24,7 @@ struct kaiju_server {
struct wl_display *wl_display;
const char *socket;
+ struct wlr_scene *scene;
struct wlr_backend *wlr_backend;
struct wlr_renderer *wlr_renderer;
struct wlr_allocator *wlr_allocator;
diff --git a/view.c b/view.c
index e12fc1f..0b93a0f 100644
--- a/view.c
+++ b/view.c
@@ -26,18 +26,20 @@ kaiju_view_focus(struct kaiju_view *view)
/* Deactivate the previous surface */
struct wlr_xdg_surface *xdg_previous =
wlr_xdg_surface_from_wlr_surface(previous);
- wlr_xdg_toplevel_set_activated(xdg_previous, false);
+ wlr_xdg_toplevel_set_activated(xdg_previous->toplevel, false);
}
struct kaiju_server *server = view->server;
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat);
+ wlr_scene_node_raise_to_top(&view->scene_tree->node);
+
/* Move the view to the front */
wl_list_remove(&view->link);
wl_list_insert(&server->views, &view->link);
/* Activate the current surface */
- wlr_xdg_toplevel_set_activated(view->wlr_xdg_surface, true);
+ wlr_xdg_toplevel_set_activated(view->wlr_xdg_surface->toplevel, true);
/* Tell the seat to give keyboard input to the surface */
wlr_seat_keyboard_notify_enter(seat, surface, keyboard->keycodes,
@@ -59,25 +61,26 @@ kaiju_view_position(struct kaiju_view *view)
{
assert(view);
- struct wlr_box *layout = wlr_output_layout_get_box(
- view->server->wlr_output_layout, NULL);
+ struct wlr_box layout;
+ wlr_output_layout_get_box(
+ view->server->wlr_output_layout, NULL, &layout);
- //if (view->wlr_xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
if (!view->wlr_xdg_surface->toplevel->parent) {
/* The parent view should occupy all the screen space */
- view->x = layout->x;
- view->y = layout->y;
+ view->x = layout.x;
+ view->y = layout.y;
- wlr_xdg_toplevel_set_size(view->wlr_xdg_surface,
- (uint32_t)layout->width,
- (uint32_t)layout->height);
- wlr_xdg_toplevel_set_maximized(view->wlr_xdg_surface, true);
+ wlr_xdg_toplevel_set_size(view->wlr_xdg_surface->toplevel,
+ (uint32_t)layout.width,
+ (uint32_t)layout.height);
+ wlr_xdg_toplevel_set_maximized(view->wlr_xdg_surface->toplevel, true);
} else {
/* The child view should be centered */
int width, height;
kaiju_view_get_geometry(view, &width, &height);
- view->x = (layout->width - width) / 2;
- view->y = (layout->height - height) / 2;
+ view->x = (layout.width - width) / 2;
+ view->y = (layout.height - height) / 2;
+ wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y);
}
}
@@ -128,6 +131,12 @@ struct kaiju_view *kaiju_view_create(struct kaiju_server *server,
view->server = server;
view->wlr_xdg_surface = surface;
+ view->scene_tree = wlr_scene_xdg_surface_create(
+ &view->server->scene->tree,
+ view->wlr_xdg_surface->toplevel->base);
+
+ view->scene_tree->node.data = view;
+ view->wlr_xdg_surface->data = view->scene_tree;
view->events.map.notify = view_map_handler;
wl_signal_add(&surface->events.map, &view->events.map);
diff --git a/view.h b/view.h
index 5356b1c..0e8926b 100644
--- a/view.h
+++ b/view.h
@@ -10,6 +10,7 @@ struct kaiju_server;
struct kaiju_view {
struct wlr_xdg_surface *wlr_xdg_surface;
+ struct wlr_scene_tree *scene_tree;
bool mapped;
int x, y;
--
2.39.0
---
seat.c | 23 +++++++++++++----------
server.c | 4 ++--
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/seat.c b/seat.c
index 369ea44..890ec3e 100644
--- a/seat.c
+++ b/seat.c
@@ -55,11 +55,14 @@ new_pointer(struct kaiju_seat *seat, struct kaiju_input_device *device)
static void
new_keyboard(struct kaiju_seat *seat, struct kaiju_input_device *device)
{
- struct wlr_keyboard *keyboard = device->wlr_input_device->keyboard;
+ struct wlr_keyboard *keyboard =
+ wlr_keyboard_from_input_device(device->wlr_input_device);
+
wlr_keyboard_set_keymap(keyboard,
seat->wlr_keyboard_group->keyboard.keymap);
+
wlr_keyboard_group_add_keyboard(seat->wlr_keyboard_group, keyboard);
- wlr_seat_set_keyboard(seat->wlr_seat, device->wlr_input_device);
+ wlr_seat_set_keyboard(seat->wlr_seat, keyboard);
}
void
@@ -108,7 +111,7 @@ keyboard_key_handler(struct wl_listener *listener, void *data)
{
struct kaiju_seat *seat = wl_container_of(listener, seat,
keyboard_events.key);
- struct wlr_event_keyboard_key *event = data;
+ struct wlr_keyboard_key_event *event = data;
wlr_seat_keyboard_notify_key(seat->wlr_seat, event->time_msec,
event->keycode, event->state);
@@ -148,9 +151,9 @@ cursor_motion_handler(struct wl_listener *listener, void *data)
{
struct kaiju_seat *seat = wl_container_of(listener, seat,
cursor_events.motion);
- struct wlr_event_pointer_motion *event = data;
+ struct wlr_pointer_motion_event *event = data;
- wlr_cursor_move(seat->wlr_cursor, event->device, event->delta_x,
+ wlr_cursor_move(seat->wlr_cursor, &event->pointer->base, event->delta_x,
event->delta_y);
cursor_motion(seat, event->time_msec);
@@ -161,10 +164,10 @@ cursor_absolute_handler(struct wl_listener *listener, void *data)
{
struct kaiju_seat *seat = wl_container_of(listener, seat,
cursor_events.motion_absolute);
- struct wlr_event_pointer_motion_absolute *event = data;
+ struct wlr_pointer_motion_absolute_event *event = data;
- wlr_cursor_warp_absolute(seat->wlr_cursor, event->device, event->x,
- event->y);
+ wlr_cursor_warp_absolute(seat->wlr_cursor, &event->pointer->base,
+ event->x, event->y);
cursor_motion(seat, event->time_msec);
}
@@ -174,7 +177,7 @@ cursor_button_handler(struct wl_listener *listener, void *data)
{
struct kaiju_seat *seat = wl_container_of(listener, seat,
cursor_events.button);
- struct wlr_event_pointer_button *event = data;
+ struct wlr_pointer_button_event *event = data;
wlr_seat_pointer_notify_button(seat->wlr_seat, event->time_msec,
event->button, event->state);
@@ -196,7 +199,7 @@ cursor_axis_handler(struct wl_listener *listener, void *data)
{
struct kaiju_seat *seat = wl_container_of(listener, seat,
cursor_events.axis);
- struct wlr_event_pointer_axis *event = data;
+ struct wlr_pointer_axis_event *event = data;
wlr_seat_pointer_notify_axis(seat->wlr_seat, event->time_msec,
event->orientation, event->delta, event->delta_discrete,
diff --git a/server.c b/server.c
index 4fd7558..5d976f9 100644
--- a/server.c
+++ b/server.c
@@ -138,11 +138,11 @@ new_virtual_keyboard_handler(struct wl_listener *listener, void *data)
{
struct kaiju_server *server = wl_container_of(listener, server,
events.new_virtual_keyboard);
- struct wlr_virtual_keyboard_v1 *keyboard = data;
+ struct wlr_virtual_keyboard_v1 *vkeyboard = data;
wlr_log(WLR_DEBUG, "handling new virtual keyboard");
- kaiju_seat_new_device(server->seat, &keyboard->input_device);
+ kaiju_seat_new_device(server->seat, &vkeyboard->keyboard.base);
}
bool
--
2.39.0