mirror of
https://github.com/cage-kiosk/cage.git
synced 2025-10-29 05:40:19 -04:00
Use the wlroots scene-graph API
References: https://github.com/swaywm/wlroots/pull/1966
This commit is contained in:
parent
395189fb05
commit
f544483340
11 changed files with 61 additions and 149 deletions
8
cage.c
8
cage.c
|
|
@ -28,6 +28,7 @@
|
|||
#include <wlr/types/wlr_idle.h>
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_screencopy_v1.h>
|
||||
#include <wlr/types/wlr_server_decoration.h>
|
||||
#if CAGE_HAS_XWAYLAND
|
||||
|
|
@ -342,6 +343,13 @@ main(int argc, char *argv[])
|
|||
goto end;
|
||||
}
|
||||
|
||||
server.scene = wlr_scene_create();
|
||||
if (!server.scene) {
|
||||
wlr_log(WLR_ERROR, "Unable to create scene");
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
compositor = wlr_compositor_create(server.wl_display, server.renderer);
|
||||
if (!compositor) {
|
||||
wlr_log(WLR_ERROR, "Unable to create the wlroots compositor");
|
||||
|
|
|
|||
67
output.c
67
output.c
|
|
@ -26,6 +26,7 @@
|
|||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_damage.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
|
@ -105,63 +106,19 @@ output_surface_for_each_surface(struct cg_output *output, struct wlr_surface *su
|
|||
wlr_surface_for_each_surface(surface, output_for_each_surface_iterator, &data);
|
||||
}
|
||||
|
||||
static void
|
||||
output_view_for_each_surface(struct cg_output *output, struct cg_view *view, cg_surface_iterator_func_t iterator,
|
||||
void *user_data)
|
||||
{
|
||||
struct surface_iterator_data data = {
|
||||
.user_iterator = iterator,
|
||||
.user_data = user_data,
|
||||
.output = output,
|
||||
.ox = view->lx,
|
||||
.oy = view->ly,
|
||||
};
|
||||
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &data.ox, &data.oy);
|
||||
view_for_each_surface(view, output_for_each_surface_iterator, &data);
|
||||
}
|
||||
|
||||
void
|
||||
output_view_for_each_popup_surface(struct cg_output *output, struct cg_view *view, cg_surface_iterator_func_t iterator,
|
||||
void *user_data)
|
||||
{
|
||||
struct surface_iterator_data data = {
|
||||
.user_iterator = iterator,
|
||||
.user_data = user_data,
|
||||
.output = output,
|
||||
.ox = view->lx,
|
||||
.oy = view->ly,
|
||||
};
|
||||
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &data.ox, &data.oy);
|
||||
view_for_each_popup_surface(view, output_for_each_surface_iterator, &data);
|
||||
}
|
||||
|
||||
void
|
||||
output_drag_icons_for_each_surface(struct cg_output *output, struct wl_list *drag_icons,
|
||||
cg_surface_iterator_func_t iterator, void *user_data)
|
||||
{
|
||||
struct cg_drag_icon *drag_icon;
|
||||
wl_list_for_each (drag_icon, drag_icons, link) {
|
||||
if (drag_icon->wlr_drag_icon->mapped) {
|
||||
double ox = drag_icon->lx;
|
||||
double oy = drag_icon->ly;
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &ox, &oy);
|
||||
output_surface_for_each_surface(output, drag_icon->wlr_drag_icon->surface, ox, oy, iterator,
|
||||
user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_for_each_surface(struct cg_output *output, cg_surface_iterator_func_t iterator, void *user_data)
|
||||
{
|
||||
struct cg_view *view;
|
||||
wl_list_for_each_reverse (view, &output->server->views, link) {
|
||||
output_view_for_each_surface(output, view, iterator, user_data);
|
||||
}
|
||||
struct surface_iterator_data data = {
|
||||
.user_iterator = iterator,
|
||||
.user_data = user_data,
|
||||
.output = output,
|
||||
.ox = 0,
|
||||
.oy = 0,
|
||||
};
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &data.ox, &data.oy);
|
||||
|
||||
output_drag_icons_for_each_surface(output, &output->server->seat->drag_icons, iterator, user_data);
|
||||
wlr_scene_node_for_each_surface(&output->server->scene->node, output_for_each_surface_iterator, &data);
|
||||
}
|
||||
|
||||
struct send_frame_done_data {
|
||||
|
|
@ -182,7 +139,7 @@ send_frame_done(struct cg_output *output, struct send_frame_done_data *data)
|
|||
}
|
||||
|
||||
static void
|
||||
count_surface_iterator(struct cg_output *output, struct wlr_surface *surface, struct wlr_box *_box, void *data)
|
||||
count_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *data)
|
||||
{
|
||||
size_t *n = data;
|
||||
(*n)++;
|
||||
|
|
@ -207,7 +164,7 @@ scan_out_primary_view(struct cg_output *output)
|
|||
}
|
||||
|
||||
size_t n_surfaces = 0;
|
||||
output_view_for_each_surface(output, view, count_surface_iterator, &n_surfaces);
|
||||
wlr_scene_node_for_each_surface(&view->scene_surface->node, count_surface_iterator, &n_surfaces);
|
||||
if (n_surfaces > 1) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
4
output.h
4
output.h
|
|
@ -28,10 +28,6 @@ typedef void (*cg_surface_iterator_func_t)(struct cg_output *output, struct wlr_
|
|||
void handle_new_output(struct wl_listener *listener, void *data);
|
||||
void output_surface_for_each_surface(struct cg_output *output, struct wlr_surface *surface, double ox, double oy,
|
||||
cg_surface_iterator_func_t iterator, void *user_data);
|
||||
void output_view_for_each_popup_surface(struct cg_output *output, struct cg_view *view,
|
||||
cg_surface_iterator_func_t iterator, void *user_data);
|
||||
void output_drag_icons_for_each_surface(struct cg_output *output, struct wl_list *drag_icons,
|
||||
cg_surface_iterator_func_t iterator, void *user_data);
|
||||
void output_damage_surface(struct cg_output *output, struct wlr_surface *surface, double lx, double ly, bool whole);
|
||||
void output_set_window_title(struct cg_output *output, const char *title);
|
||||
|
||||
|
|
|
|||
94
render.c
94
render.c
|
|
@ -13,6 +13,7 @@
|
|||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/util/box.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
|
@ -46,84 +47,6 @@ struct render_data {
|
|||
pixman_region32_t *damage;
|
||||
};
|
||||
|
||||
static void
|
||||
render_texture(struct wlr_output *wlr_output, pixman_region32_t *output_damage, struct wlr_texture *texture,
|
||||
const struct wlr_box *box, const float matrix[static 9])
|
||||
{
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_init(&damage);
|
||||
pixman_region32_union_rect(&damage, &damage, box->x, box->y, box->width, box->height);
|
||||
pixman_region32_intersect(&damage, &damage, output_damage);
|
||||
if (!pixman_region32_not_empty(&damage)) {
|
||||
goto damage_finish;
|
||||
}
|
||||
|
||||
int nrects;
|
||||
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
|
||||
for (int i = 0; i < nrects; i++) {
|
||||
scissor_output(wlr_output, &rects[i]);
|
||||
wlr_render_texture_with_matrix(wlr_output->renderer, texture, matrix, 1.0f);
|
||||
}
|
||||
|
||||
damage_finish:
|
||||
pixman_region32_fini(&damage);
|
||||
}
|
||||
|
||||
static void
|
||||
render_surface_iterator(struct cg_output *output, struct wlr_surface *surface, struct wlr_box *box, void *user_data)
|
||||
{
|
||||
struct render_data *data = user_data;
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
pixman_region32_t *output_damage = data->damage;
|
||||
|
||||
struct wlr_texture *texture = wlr_surface_get_texture(surface);
|
||||
if (!texture) {
|
||||
wlr_log(WLR_DEBUG, "Cannot obtain surface texture");
|
||||
return;
|
||||
}
|
||||
|
||||
scale_box(box, wlr_output->scale);
|
||||
|
||||
float matrix[9];
|
||||
enum wl_output_transform transform = wlr_output_transform_invert(surface->current.transform);
|
||||
wlr_matrix_project_box(matrix, box, transform, 0.0f, wlr_output->transform_matrix);
|
||||
|
||||
render_texture(wlr_output, output_damage, texture, box, matrix);
|
||||
}
|
||||
|
||||
static void
|
||||
render_drag_icons(struct cg_output *output, pixman_region32_t *damage, struct wl_list *drag_icons)
|
||||
{
|
||||
struct render_data data = {
|
||||
.damage = damage,
|
||||
};
|
||||
output_drag_icons_for_each_surface(output, drag_icons, render_surface_iterator, &data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render all toplevels without descending into popups.
|
||||
*/
|
||||
static void
|
||||
render_view_toplevels(struct cg_view *view, struct cg_output *output, pixman_region32_t *damage)
|
||||
{
|
||||
struct render_data data = {
|
||||
.damage = damage,
|
||||
};
|
||||
double ox = view->lx;
|
||||
double oy = view->ly;
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &ox, &oy);
|
||||
output_surface_for_each_surface(output, view->wlr_surface, ox, oy, render_surface_iterator, &data);
|
||||
}
|
||||
|
||||
static void
|
||||
render_view_popups(struct cg_view *view, struct cg_output *output, pixman_region32_t *damage)
|
||||
{
|
||||
struct render_data data = {
|
||||
.damage = damage,
|
||||
};
|
||||
output_view_for_each_popup_surface(output, view, render_surface_iterator, &data);
|
||||
}
|
||||
|
||||
void
|
||||
output_render(struct cg_output *output, pixman_region32_t *damage)
|
||||
{
|
||||
|
|
@ -151,18 +74,9 @@ output_render(struct cg_output *output, pixman_region32_t *damage)
|
|||
wlr_renderer_clear(server->renderer, color);
|
||||
}
|
||||
|
||||
// TODO: render only top view, possibly use focused view for this, see #35.
|
||||
struct cg_view *view;
|
||||
wl_list_for_each_reverse (view, &server->views, link) {
|
||||
render_view_toplevels(view, output, damage);
|
||||
}
|
||||
|
||||
struct cg_view *focused_view = seat_get_focus(server->seat);
|
||||
if (focused_view) {
|
||||
render_view_popups(focused_view, output, damage);
|
||||
}
|
||||
|
||||
render_drag_icons(output, damage, &server->seat->drag_icons);
|
||||
double lx = 0, ly = 0;
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &lx, &ly);
|
||||
wlr_scene_render_output(server->scene, wlr_output, lx, ly, damage);
|
||||
|
||||
renderer_end:
|
||||
/* Draw software cursor in case hardware cursors aren't
|
||||
|
|
|
|||
9
seat.c
9
seat.c
|
|
@ -18,6 +18,7 @@
|
|||
#include <wlr/types/wlr_idle.h>
|
||||
#include <wlr/types/wlr_keyboard_group.h>
|
||||
#include <wlr/types/wlr_primary_selection.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/types/wlr_touch.h>
|
||||
|
|
@ -632,6 +633,8 @@ drag_icon_update_position(struct cg_drag_icon *drag_icon)
|
|||
}
|
||||
|
||||
drag_icon_damage(drag_icon);
|
||||
|
||||
wlr_scene_node_set_position(&drag_icon->scene_surface->node, drag_icon->lx, drag_icon->ly);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -642,6 +645,7 @@ handle_drag_icon_destroy(struct wl_listener *listener, void *data)
|
|||
drag_icon_damage(drag_icon);
|
||||
wl_list_remove(&drag_icon->link);
|
||||
wl_list_remove(&drag_icon->destroy.link);
|
||||
wlr_scene_node_destroy(&drag_icon->scene_surface->node);
|
||||
free(drag_icon);
|
||||
}
|
||||
|
||||
|
|
@ -684,6 +688,11 @@ handle_start_drag(struct wl_listener *listener, void *data)
|
|||
}
|
||||
drag_icon->seat = seat;
|
||||
drag_icon->wlr_drag_icon = wlr_drag_icon;
|
||||
drag_icon->scene_surface = wlr_scene_surface_create(&seat->server->scene->node, wlr_drag_icon->surface);
|
||||
if (!drag_icon->scene_surface) {
|
||||
free(drag_icon);
|
||||
return;
|
||||
}
|
||||
|
||||
drag_icon->destroy.notify = handle_drag_icon_destroy;
|
||||
wl_signal_add(&wlr_drag_icon->events.destroy, &drag_icon->destroy);
|
||||
|
|
|
|||
1
seat.h
1
seat.h
|
|
@ -77,6 +77,7 @@ struct cg_drag_icon {
|
|||
struct wl_list link; // seat::drag_icons
|
||||
struct cg_seat *seat;
|
||||
struct wlr_drag_icon *wlr_drag_icon;
|
||||
struct wlr_scene_surface *scene_surface;
|
||||
|
||||
/* The drag icon has a position in layout coordinates. */
|
||||
double lx, ly;
|
||||
|
|
|
|||
1
server.h
1
server.h
|
|
@ -36,6 +36,7 @@ struct cg_server {
|
|||
|
||||
enum cg_multi_output_mode output_mode;
|
||||
struct wlr_output_layout *output_layout;
|
||||
struct wlr_scene *scene;
|
||||
/* Includes disabled outputs; depending on the output_mode
|
||||
* some outputs may be disabled. */
|
||||
struct wl_list outputs; // cg_output::link
|
||||
|
|
|
|||
14
view.c
14
view.c
|
|
@ -13,6 +13,7 @@
|
|||
#include <string.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
|
||||
#include "output.h"
|
||||
|
|
@ -173,6 +174,9 @@ view_maximize(struct cg_view *view, struct wlr_box *layout_box)
|
|||
{
|
||||
view->lx = layout_box->x;
|
||||
view->ly = layout_box->y;
|
||||
|
||||
wlr_scene_node_set_position(&view->scene_surface->node, view->lx, view->ly);
|
||||
|
||||
view->impl->maximize(view, layout_box->width, layout_box->height);
|
||||
}
|
||||
|
||||
|
|
@ -184,6 +188,8 @@ view_center(struct cg_view *view, struct wlr_box *layout_box)
|
|||
|
||||
view->lx = (layout_box->width - width) / 2;
|
||||
view->ly = (layout_box->height - height) / 2;
|
||||
|
||||
wlr_scene_node_set_position(&view->scene_surface->node, view->lx, view->ly);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -225,6 +231,8 @@ view_unmap(struct cg_view *view)
|
|||
child->destroy(child);
|
||||
}
|
||||
|
||||
wlr_scene_node_destroy(&view->scene_surface->node);
|
||||
|
||||
view->wlr_surface = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -233,6 +241,12 @@ view_map(struct cg_view *view, struct wlr_surface *surface)
|
|||
{
|
||||
view->wlr_surface = surface;
|
||||
|
||||
view->scene_surface = wlr_scene_surface_create(&view->server->scene->node, surface);
|
||||
if (!view->scene_surface) {
|
||||
wl_resource_post_no_memory(surface->resource);
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_subsurface *subsurface;
|
||||
wl_list_for_each (subsurface, &view->wlr_surface->current.subsurfaces_below, current.link) {
|
||||
subsurface_create(view, subsurface);
|
||||
|
|
|
|||
1
view.h
1
view.h
|
|
@ -26,6 +26,7 @@ struct cg_view {
|
|||
struct wl_list link; // server::views
|
||||
struct wl_list children; // cg_view_child::link
|
||||
struct wlr_surface *wlr_surface;
|
||||
struct wlr_scene_surface *scene_surface;
|
||||
|
||||
/* The view has a position in layout coordinates. */
|
||||
int lx, ly;
|
||||
|
|
|
|||
10
xdg_shell.c
10
xdg_shell.c
|
|
@ -9,6 +9,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
|
|
@ -60,6 +61,14 @@ static void
|
|||
handle_xdg_popup_map(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct cg_xdg_popup *popup = wl_container_of(listener, popup, map);
|
||||
struct wlr_scene_node *parent_node = &popup->view_child.view->scene_surface->node;
|
||||
popup->scene_surface = wlr_scene_surface_create(parent_node, popup->view_child.wlr_surface);
|
||||
if (!popup->scene_surface) {
|
||||
return;
|
||||
}
|
||||
double sx, sy;
|
||||
wlr_xdg_popup_get_position(popup->wlr_popup, &sx, &sy);
|
||||
wlr_scene_node_set_position(&popup->scene_surface->node, sx, sy);
|
||||
view_damage_whole(popup->view_child.view);
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +76,7 @@ static void
|
|||
handle_xdg_popup_unmap(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct cg_xdg_popup *popup = wl_container_of(listener, popup, unmap);
|
||||
wlr_scene_node_destroy(&popup->scene_surface->node);
|
||||
view_damage_whole(popup->view_child.view);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ struct cg_xdg_shell_view {
|
|||
struct cg_xdg_popup {
|
||||
struct cg_view_child view_child;
|
||||
struct wlr_xdg_popup *wlr_popup;
|
||||
struct wlr_scene_surface *scene_surface;
|
||||
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener map;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue