Merge pull request #885 from emersion/remove-surface-subsurface
Remove wlr_surface::subsurface, add wlr_subcompositor
This commit is contained in:
commit
12bf39a715
|
@ -6,12 +6,19 @@
|
||||||
|
|
||||||
struct wlr_surface;
|
struct wlr_surface;
|
||||||
|
|
||||||
|
struct wlr_subcompositor {
|
||||||
|
struct wl_global *wl_global;
|
||||||
|
struct wl_list wl_resources;
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_compositor {
|
struct wlr_compositor {
|
||||||
struct wl_global *wl_global;
|
struct wl_global *wl_global;
|
||||||
struct wl_list wl_resources;
|
struct wl_list wl_resources;
|
||||||
struct wlr_renderer *renderer;
|
struct wlr_renderer *renderer;
|
||||||
struct wl_list surfaces;
|
struct wl_list surfaces;
|
||||||
|
|
||||||
|
struct wlr_subcompositor subcompositor;
|
||||||
|
|
||||||
struct wl_listener display_destroy;
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -56,7 +56,8 @@ struct wlr_subsurface {
|
||||||
struct wl_list parent_link;
|
struct wl_list parent_link;
|
||||||
struct wl_list parent_pending_link;
|
struct wl_list parent_pending_link;
|
||||||
|
|
||||||
struct wl_listener parent_destroy_listener;
|
struct wl_listener surface_destroy;
|
||||||
|
struct wl_listener parent_destroy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
|
@ -87,9 +88,7 @@ struct wlr_surface {
|
||||||
void (*role_committed)(struct wlr_surface *surface, void *role_data);
|
void (*role_committed)(struct wlr_surface *surface, void *role_data);
|
||||||
void *role_data;
|
void *role_data;
|
||||||
|
|
||||||
// subsurface properties
|
struct wl_list subsurfaces; // wlr_subsurface::parent_link
|
||||||
struct wlr_subsurface *subsurface;
|
|
||||||
struct wl_list subsurface_list; // wlr_subsurface::parent_link
|
|
||||||
|
|
||||||
// wlr_subsurface::parent_pending_link
|
// wlr_subsurface::parent_pending_link
|
||||||
struct wl_list subsurface_pending_list;
|
struct wl_list subsurface_pending_list;
|
||||||
|
|
|
@ -459,7 +459,7 @@ void view_map(struct roots_view *view, struct wlr_surface *surface) {
|
||||||
view->wlr_surface = surface;
|
view->wlr_surface = surface;
|
||||||
|
|
||||||
struct wlr_subsurface *subsurface;
|
struct wlr_subsurface *subsurface;
|
||||||
wl_list_for_each(subsurface, &view->wlr_surface->subsurface_list,
|
wl_list_for_each(subsurface, &view->wlr_surface->subsurfaces,
|
||||||
parent_link) {
|
parent_link) {
|
||||||
subsurface_create(view, subsurface);
|
subsurface_create(view, subsurface);
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,7 +318,7 @@ static void render_view(struct roots_view *view, struct render_data *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool has_standalone_surface(struct roots_view *view) {
|
static bool has_standalone_surface(struct roots_view *view) {
|
||||||
if (!wl_list_empty(&view->wlr_surface->subsurface_list)) {
|
if (!wl_list_empty(&view->wlr_surface->subsurfaces)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
static const char *subsurface_role = "wl_subsurface";
|
static const char *subsurface_role = "wl_subsurface";
|
||||||
|
|
||||||
bool wlr_surface_is_subsurface(struct wlr_surface *surface) {
|
bool wlr_surface_is_subsurface(struct wlr_surface *surface) {
|
||||||
return strcmp(surface->role, subsurface_role) == 0;
|
return surface->role != NULL &&
|
||||||
|
strcmp(surface->role, subsurface_role) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_subsurface *wlr_subsurface_from_surface(
|
struct wlr_subsurface *wlr_subsurface_from_surface(
|
||||||
|
@ -19,9 +20,96 @@ struct wlr_subsurface *wlr_subsurface_from_surface(
|
||||||
return (struct wlr_subsurface *)surface->role_data;
|
return (struct wlr_subsurface *)surface->role_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void subcompositor_handle_destroy(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subcompositor_handle_get_subsurface(struct wl_client *client,
|
||||||
|
struct wl_resource *resource, uint32_t id,
|
||||||
|
struct wl_resource *surface_resource,
|
||||||
|
struct wl_resource *parent_resource) {
|
||||||
|
struct wlr_surface *surface = wlr_surface_from_resource(surface_resource);
|
||||||
|
struct wlr_surface *parent = wlr_surface_from_resource(parent_resource);
|
||||||
|
|
||||||
|
static const char msg[] = "get_subsurface: wl_subsurface@";
|
||||||
|
|
||||||
|
if (surface == parent) {
|
||||||
|
wl_resource_post_error(resource,
|
||||||
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
||||||
|
"%s%d: wl_surface@%d cannot be its own parent",
|
||||||
|
msg, id, wl_resource_get_id(surface_resource));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlr_surface_is_subsurface(surface)) {
|
||||||
|
wl_resource_post_error(resource,
|
||||||
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
||||||
|
"%s%d: wl_surface@%d is already a sub-surface",
|
||||||
|
msg, id, wl_resource_get_id(surface_resource));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlr_surface_get_root_surface(parent) == surface) {
|
||||||
|
wl_resource_post_error(resource,
|
||||||
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
||||||
|
"%s%d: wl_surface@%d is an ancestor of parent",
|
||||||
|
msg, id, wl_resource_get_id(surface_resource));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlr_surface_set_role(surface, subsurface_role, resource,
|
||||||
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_surface_make_subsurface(surface, parent, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_subcompositor_interface subcompositor_interface = {
|
||||||
|
.destroy = subcompositor_handle_destroy,
|
||||||
|
.get_subsurface = subcompositor_handle_get_subsurface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void subcompositor_bind(struct wl_client *client, void *data,
|
||||||
|
uint32_t version, uint32_t id) {
|
||||||
|
struct wlr_subcompositor *subcompositor = data;
|
||||||
|
struct wl_resource *resource =
|
||||||
|
wl_resource_create(client, &wl_subcompositor_interface, 1, id);
|
||||||
|
if (resource == NULL) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_resource_set_implementation(resource, &subcompositor_interface,
|
||||||
|
subcompositor, NULL);
|
||||||
|
wl_list_insert(&subcompositor->wl_resources, wl_resource_get_link(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subcompositor_init(struct wlr_subcompositor *subcompositor,
|
||||||
|
struct wl_display *display) {
|
||||||
|
subcompositor->wl_global = wl_global_create(display,
|
||||||
|
&wl_subcompositor_interface, 1, subcompositor, subcompositor_bind);
|
||||||
|
if (subcompositor->wl_global == NULL) {
|
||||||
|
wlr_log_errno(L_ERROR, "Could not allocate subcompositor global");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_list_init(&subcompositor->wl_resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subcompositor_finish(struct wlr_subcompositor *subcompositor) {
|
||||||
|
wl_global_destroy(subcompositor->wl_global);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const struct wl_compositor_interface wl_compositor_impl;
|
static const struct wl_compositor_interface wl_compositor_impl;
|
||||||
|
|
||||||
static struct wlr_compositor *compositor_from_resource(struct wl_resource *resource) {
|
static struct wlr_compositor *compositor_from_resource(
|
||||||
|
struct wl_resource *resource) {
|
||||||
assert(wl_resource_instance_of(resource, &wl_compositor_interface,
|
assert(wl_resource_instance_of(resource, &wl_compositor_interface,
|
||||||
&wl_compositor_impl));
|
&wl_compositor_impl));
|
||||||
return wl_resource_get_user_data(resource);
|
return wl_resource_get_user_data(resource);
|
||||||
|
@ -86,16 +174,15 @@ static void wl_compositor_bind(struct wl_client *wl_client, void *data,
|
||||||
struct wlr_compositor *compositor = data;
|
struct wlr_compositor *compositor = data;
|
||||||
assert(wl_client && compositor);
|
assert(wl_client && compositor);
|
||||||
|
|
||||||
struct wl_resource *wl_resource =
|
struct wl_resource *resource =
|
||||||
wl_resource_create(wl_client, &wl_compositor_interface, version, id);
|
wl_resource_create(wl_client, &wl_compositor_interface, version, id);
|
||||||
if (wl_resource == NULL) {
|
if (resource == NULL) {
|
||||||
wl_client_post_no_memory(wl_client);
|
wl_client_post_no_memory(wl_client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_resource_set_implementation(wl_resource, &wl_compositor_impl,
|
wl_resource_set_implementation(resource, &wl_compositor_impl,
|
||||||
compositor, wl_compositor_destroy);
|
compositor, wl_compositor_destroy);
|
||||||
wl_list_insert(&compositor->wl_resources,
|
wl_list_insert(&compositor->wl_resources, wl_resource_get_link(resource));
|
||||||
wl_resource_get_link(wl_resource));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_compositor_destroy(struct wlr_compositor *compositor) {
|
void wlr_compositor_destroy(struct wlr_compositor *compositor) {
|
||||||
|
@ -103,82 +190,12 @@ void wlr_compositor_destroy(struct wlr_compositor *compositor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&compositor->events.destroy, compositor);
|
wlr_signal_emit_safe(&compositor->events.destroy, compositor);
|
||||||
|
subcompositor_finish(&compositor->subcompositor);
|
||||||
wl_list_remove(&compositor->display_destroy.link);
|
wl_list_remove(&compositor->display_destroy.link);
|
||||||
wl_global_destroy(compositor->wl_global);
|
wl_global_destroy(compositor->wl_global);
|
||||||
free(compositor);
|
free(compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subcompositor_destroy(struct wl_client *client,
|
|
||||||
struct wl_resource *resource) {
|
|
||||||
wl_resource_destroy(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void subcompositor_get_subsurface(struct wl_client *client,
|
|
||||||
struct wl_resource *resource, uint32_t id,
|
|
||||||
struct wl_resource *surface_resource,
|
|
||||||
struct wl_resource *parent_resource) {
|
|
||||||
struct wlr_surface *surface = wlr_surface_from_resource(surface_resource);
|
|
||||||
struct wlr_surface *parent = wlr_surface_from_resource(parent_resource);
|
|
||||||
|
|
||||||
static const char msg[] = "get_subsurface: wl_subsurface@";
|
|
||||||
|
|
||||||
if (surface == parent) {
|
|
||||||
wl_resource_post_error(resource,
|
|
||||||
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
|
||||||
"%s%d: wl_surface@%d cannot be its own parent",
|
|
||||||
msg, id, wl_resource_get_id(surface_resource));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surface->subsurface) {
|
|
||||||
wl_resource_post_error(resource,
|
|
||||||
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
|
||||||
"%s%d: wl_surface@%d is already a sub-surface",
|
|
||||||
msg, id, wl_resource_get_id(surface_resource));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wlr_surface_get_root_surface(parent) == surface) {
|
|
||||||
wl_resource_post_error(resource,
|
|
||||||
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
|
||||||
"%s%d: wl_surface@%d is an ancestor of parent",
|
|
||||||
msg, id, wl_resource_get_id(surface_resource));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wlr_surface_set_role(surface, subsurface_role, resource,
|
|
||||||
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_surface_make_subsurface(surface, parent, id);
|
|
||||||
if (!surface->subsurface) {
|
|
||||||
wl_resource_post_no_memory(resource);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->role_data = surface->subsurface;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const struct wl_subcompositor_interface subcompositor_interface = {
|
|
||||||
.destroy = subcompositor_destroy,
|
|
||||||
.get_subsurface = subcompositor_get_subsurface,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void subcompositor_bind(struct wl_client *client, void *data,
|
|
||||||
uint32_t version, uint32_t id) {
|
|
||||||
struct wlr_compositor *compositor = data;
|
|
||||||
struct wl_resource *resource =
|
|
||||||
wl_resource_create(client, &wl_subcompositor_interface, 1, id);
|
|
||||||
if (resource == NULL) {
|
|
||||||
wl_client_post_no_memory(client);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wl_resource_set_implementation(resource, &subcompositor_interface,
|
|
||||||
compositor, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_compositor *compositor =
|
struct wlr_compositor *compositor =
|
||||||
wl_container_of(listener, compositor, display_destroy);
|
wl_container_of(listener, compositor, display_destroy);
|
||||||
|
@ -204,14 +221,13 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
|
||||||
compositor->wl_global = compositor_global;
|
compositor->wl_global = compositor_global;
|
||||||
compositor->renderer = renderer;
|
compositor->renderer = renderer;
|
||||||
|
|
||||||
wl_global_create(display, &wl_subcompositor_interface, 1, compositor,
|
|
||||||
subcompositor_bind);
|
|
||||||
|
|
||||||
wl_list_init(&compositor->wl_resources);
|
wl_list_init(&compositor->wl_resources);
|
||||||
wl_list_init(&compositor->surfaces);
|
wl_list_init(&compositor->surfaces);
|
||||||
wl_signal_init(&compositor->events.new_surface);
|
wl_signal_init(&compositor->events.new_surface);
|
||||||
wl_signal_init(&compositor->events.destroy);
|
wl_signal_init(&compositor->events.destroy);
|
||||||
|
|
||||||
|
subcompositor_init(&compositor->subcompositor, display);
|
||||||
|
|
||||||
compositor->display_destroy.notify = handle_display_destroy;
|
compositor->display_destroy.notify = handle_display_destroy;
|
||||||
wl_display_add_destroy_listener(display, &compositor->display_destroy);
|
wl_display_add_destroy_listener(display, &compositor->display_destroy);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/render/egl.h>
|
#include <wlr/render/egl.h>
|
||||||
#include <wlr/render/interface.h>
|
#include <wlr/render/interface.h>
|
||||||
|
#include <wlr/types/wlr_compositor.h>
|
||||||
#include <wlr/types/wlr_matrix.h>
|
#include <wlr/types/wlr_matrix.h>
|
||||||
#include <wlr/types/wlr_region.h>
|
#include <wlr/types/wlr_region.h>
|
||||||
#include <wlr/types/wlr_surface.h>
|
#include <wlr/types/wlr_surface.h>
|
||||||
|
@ -129,8 +130,7 @@ static void surface_set_opaque_region(struct wl_client *client,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void surface_set_input_region(struct wl_client *client,
|
static void surface_set_input_region(struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
struct wl_resource *resource, struct wl_resource *region_resource) {
|
||||||
struct wl_resource *region_resource) {
|
|
||||||
struct wlr_surface *surface = wlr_surface_from_resource(resource);
|
struct wlr_surface *surface = wlr_surface_from_resource(resource);
|
||||||
surface->pending->invalid |= WLR_SURFACE_INVALID_INPUT_REGION;
|
surface->pending->invalid |= WLR_SURFACE_INVALID_INPUT_REGION;
|
||||||
if (region_resource) {
|
if (region_resource) {
|
||||||
|
@ -326,7 +326,7 @@ static void wlr_surface_damage_subsurfaces(struct wlr_subsurface *subsurface) {
|
||||||
subsurface->reordered = false;
|
subsurface->reordered = false;
|
||||||
|
|
||||||
struct wlr_subsurface *child;
|
struct wlr_subsurface *child;
|
||||||
wl_list_for_each(child, &subsurface->surface->subsurface_list, parent_link) {
|
wl_list_for_each(child, &subsurface->surface->subsurfaces, parent_link) {
|
||||||
wlr_surface_damage_subsurfaces(child);
|
wlr_surface_damage_subsurfaces(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ static void wlr_surface_commit_pending(struct wlr_surface *surface) {
|
||||||
wl_list_for_each_reverse(subsurface, &surface->subsurface_pending_list,
|
wl_list_for_each_reverse(subsurface, &surface->subsurface_pending_list,
|
||||||
parent_pending_link) {
|
parent_pending_link) {
|
||||||
wl_list_remove(&subsurface->parent_link);
|
wl_list_remove(&subsurface->parent_link);
|
||||||
wl_list_insert(&surface->subsurface_list, &subsurface->parent_link);
|
wl_list_insert(&surface->subsurfaces, &subsurface->parent_link);
|
||||||
|
|
||||||
if (subsurface->reordered) {
|
if (subsurface->reordered) {
|
||||||
// TODO: damage all the subsurfaces
|
// TODO: damage all the subsurfaces
|
||||||
|
@ -438,7 +438,7 @@ static void wlr_surface_commit_pending(struct wlr_surface *surface) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool wlr_subsurface_is_synchronized(struct wlr_subsurface *subsurface) {
|
static bool wlr_subsurface_is_synchronized(struct wlr_subsurface *subsurface) {
|
||||||
while (subsurface) {
|
while (1) {
|
||||||
if (subsurface->synchronized) {
|
if (subsurface->synchronized) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,10 @@ static bool wlr_subsurface_is_synchronized(struct wlr_subsurface *subsurface) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
subsurface = subsurface->parent->subsurface;
|
if (!wlr_surface_is_subsurface(subsurface->parent)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
subsurface = wlr_subsurface_from_surface(subsurface->parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -468,7 +471,7 @@ static void wlr_subsurface_parent_commit(struct wlr_subsurface *subsurface,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_subsurface *tmp;
|
struct wlr_subsurface *tmp;
|
||||||
wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
|
wl_list_for_each(tmp, &surface->subsurfaces, parent_link) {
|
||||||
wlr_subsurface_parent_commit(tmp, true);
|
wlr_subsurface_parent_commit(tmp, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,19 +494,19 @@ static void wlr_subsurface_commit(struct wlr_subsurface *subsurface) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_subsurface *tmp;
|
struct wlr_subsurface *tmp;
|
||||||
wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
|
wl_list_for_each(tmp, &surface->subsurfaces, parent_link) {
|
||||||
wlr_subsurface_parent_commit(tmp, false);
|
wlr_subsurface_parent_commit(tmp, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void surface_commit(struct wl_client *client,
|
static void surface_commit(struct wl_client *client,
|
||||||
struct wl_resource *resource) {
|
struct wl_resource *resource) {
|
||||||
struct wlr_surface *surface = wlr_surface_from_resource(resource);
|
struct wlr_surface *surface = wlr_surface_from_resource(resource);
|
||||||
struct wlr_subsurface *subsurface = surface->subsurface;
|
|
||||||
|
|
||||||
if (subsurface) {
|
if (wlr_surface_is_subsurface(surface)) {
|
||||||
|
struct wlr_subsurface *subsurface =
|
||||||
|
wlr_subsurface_from_surface(surface);
|
||||||
wlr_subsurface_commit(subsurface);
|
wlr_subsurface_commit(subsurface);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -511,7 +514,7 @@ static void surface_commit(struct wl_client *client,
|
||||||
wlr_surface_commit_pending(surface);
|
wlr_surface_commit_pending(surface);
|
||||||
|
|
||||||
struct wlr_subsurface *tmp;
|
struct wlr_subsurface *tmp;
|
||||||
wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
|
wl_list_for_each(tmp, &surface->subsurfaces, parent_link) {
|
||||||
wlr_subsurface_parent_commit(tmp, false);
|
wlr_subsurface_parent_commit(tmp, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -603,28 +606,26 @@ static void wlr_surface_state_destroy(struct wlr_surface_state *state) {
|
||||||
void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) {
|
void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) {
|
||||||
wlr_signal_emit_safe(&subsurface->events.destroy, subsurface);
|
wlr_signal_emit_safe(&subsurface->events.destroy, subsurface);
|
||||||
|
|
||||||
|
wl_list_remove(&subsurface->surface_destroy.link);
|
||||||
wlr_surface_state_destroy(subsurface->cached);
|
wlr_surface_state_destroy(subsurface->cached);
|
||||||
|
|
||||||
if (subsurface->parent) {
|
if (subsurface->parent) {
|
||||||
wl_list_remove(&subsurface->parent_link);
|
wl_list_remove(&subsurface->parent_link);
|
||||||
wl_list_remove(&subsurface->parent_pending_link);
|
wl_list_remove(&subsurface->parent_pending_link);
|
||||||
wl_list_remove(&subsurface->parent_destroy_listener.link);
|
wl_list_remove(&subsurface->parent_destroy.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_resource_set_user_data(subsurface->resource, NULL);
|
wl_resource_set_user_data(subsurface->resource, NULL);
|
||||||
if (subsurface->surface) {
|
if (subsurface->surface) {
|
||||||
subsurface->surface->subsurface = NULL;
|
subsurface->surface->role_data = NULL;
|
||||||
}
|
}
|
||||||
free(subsurface);
|
free(subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_surface(struct wl_resource *resource) {
|
static void destroy_surface(struct wl_resource *resource) {
|
||||||
struct wlr_surface *surface = wlr_surface_from_resource(resource);
|
struct wlr_surface *surface = wlr_surface_from_resource(resource);
|
||||||
wlr_signal_emit_safe(&surface->events.destroy, surface);
|
|
||||||
|
|
||||||
if (surface->subsurface) {
|
wlr_signal_emit_safe(&surface->events.destroy, surface);
|
||||||
wlr_subsurface_destroy(surface->subsurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_texture_destroy(surface->texture);
|
wlr_texture_destroy(surface->texture);
|
||||||
wlr_surface_state_destroy(surface->pending);
|
wlr_surface_state_destroy(surface->pending);
|
||||||
|
@ -650,7 +651,7 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res,
|
||||||
wl_signal_init(&surface->events.commit);
|
wl_signal_init(&surface->events.commit);
|
||||||
wl_signal_init(&surface->events.destroy);
|
wl_signal_init(&surface->events.destroy);
|
||||||
wl_signal_init(&surface->events.new_subsurface);
|
wl_signal_init(&surface->events.new_subsurface);
|
||||||
wl_list_init(&surface->subsurface_list);
|
wl_list_init(&surface->subsurfaces);
|
||||||
wl_list_init(&surface->subsurface_pending_list);
|
wl_list_init(&surface->subsurface_pending_list);
|
||||||
wl_resource_set_implementation(res, &surface_interface,
|
wl_resource_set_implementation(res, &surface_interface,
|
||||||
surface, destroy_surface);
|
surface, destroy_surface);
|
||||||
|
@ -720,7 +721,7 @@ static struct wlr_subsurface *subsurface_find_sibling(
|
||||||
struct wlr_surface *parent = subsurface->parent;
|
struct wlr_surface *parent = subsurface->parent;
|
||||||
|
|
||||||
struct wlr_subsurface *sibling;
|
struct wlr_subsurface *sibling;
|
||||||
wl_list_for_each(sibling, &parent->subsurface_list, parent_link) {
|
wl_list_for_each(sibling, &parent->subsurfaces, parent_link) {
|
||||||
if (sibling->surface == surface && sibling != subsurface) {
|
if (sibling->surface == surface && sibling != subsurface) {
|
||||||
return sibling;
|
return sibling;
|
||||||
}
|
}
|
||||||
|
@ -812,17 +813,23 @@ static const struct wl_subsurface_interface subsurface_implementation = {
|
||||||
static void subsurface_handle_parent_destroy(struct wl_listener *listener,
|
static void subsurface_handle_parent_destroy(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_subsurface *subsurface =
|
struct wlr_subsurface *subsurface =
|
||||||
wl_container_of(listener, subsurface, parent_destroy_listener);
|
wl_container_of(listener, subsurface, parent_destroy);
|
||||||
wl_list_remove(&subsurface->parent_link);
|
wl_list_remove(&subsurface->parent_link);
|
||||||
wl_list_remove(&subsurface->parent_pending_link);
|
wl_list_remove(&subsurface->parent_pending_link);
|
||||||
wl_list_remove(&subsurface->parent_destroy_listener.link);
|
wl_list_remove(&subsurface->parent_destroy.link);
|
||||||
subsurface->parent = NULL;
|
subsurface->parent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void subsurface_handle_surface_destroy(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct wlr_subsurface *subsurface =
|
||||||
|
wl_container_of(listener, subsurface, surface_destroy);
|
||||||
|
wlr_subsurface_destroy(subsurface);
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_surface_make_subsurface(struct wlr_surface *surface,
|
void wlr_surface_make_subsurface(struct wlr_surface *surface,
|
||||||
struct wlr_surface *parent, uint32_t id) {
|
struct wlr_surface *parent, uint32_t id) {
|
||||||
struct wl_client *client = wl_resource_get_client(surface->resource);
|
struct wl_client *client = wl_resource_get_client(surface->resource);
|
||||||
assert(surface->subsurface == NULL);
|
|
||||||
|
|
||||||
struct wlr_subsurface *subsurface =
|
struct wlr_subsurface *subsurface =
|
||||||
calloc(1, sizeof(struct wlr_subsurface));
|
calloc(1, sizeof(struct wlr_subsurface));
|
||||||
|
@ -839,14 +846,14 @@ void wlr_surface_make_subsurface(struct wlr_surface *surface,
|
||||||
subsurface->synchronized = true;
|
subsurface->synchronized = true;
|
||||||
subsurface->surface = surface;
|
subsurface->surface = surface;
|
||||||
wl_signal_init(&subsurface->events.destroy);
|
wl_signal_init(&subsurface->events.destroy);
|
||||||
|
wl_signal_add(&surface->events.destroy, &subsurface->surface_destroy);
|
||||||
|
subsurface->surface_destroy.notify = subsurface_handle_surface_destroy;
|
||||||
|
|
||||||
// link parent
|
// link parent
|
||||||
subsurface->parent = parent;
|
subsurface->parent = parent;
|
||||||
wl_signal_add(&parent->events.destroy,
|
wl_signal_add(&parent->events.destroy, &subsurface->parent_destroy);
|
||||||
&subsurface->parent_destroy_listener);
|
subsurface->parent_destroy.notify = subsurface_handle_parent_destroy;
|
||||||
subsurface->parent_destroy_listener.notify =
|
wl_list_insert(&parent->subsurfaces, &subsurface->parent_link);
|
||||||
subsurface_handle_parent_destroy;
|
|
||||||
wl_list_insert(&parent->subsurface_list, &subsurface->parent_link);
|
|
||||||
wl_list_insert(&parent->subsurface_pending_list,
|
wl_list_insert(&parent->subsurface_pending_list,
|
||||||
&subsurface->parent_pending_link);
|
&subsurface->parent_pending_link);
|
||||||
|
|
||||||
|
@ -863,21 +870,19 @@ void wlr_surface_make_subsurface(struct wlr_surface *surface,
|
||||||
&subsurface_implementation, subsurface,
|
&subsurface_implementation, subsurface,
|
||||||
subsurface_resource_destroy);
|
subsurface_resource_destroy);
|
||||||
|
|
||||||
surface->subsurface = subsurface;
|
surface->role_data = subsurface;
|
||||||
|
|
||||||
wlr_signal_emit_safe(&parent->events.new_subsurface, subsurface);
|
wlr_signal_emit_safe(&parent->events.new_subsurface, subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface) {
|
struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface) {
|
||||||
while (surface != NULL) {
|
while (wlr_surface_is_subsurface(surface)) {
|
||||||
struct wlr_subsurface *sub = surface->subsurface;
|
struct wlr_subsurface *subsurface =
|
||||||
if (sub == NULL) {
|
wlr_subsurface_from_surface(surface);
|
||||||
return surface;
|
surface = subsurface->surface;
|
||||||
}
|
|
||||||
surface = sub->parent;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_surface_point_accepts_input(struct wlr_surface *surface,
|
bool wlr_surface_point_accepts_input(struct wlr_surface *surface,
|
||||||
|
@ -890,7 +895,7 @@ bool wlr_surface_point_accepts_input(struct wlr_surface *surface,
|
||||||
struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface,
|
struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface,
|
||||||
double sx, double sy, double *sub_x, double *sub_y) {
|
double sx, double sy, double *sub_x, double *sub_y) {
|
||||||
struct wlr_subsurface *subsurface;
|
struct wlr_subsurface *subsurface;
|
||||||
wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
|
wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) {
|
||||||
double _sub_x = subsurface->surface->current->subsurface_position.x;
|
double _sub_x = subsurface->surface->current->subsurface_position.x;
|
||||||
double _sub_y = subsurface->surface->current->subsurface_position.y;
|
double _sub_y = subsurface->surface->current->subsurface_position.y;
|
||||||
struct wlr_surface *sub = wlr_surface_surface_at(subsurface->surface,
|
struct wlr_surface *sub = wlr_surface_surface_at(subsurface->surface,
|
||||||
|
@ -957,7 +962,7 @@ static void surface_for_each_surface(struct wlr_surface *surface, int x, int y,
|
||||||
iterator(surface, x, y, user_data);
|
iterator(surface, x, y, user_data);
|
||||||
|
|
||||||
struct wlr_subsurface *subsurface;
|
struct wlr_subsurface *subsurface;
|
||||||
wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
|
wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) {
|
||||||
struct wlr_surface_state *state = subsurface->surface->current;
|
struct wlr_surface_state *state = subsurface->surface->current;
|
||||||
int sx = state->subsurface_position.x;
|
int sx = state->subsurface_position.x;
|
||||||
int sy = state->subsurface_position.y;
|
int sy = state->subsurface_position.y;
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
static const char *wlr_wl_shell_surface_role = "wl-shell-surface";
|
static const char *wlr_wl_shell_surface_role = "wl-shell-surface";
|
||||||
|
|
||||||
bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface) {
|
bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface) {
|
||||||
return strcmp(surface->role, wlr_wl_shell_surface_role) == 0;
|
return surface->role != NULL &&
|
||||||
|
strcmp(surface->role, wlr_wl_shell_surface_role) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_wl_surface *wlr_wl_shell_surface_from_wlr_surface(
|
struct wlr_wl_surface *wlr_wl_shell_surface_from_wlr_surface(
|
||||||
|
|
|
@ -17,8 +17,9 @@ static const char *wlr_desktop_xdg_toplevel_role = "xdg_toplevel";
|
||||||
static const char *wlr_desktop_xdg_popup_role = "xdg_popup";
|
static const char *wlr_desktop_xdg_popup_role = "xdg_popup";
|
||||||
|
|
||||||
bool wlr_surface_is_xdg_surface(struct wlr_surface *surface) {
|
bool wlr_surface_is_xdg_surface(struct wlr_surface *surface) {
|
||||||
return strcmp(surface->role, wlr_desktop_xdg_toplevel_role) == 0 ||
|
return surface->role != NULL &&
|
||||||
strcmp(surface->role, wlr_desktop_xdg_popup_role) == 0;
|
(strcmp(surface->role, wlr_desktop_xdg_toplevel_role) == 0 ||
|
||||||
|
strcmp(surface->role, wlr_desktop_xdg_popup_role) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_xdg_surface *wlr_xdg_surface_from_wlr_surface(
|
struct wlr_xdg_surface *wlr_xdg_surface_from_wlr_surface(
|
||||||
|
|
|
@ -17,8 +17,9 @@ static const char *wlr_desktop_xdg_toplevel_role = "xdg_toplevel_v6";
|
||||||
static const char *wlr_desktop_xdg_popup_role = "xdg_popup_v6";
|
static const char *wlr_desktop_xdg_popup_role = "xdg_popup_v6";
|
||||||
|
|
||||||
bool wlr_surface_is_xdg_surface_v6(struct wlr_surface *surface) {
|
bool wlr_surface_is_xdg_surface_v6(struct wlr_surface *surface) {
|
||||||
return strcmp(surface->role, wlr_desktop_xdg_toplevel_role) == 0 ||
|
return surface->role != NULL &&
|
||||||
strcmp(surface->role, wlr_desktop_xdg_popup_role) == 0;
|
(strcmp(surface->role, wlr_desktop_xdg_toplevel_role) == 0 ||
|
||||||
|
strcmp(surface->role, wlr_desktop_xdg_popup_role) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_from_wlr_surface(
|
struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_from_wlr_surface(
|
||||||
|
|
|
@ -80,7 +80,8 @@ const char *atom_map[ATOM_LAST] = {
|
||||||
const char *wlr_xwayland_surface_role = "wlr_xwayland_surface";
|
const char *wlr_xwayland_surface_role = "wlr_xwayland_surface";
|
||||||
|
|
||||||
bool wlr_surface_is_xwayland_surface(struct wlr_surface *surface) {
|
bool wlr_surface_is_xwayland_surface(struct wlr_surface *surface) {
|
||||||
return strcmp(surface->role, wlr_xwayland_surface_role) == 0;
|
return surface->role != NULL &&
|
||||||
|
strcmp(surface->role, wlr_xwayland_surface_role) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_xwayland_surface *wlr_xwayland_surface_from_wlr_surface(
|
struct wlr_xwayland_surface *wlr_xwayland_surface_from_wlr_surface(
|
||||||
|
|
Loading…
Reference in New Issue