Use scene-graph helpers for sub-surfaces

Delegate sub-surface handling to wlr_scene_surface_tree_create.

References: https://github.com/swaywm/wlroots/pull/3128
This commit is contained in:
Simon Ser 2021-08-28 11:08:11 +02:00 committed by Jente Hidskes
parent fb3dc58237
commit 128fa90ea1
6 changed files with 16 additions and 95 deletions

View file

@ -164,7 +164,7 @@ scan_out_primary_view(struct cg_output *output)
}
size_t n_surfaces = 0;
wlr_scene_node_for_each_surface(&view->scene_surface->node, count_surface_iterator, &n_surfaces);
wlr_scene_node_for_each_surface(view->scene_node, count_surface_iterator, &n_surfaces);
if (n_surfaces > 1) {
return false;
}
@ -312,6 +312,8 @@ damage_finish:
frame_done:
clock_gettime(CLOCK_MONOTONIC, &frame_data.when);
send_frame_done(output, &frame_data);
wlr_output_damage_add_whole(output->damage);
}
static void

8
seat.c
View file

@ -624,7 +624,7 @@ 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);
wlr_scene_node_set_position(drag_icon->scene_node, drag_icon->lx, drag_icon->ly);
}
static void
@ -635,7 +635,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);
wlr_scene_node_destroy(drag_icon->scene_node);
free(drag_icon);
}
@ -678,8 +678,8 @@ 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) {
drag_icon->scene_node = wlr_scene_subsurface_tree_create(&seat->server->scene->node, wlr_drag_icon->surface);
if (!drag_icon->scene_node) {
free(drag_icon);
return;
}

2
seat.h
View file

@ -77,7 +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;
struct wlr_scene_node *scene_node;
/* The drag icon has a position in layout coordinates. */
double lx, ly;

83
view.c
View file

@ -31,16 +31,6 @@ view_child_handle_commit(struct wl_listener *listener, void *data)
view_damage_part(child->view);
}
static void subsurface_create(struct cg_view *view, struct wlr_subsurface *wlr_subsurface);
static void
view_child_handle_new_subsurface(struct wl_listener *listener, void *data)
{
struct cg_view_child *child = wl_container_of(listener, child, new_subsurface);
struct wlr_subsurface *wlr_subsurface = data;
subsurface_create(child->view, wlr_subsurface);
}
void
view_child_finish(struct cg_view_child *child)
{
@ -52,7 +42,6 @@ view_child_finish(struct cg_view_child *child)
wl_list_remove(&child->link);
wl_list_remove(&child->commit.link);
wl_list_remove(&child->new_subsurface.link);
}
void
@ -63,57 +52,10 @@ view_child_init(struct cg_view_child *child, struct cg_view *view, struct wlr_su
child->commit.notify = view_child_handle_commit;
wl_signal_add(&wlr_surface->events.commit, &child->commit);
child->new_subsurface.notify = view_child_handle_new_subsurface;
wl_signal_add(&wlr_surface->events.new_subsurface, &child->new_subsurface);
wl_list_insert(&view->children, &child->link);
}
static void
subsurface_destroy(struct cg_view_child *child)
{
if (!child) {
return;
}
struct cg_subsurface *subsurface = (struct cg_subsurface *) child;
wl_list_remove(&subsurface->destroy.link);
view_child_finish(&subsurface->view_child);
free(subsurface);
}
static void
subsurface_handle_destroy(struct wl_listener *listener, void *data)
{
struct cg_subsurface *subsurface = wl_container_of(listener, subsurface, destroy);
struct cg_view_child *view_child = (struct cg_view_child *) subsurface;
subsurface_destroy(view_child);
}
static void
subsurface_create(struct cg_view *view, struct wlr_subsurface *wlr_subsurface)
{
struct cg_subsurface *subsurface = calloc(1, sizeof(struct cg_subsurface));
if (!subsurface) {
return;
}
view_child_init(&subsurface->view_child, view, wlr_subsurface->surface);
subsurface->view_child.destroy = subsurface_destroy;
subsurface->wlr_subsurface = wlr_subsurface;
subsurface->destroy.notify = subsurface_handle_destroy;
wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
}
static void
handle_new_subsurface(struct wl_listener *listener, void *data)
{
struct cg_view *view = wl_container_of(listener, view, new_subsurface);
struct wlr_subsurface *wlr_subsurface = data;
subsurface_create(view, wlr_subsurface);
}
char *
view_get_title(struct cg_view *view)
{
@ -175,7 +117,7 @@ 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);
wlr_scene_node_set_position(view->scene_node, view->lx, view->ly);
view->impl->maximize(view, layout_box->width, layout_box->height);
}
@ -189,7 +131,7 @@ 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);
wlr_scene_node_set_position(view->scene_node, view->lx, view->ly);
}
void
@ -209,14 +151,12 @@ view_unmap(struct cg_view *view)
{
wl_list_remove(&view->link);
wl_list_remove(&view->new_subsurface.link);
struct cg_view_child *child, *tmp;
wl_list_for_each_safe (child, tmp, &view->children, link) {
child->destroy(child);
}
wlr_scene_node_destroy(&view->scene_surface->node);
wlr_scene_node_destroy(view->scene_node);
view->wlr_surface = NULL;
}
@ -226,23 +166,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) {
view->scene_node = wlr_scene_subsurface_tree_create(&view->server->scene->node, surface);
if (!view->scene_node) {
wl_resource_post_no_memory(surface->resource);
return;
}
view->scene_surface->node.data = view;
struct wlr_subsurface *subsurface;
wl_list_for_each (subsurface, &view->wlr_surface->current.subsurfaces_below, current.link) {
subsurface_create(view, subsurface);
}
wl_list_for_each (subsurface, &view->wlr_surface->current.subsurfaces_above, current.link) {
subsurface_create(view, subsurface);
}
view->new_subsurface.notify = handle_new_subsurface;
wl_signal_add(&view->wlr_surface->events.new_subsurface, &view->new_subsurface);
view->scene_node->data = view;
#if CAGE_HAS_XWAYLAND
/* We shouldn't position override-redirect windows. They set

12
view.h
View file

@ -26,15 +26,13 @@ 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;
struct wlr_scene_node *scene_node;
/* The view has a position in layout coordinates. */
int lx, ly;
enum cg_view_type type;
const struct cg_view_impl *impl;
struct wl_listener new_subsurface;
};
struct cg_view_impl {
@ -53,18 +51,10 @@ struct cg_view_child {
struct wl_list link;
struct wl_listener commit;
struct wl_listener new_subsurface;
void (*destroy)(struct cg_view_child *child);
};
struct cg_subsurface {
struct cg_view_child view_child;
struct wlr_subsurface *wlr_subsurface;
struct wl_listener destroy;
};
char *view_get_title(struct cg_view *view);
bool view_is_primary(struct cg_view *view);
bool view_is_transient_for(struct cg_view *child, struct cg_view *parent);

View file

@ -61,7 +61,7 @@ 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;
struct wlr_scene_node *parent_node = popup->view_child.view->scene_node;
popup->scene_surface = wlr_scene_surface_create(parent_node, popup->view_child.wlr_surface);
if (!popup->scene_surface) {
return;