mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-26 22:55:58 +01:00
Merge pull request #915 from emersion/redesign-compositor-resources
compositor: redesign how resources are managed
This commit is contained in:
commit
daa293da93
5 changed files with 90 additions and 76 deletions
|
@ -6,9 +6,11 @@
|
||||||
struct wl_resource;
|
struct wl_resource;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implements the given resource as region.
|
* Creates a new region resource with the provided new ID. If `resource_list` is
|
||||||
|
* non-NULL, adds the region's resource to the list.
|
||||||
*/
|
*/
|
||||||
struct wl_resource *wlr_region_create(struct wl_client *client, uint32_t id);
|
struct wl_resource *wlr_region_create(struct wl_client *client,
|
||||||
|
uint32_t version, uint32_t id, struct wl_list *resource_list);
|
||||||
|
|
||||||
pixman_region32_t *wlr_region_from_resource(struct wl_resource *resource);
|
pixman_region32_t *wlr_region_from_resource(struct wl_resource *resource);
|
||||||
|
|
||||||
|
|
|
@ -80,10 +80,6 @@ struct wlr_surface {
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
} events;
|
} events;
|
||||||
|
|
||||||
// destroy listener used by compositor
|
|
||||||
struct wl_listener compositor_listener;
|
|
||||||
void *compositor_data;
|
|
||||||
|
|
||||||
// surface commit callback for the role that runs before all others
|
// surface commit callback for the role that runs before all others
|
||||||
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;
|
||||||
|
@ -102,8 +98,14 @@ typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface,
|
||||||
int sx, int sy, void *data);
|
int sx, int sy, void *data);
|
||||||
|
|
||||||
struct wlr_renderer;
|
struct wlr_renderer;
|
||||||
struct wlr_surface *wlr_surface_create(struct wl_resource *res,
|
|
||||||
struct wlr_renderer *renderer);
|
/**
|
||||||
|
* Create a new surface resource with the provided new ID. If `resource_list`
|
||||||
|
* is non-NULL, adds the surface's resource to the list.
|
||||||
|
*/
|
||||||
|
struct wlr_surface *wlr_surface_create(struct wl_client *client,
|
||||||
|
uint32_t version, uint32_t id, struct wlr_renderer *renderer,
|
||||||
|
struct wl_list *resource_list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the lifetime role for this surface. Returns 0 on success or -1 if the
|
* Set the lifetime role for this surface. Returns 0 on success or -1 if the
|
||||||
|
@ -121,10 +123,12 @@ int wlr_surface_set_role(struct wlr_surface *surface, const char *role,
|
||||||
bool wlr_surface_has_buffer(struct wlr_surface *surface);
|
bool wlr_surface_has_buffer(struct wlr_surface *surface);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the subsurface implementation for this surface.
|
* Create a new subsurface resource with the provided new ID. If `resource_list`
|
||||||
|
* is non-NULL, adds the subsurface's resource to the list.
|
||||||
*/
|
*/
|
||||||
struct wlr_subsurface *wlr_surface_make_subsurface(struct wlr_surface *surface,
|
struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface,
|
||||||
struct wlr_surface *parent, uint32_t id);
|
struct wlr_surface *parent, uint32_t version, uint32_t id,
|
||||||
|
struct wl_list *resource_list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the root of the subsurface tree for this surface.
|
* Get the root of the subsurface tree for this surface.
|
||||||
|
|
|
@ -75,14 +75,8 @@ static void subcompositor_handle_get_subsurface(struct wl_client *client,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_subsurface *subsurface =
|
wlr_subsurface_create(surface, parent, wl_resource_get_version(resource),
|
||||||
wlr_surface_make_subsurface(surface, parent, id);
|
id, &subcompositor->subsurface_resources);
|
||||||
if (subsurface == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_list_insert(&subcompositor->subsurface_resources,
|
|
||||||
wl_resource_get_link(subsurface->resource));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_subcompositor_interface subcompositor_impl = {
|
static const struct wl_subcompositor_interface subcompositor_impl = {
|
||||||
|
@ -142,36 +136,17 @@ static struct wlr_compositor *compositor_from_resource(
|
||||||
return wl_resource_get_user_data(resource);
|
return wl_resource_get_user_data(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compositor_handle_surface_destroy(struct wl_listener *listener,
|
|
||||||
void *data) {
|
|
||||||
wl_list_remove(wl_resource_get_link(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wl_compositor_create_surface(struct wl_client *client,
|
static void wl_compositor_create_surface(struct wl_client *client,
|
||||||
struct wl_resource *resource, uint32_t id) {
|
struct wl_resource *resource, uint32_t id) {
|
||||||
struct wlr_compositor *compositor = compositor_from_resource(resource);
|
struct wlr_compositor *compositor = compositor_from_resource(resource);
|
||||||
|
|
||||||
struct wl_resource *surface_resource = wl_resource_create(client,
|
struct wlr_surface *surface = wlr_surface_create(client,
|
||||||
&wl_surface_interface, wl_resource_get_version(resource), id);
|
wl_resource_get_version(resource), id, compositor->renderer,
|
||||||
if (surface_resource == NULL) {
|
&compositor->surface_resources);
|
||||||
wl_resource_post_no_memory(resource);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_surface *surface = wlr_surface_create(surface_resource,
|
|
||||||
compositor->renderer);
|
|
||||||
if (surface == NULL) {
|
if (surface == NULL) {
|
||||||
wl_resource_destroy(surface_resource);
|
|
||||||
wl_resource_post_no_memory(resource);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
surface->compositor_data = compositor;
|
|
||||||
surface->compositor_listener.notify = compositor_handle_surface_destroy;
|
|
||||||
wl_resource_add_destroy_listener(surface_resource,
|
|
||||||
&surface->compositor_listener);
|
|
||||||
|
|
||||||
wl_list_insert(&compositor->surface_resources,
|
|
||||||
wl_resource_get_link(surface_resource));
|
|
||||||
wlr_signal_emit_safe(&compositor->events.new_surface, surface);
|
wlr_signal_emit_safe(&compositor->events.new_surface, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,14 +154,7 @@ static void wl_compositor_create_region(struct wl_client *client,
|
||||||
struct wl_resource *resource, uint32_t id) {
|
struct wl_resource *resource, uint32_t id) {
|
||||||
struct wlr_compositor *compositor = compositor_from_resource(resource);
|
struct wlr_compositor *compositor = compositor_from_resource(resource);
|
||||||
|
|
||||||
struct wl_resource *region_resource = wlr_region_create(client, id);
|
wlr_region_create(client, 1, id, &compositor->region_resources);
|
||||||
if (region_resource == NULL) {
|
|
||||||
wl_resource_post_no_memory(resource);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_list_insert(&compositor->region_resources,
|
|
||||||
wl_resource_get_link(region_resource));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_compositor_interface compositor_impl = {
|
static const struct wl_compositor_interface compositor_impl = {
|
||||||
|
|
|
@ -34,29 +34,40 @@ static const struct wl_region_interface region_impl = {
|
||||||
|
|
||||||
static void region_handle_resource_destroy(struct wl_resource *resource) {
|
static void region_handle_resource_destroy(struct wl_resource *resource) {
|
||||||
pixman_region32_t *reg = wlr_region_from_resource(resource);
|
pixman_region32_t *reg = wlr_region_from_resource(resource);
|
||||||
|
|
||||||
|
wl_list_remove(wl_resource_get_link(resource));
|
||||||
|
|
||||||
pixman_region32_fini(reg);
|
pixman_region32_fini(reg);
|
||||||
free(reg);
|
free(reg);
|
||||||
|
|
||||||
// Set by wlr_compositor
|
|
||||||
wl_list_remove(wl_resource_get_link(resource));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wl_resource *wlr_region_create(struct wl_client *client, uint32_t id) {
|
struct wl_resource *wlr_region_create(struct wl_client *client,
|
||||||
|
uint32_t version, uint32_t id, struct wl_list *resource_list) {
|
||||||
pixman_region32_t *region = calloc(1, sizeof(pixman_region32_t));
|
pixman_region32_t *region = calloc(1, sizeof(pixman_region32_t));
|
||||||
if (region == NULL) {
|
if (region == NULL) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixman_region32_init(region);
|
pixman_region32_init(region);
|
||||||
|
|
||||||
struct wl_resource *region_resource = wl_resource_create(client,
|
struct wl_resource *region_resource = wl_resource_create(client,
|
||||||
&wl_region_interface, 1, id);
|
&wl_region_interface, version, id);
|
||||||
if (region_resource == NULL) {
|
if (region_resource == NULL) {
|
||||||
free(region);
|
free(region);
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
wl_resource_set_implementation(region_resource, ®ion_impl, region,
|
wl_resource_set_implementation(region_resource, ®ion_impl, region,
|
||||||
region_handle_resource_destroy);
|
region_handle_resource_destroy);
|
||||||
|
|
||||||
|
struct wl_list *resource_link = wl_resource_get_link(region_resource);
|
||||||
|
if (resource_list != NULL) {
|
||||||
|
wl_list_insert(resource_list, resource_link);
|
||||||
|
} else {
|
||||||
|
wl_list_init(resource_link);
|
||||||
|
}
|
||||||
|
|
||||||
return region_resource;
|
return region_resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -615,6 +615,8 @@ static void subsurface_destroy(struct wlr_subsurface *subsurface) {
|
||||||
wl_list_remove(&subsurface->parent_destroy.link);
|
wl_list_remove(&subsurface->parent_destroy.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_list_remove(wl_resource_get_link(subsurface->resource));
|
||||||
|
|
||||||
wl_resource_set_user_data(subsurface->resource, NULL);
|
wl_resource_set_user_data(subsurface->resource, NULL);
|
||||||
if (subsurface->surface) {
|
if (subsurface->surface) {
|
||||||
subsurface->surface->role_data = NULL;
|
subsurface->surface->role_data = NULL;
|
||||||
|
@ -627,6 +629,9 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) {
|
||||||
|
|
||||||
wlr_signal_emit_safe(&surface->events.destroy, surface);
|
wlr_signal_emit_safe(&surface->events.destroy, surface);
|
||||||
|
|
||||||
|
wl_list_remove(wl_resource_get_link(surface->resource));
|
||||||
|
|
||||||
|
wl_list_remove(&surface->renderer_destroy.link);
|
||||||
wlr_texture_destroy(surface->texture);
|
wlr_texture_destroy(surface->texture);
|
||||||
surface_state_destroy(surface->pending);
|
surface_state_destroy(surface->pending);
|
||||||
surface_state_destroy(surface->current);
|
surface_state_destroy(surface->current);
|
||||||
|
@ -641,16 +646,27 @@ static void surface_handle_renderer_destroy(struct wl_listener *listener,
|
||||||
wl_resource_destroy(surface->resource);
|
wl_resource_destroy(surface->resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_surface *wlr_surface_create(struct wl_resource *res,
|
struct wlr_surface *wlr_surface_create(struct wl_client *client,
|
||||||
struct wlr_renderer *renderer) {
|
uint32_t version, uint32_t id, struct wlr_renderer *renderer,
|
||||||
|
struct wl_list *resource_list) {
|
||||||
struct wlr_surface *surface = calloc(1, sizeof(struct wlr_surface));
|
struct wlr_surface *surface = calloc(1, sizeof(struct wlr_surface));
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
wl_resource_post_no_memory(res);
|
wl_client_post_no_memory(client);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
wlr_log(L_DEBUG, "New wlr_surface %p (res %p)", surface, res);
|
surface->resource = wl_resource_create(client, &wl_surface_interface,
|
||||||
|
version, id);
|
||||||
|
if (surface->resource == NULL) {
|
||||||
|
free(surface);
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wl_resource_set_implementation(surface->resource, &surface_interface,
|
||||||
|
surface, surface_handle_resource_destroy);
|
||||||
|
|
||||||
|
wlr_log(L_DEBUG, "New wlr_surface %p (res %p)", surface, surface->resource);
|
||||||
|
|
||||||
surface->renderer = renderer;
|
surface->renderer = renderer;
|
||||||
surface->resource = res;
|
|
||||||
|
|
||||||
surface->current = surface_state_create();
|
surface->current = surface_state_create();
|
||||||
surface->pending = surface_state_create();
|
surface->pending = surface_state_create();
|
||||||
|
@ -660,12 +676,17 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res,
|
||||||
wl_signal_init(&surface->events.new_subsurface);
|
wl_signal_init(&surface->events.new_subsurface);
|
||||||
wl_list_init(&surface->subsurfaces);
|
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,
|
|
||||||
surface, surface_handle_resource_destroy);
|
|
||||||
|
|
||||||
wl_signal_add(&renderer->events.destroy, &surface->renderer_destroy);
|
wl_signal_add(&renderer->events.destroy, &surface->renderer_destroy);
|
||||||
surface->renderer_destroy.notify = surface_handle_renderer_destroy;
|
surface->renderer_destroy.notify = surface_handle_renderer_destroy;
|
||||||
|
|
||||||
|
struct wl_list *resource_link = wl_resource_get_link(surface->resource);
|
||||||
|
if (resource_list != NULL) {
|
||||||
|
wl_list_insert(resource_list, resource_link);
|
||||||
|
} else {
|
||||||
|
wl_list_init(resource_link);
|
||||||
|
}
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -838,8 +859,9 @@ static void subsurface_handle_surface_destroy(struct wl_listener *listener,
|
||||||
subsurface_destroy(subsurface);
|
subsurface_destroy(subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_subsurface *wlr_surface_make_subsurface(struct wlr_surface *surface,
|
struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface,
|
||||||
struct wlr_surface *parent, uint32_t id) {
|
struct wlr_surface *parent, uint32_t version, uint32_t id,
|
||||||
|
struct wl_list *resource_list) {
|
||||||
struct wl_client *client = wl_resource_get_client(surface->resource);
|
struct wl_client *client = wl_resource_get_client(surface->resource);
|
||||||
|
|
||||||
struct wlr_subsurface *subsurface =
|
struct wlr_subsurface *subsurface =
|
||||||
|
@ -856,7 +878,20 @@ struct wlr_subsurface *wlr_surface_make_subsurface(struct wlr_surface *surface,
|
||||||
}
|
}
|
||||||
subsurface->synchronized = true;
|
subsurface->synchronized = true;
|
||||||
subsurface->surface = surface;
|
subsurface->surface = surface;
|
||||||
|
subsurface->resource =
|
||||||
|
wl_resource_create(client, &wl_subsurface_interface, version, id);
|
||||||
|
if (subsurface->resource == NULL) {
|
||||||
|
surface_state_destroy(subsurface->cached);
|
||||||
|
free(subsurface);
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wl_resource_set_implementation(subsurface->resource,
|
||||||
|
&subsurface_implementation, subsurface,
|
||||||
|
subsurface_resource_destroy);
|
||||||
|
|
||||||
wl_signal_init(&subsurface->events.destroy);
|
wl_signal_init(&subsurface->events.destroy);
|
||||||
|
|
||||||
wl_signal_add(&surface->events.destroy, &subsurface->surface_destroy);
|
wl_signal_add(&surface->events.destroy, &subsurface->surface_destroy);
|
||||||
subsurface->surface_destroy.notify = subsurface_handle_surface_destroy;
|
subsurface->surface_destroy.notify = subsurface_handle_surface_destroy;
|
||||||
|
|
||||||
|
@ -868,21 +903,15 @@ struct wlr_subsurface *wlr_surface_make_subsurface(struct wlr_surface *surface,
|
||||||
wl_list_insert(&parent->subsurface_pending_list,
|
wl_list_insert(&parent->subsurface_pending_list,
|
||||||
&subsurface->parent_pending_link);
|
&subsurface->parent_pending_link);
|
||||||
|
|
||||||
subsurface->resource =
|
|
||||||
wl_resource_create(client, &wl_subsurface_interface, 1, id);
|
|
||||||
if (subsurface->resource == NULL) {
|
|
||||||
surface_state_destroy(subsurface->cached);
|
|
||||||
free(subsurface);
|
|
||||||
wl_client_post_no_memory(client);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_resource_set_implementation(subsurface->resource,
|
|
||||||
&subsurface_implementation, subsurface,
|
|
||||||
subsurface_resource_destroy);
|
|
||||||
|
|
||||||
surface->role_data = subsurface;
|
surface->role_data = subsurface;
|
||||||
|
|
||||||
|
struct wl_list *resource_link = wl_resource_get_link(subsurface->resource);
|
||||||
|
if (resource_list != NULL) {
|
||||||
|
wl_list_insert(resource_list, resource_link);
|
||||||
|
} else {
|
||||||
|
wl_list_init(resource_link);
|
||||||
|
}
|
||||||
|
|
||||||
wlr_signal_emit_safe(&parent->events.new_subsurface, subsurface);
|
wlr_signal_emit_safe(&parent->events.new_subsurface, subsurface);
|
||||||
|
|
||||||
return subsurface;
|
return subsurface;
|
||||||
|
|
Loading…
Reference in a new issue