compositor: replace role_data with role_resource

This increases type safety, makes it more obvious that role_data
must represent the role object, and will allow for automatic
cleanup when the resource is destroyed.
This commit is contained in:
Simon Ser 2023-06-23 14:23:27 +02:00
parent 00f1870d35
commit 89cb484220
10 changed files with 43 additions and 38 deletions

View file

@ -167,7 +167,7 @@ struct wlr_surface {
* The role object representing the role. NULL if the role isn't * The role object representing the role. NULL if the role isn't
* represented by any object or the object was destroyed. * represented by any object or the object was destroyed.
*/ */
void *role_data; struct wl_resource *role_resource;
struct { struct {
struct wl_signal client_commit; struct wl_signal client_commit;
@ -247,7 +247,7 @@ bool wlr_surface_set_role(struct wlr_surface *surface, const struct wlr_surface_
* Set the role object for this surface. The surface must have a role and * Set the role object for this surface. The surface must have a role and
* no already set role object. * no already set role object.
*/ */
void wlr_surface_set_role_object(struct wlr_surface *surface, void *role_data); void wlr_surface_set_role_object(struct wlr_surface *surface, struct wl_resource *role_resource);
/** /**
* Destroy the object representing the surface's role. If it doesn't exist, * Destroy the object representing the surface's role. If it doesn't exist,

View file

@ -37,7 +37,7 @@ static int max(int fst, int snd) {
static void surface_handle_destroy(struct wl_client *client, static void surface_handle_destroy(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);
if (surface->role_data != NULL) { if (surface->role_resource != NULL) {
wl_resource_post_error(resource, wl_resource_post_error(resource,
WL_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT, WL_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT,
"surface was destroyed before its role object"); "surface was destroyed before its role object");
@ -492,7 +492,7 @@ static void surface_commit_state(struct wlr_surface *surface,
} }
if (surface->role != NULL && surface->role->commit != NULL && if (surface->role != NULL && surface->role->commit != NULL &&
(surface->role_data != NULL || surface->role->no_object)) { (surface->role_resource != NULL || surface->role->no_object)) {
surface->role->commit(surface); surface->role->commit(surface);
} }
@ -753,7 +753,7 @@ void wlr_surface_unmap(struct wlr_surface *surface) {
surface->mapped = false; surface->mapped = false;
wl_signal_emit_mutable(&surface->events.unmap, NULL); wl_signal_emit_mutable(&surface->events.unmap, NULL);
if (surface->role != NULL && surface->role->unmap != NULL && if (surface->role != NULL && surface->role->unmap != NULL &&
(surface->role_data != NULL || surface->role->no_object)) { (surface->role_resource != NULL || surface->role->no_object)) {
surface->role->unmap(surface); surface->role->unmap(surface);
} }
@ -779,7 +779,7 @@ bool wlr_surface_set_role(struct wlr_surface *surface, const struct wlr_surface_
} }
return false; return false;
} }
if (surface->role_data != NULL) { if (surface->role_resource != NULL) {
wl_resource_post_error(error_resource, error_code, wl_resource_post_error(error_resource, error_code,
"Cannot reassign role %s to wl_surface@%" PRIu32 ", role object still exists", "Cannot reassign role %s to wl_surface@%" PRIu32 ", role object still exists",
role->name, wl_resource_get_id(surface->resource)); role->name, wl_resource_get_id(surface->resource));
@ -790,23 +790,23 @@ bool wlr_surface_set_role(struct wlr_surface *surface, const struct wlr_surface_
return true; return true;
} }
void wlr_surface_set_role_object(struct wlr_surface *surface, void *role_data) { void wlr_surface_set_role_object(struct wlr_surface *surface, struct wl_resource *role_resource) {
assert(surface->role != NULL); assert(surface->role != NULL);
assert(!surface->role->no_object); assert(!surface->role->no_object);
assert(surface->role_data == NULL); assert(surface->role_resource == NULL);
assert(role_data != NULL); assert(role_resource != NULL);
surface->role_data = role_data; surface->role_resource = role_resource;
} }
void wlr_surface_destroy_role_object(struct wlr_surface *surface) { void wlr_surface_destroy_role_object(struct wlr_surface *surface) {
if (surface->role_data == NULL) { if (surface->role_resource == NULL) {
return; return;
} }
wlr_surface_unmap(surface); wlr_surface_unmap(surface);
if (surface->role->destroy != NULL) { if (surface->role->destroy != NULL) {
surface->role->destroy(surface); surface->role->destroy(surface);
} }
surface->role_data = NULL; surface->role_resource = NULL;
} }
uint32_t wlr_surface_lock_pending(struct wlr_surface *surface) { uint32_t wlr_surface_lock_pending(struct wlr_surface *surface) {

View file

@ -138,12 +138,14 @@ static void popup_surface_consider_map(struct wlr_input_popup_surface_v2 *popup_
} }
static void popup_surface_surface_role_commit(struct wlr_surface *surface) { static void popup_surface_surface_role_commit(struct wlr_surface *surface) {
struct wlr_input_popup_surface_v2 *popup_surface = surface->role_data; struct wlr_input_popup_surface_v2 *popup_surface =
wlr_input_popup_surface_v2_try_from_wlr_surface(surface);
popup_surface_consider_map(popup_surface); popup_surface_consider_map(popup_surface);
} }
static void popup_surface_surface_role_destroy(struct wlr_surface *surface) { static void popup_surface_surface_role_destroy(struct wlr_surface *surface) {
struct wlr_input_popup_surface_v2 *popup_surface = surface->role_data; struct wlr_input_popup_surface_v2 *popup_surface =
wlr_input_popup_surface_v2_try_from_wlr_surface(surface);
wl_signal_emit_mutable(&popup_surface->events.destroy, NULL); wl_signal_emit_mutable(&popup_surface->events.destroy, NULL);
wl_list_remove(&popup_surface->link); wl_list_remove(&popup_surface->link);
@ -157,14 +159,6 @@ static const struct wlr_surface_role input_popup_surface_v2_role = {
.destroy = popup_surface_surface_role_destroy, .destroy = popup_surface_surface_role_destroy,
}; };
struct wlr_input_popup_surface_v2 *wlr_input_popup_surface_v2_try_from_wlr_surface(
struct wlr_surface *surface) {
if (surface->role != &input_popup_surface_v2_role) {
return NULL;
}
return (struct wlr_input_popup_surface_v2 *)surface->role_data;
}
static const struct zwp_input_popup_surface_v2_interface input_popup_impl; static const struct zwp_input_popup_surface_v2_interface input_popup_impl;
static struct wlr_input_popup_surface_v2 *popup_surface_from_resource(struct wl_resource *resource) { static struct wlr_input_popup_surface_v2 *popup_surface_from_resource(struct wl_resource *resource) {
@ -173,6 +167,14 @@ static struct wlr_input_popup_surface_v2 *popup_surface_from_resource(struct wl_
return wl_resource_get_user_data(resource); return wl_resource_get_user_data(resource);
} }
struct wlr_input_popup_surface_v2 *wlr_input_popup_surface_v2_try_from_wlr_surface(
struct wlr_surface *surface) {
if (surface->role != &input_popup_surface_v2_role || surface->role_resource == NULL) {
return NULL;
}
return popup_surface_from_resource(surface->role_resource);
}
static void popup_resource_destroy(struct wl_resource *resource) { static void popup_resource_destroy(struct wl_resource *resource) {
struct wlr_input_popup_surface_v2 *popup_surface = struct wlr_input_popup_surface_v2 *popup_surface =
popup_surface_from_resource(resource); popup_surface_from_resource(resource);
@ -225,7 +227,7 @@ static void im_get_input_popup_surface(struct wl_client *client,
wl_resource_set_implementation(popup_resource, &input_popup_impl, wl_resource_set_implementation(popup_resource, &input_popup_impl,
popup_surface, popup_resource_destroy); popup_surface, popup_resource_destroy);
wlr_surface_set_role_object(surface, popup_surface); wlr_surface_set_role_object(surface, popup_resource);
popup_surface->resource = popup_resource; popup_surface->resource = popup_resource;
popup_surface->input_method = input_method; popup_surface->input_method = input_method;

View file

@ -40,10 +40,10 @@ static const struct wlr_surface_role layer_surface_role;
struct wlr_layer_surface_v1 *wlr_layer_surface_v1_try_from_wlr_surface( struct wlr_layer_surface_v1 *wlr_layer_surface_v1_try_from_wlr_surface(
struct wlr_surface *surface) { struct wlr_surface *surface) {
if (surface->role != &layer_surface_role) { if (surface->role != &layer_surface_role || surface->role_resource == NULL) {
return NULL; return NULL;
} }
return (struct wlr_layer_surface_v1 *)surface->role_data; return wlr_layer_surface_v1_from_resource(surface->role_resource);
} }
static void layer_surface_configure_destroy( static void layer_surface_configure_destroy(
@ -445,7 +445,7 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client,
wl_resource_set_implementation(surface->resource, wl_resource_set_implementation(surface->resource,
&layer_surface_implementation, surface, layer_surface_resource_destroy); &layer_surface_implementation, surface, layer_surface_resource_destroy);
wlr_surface_set_role_object(wlr_surface, surface); wlr_surface_set_role_object(wlr_surface, surface->resource);
} }
static const struct zwlr_layer_shell_v1_interface layer_shell_implementation = { static const struct zwlr_layer_shell_v1_interface layer_shell_implementation = {

View file

@ -50,10 +50,10 @@ static const struct wlr_surface_role lock_surface_role;
struct wlr_session_lock_surface_v1 *wlr_session_lock_surface_v1_try_from_wlr_surface( struct wlr_session_lock_surface_v1 *wlr_session_lock_surface_v1_try_from_wlr_surface(
struct wlr_surface *surface) { struct wlr_surface *surface) {
if (surface->role != &lock_surface_role) { if (surface->role != &lock_surface_role || surface->role_resource == NULL) {
return NULL; return NULL;
} }
return (struct wlr_session_lock_surface_v1 *)surface->role_data; return lock_surface_from_resource(surface->role_resource);
} }
uint32_t wlr_session_lock_surface_v1_configure( uint32_t wlr_session_lock_surface_v1_configure(
@ -274,7 +274,7 @@ static void lock_handle_get_lock_surface(struct wl_client *client,
lock_surface->resource = lock_surface_resource; lock_surface->resource = lock_surface_resource;
wl_resource_set_user_data(lock_surface_resource, lock_surface); wl_resource_set_user_data(lock_surface_resource, lock_surface);
wlr_surface_set_role_object(surface, lock_surface); wlr_surface_set_role_object(surface, lock_surface_resource);
wl_list_insert(&lock->surfaces, &lock_surface->link); wl_list_insert(&lock->surfaces, &lock_surface->link);

View file

@ -293,10 +293,10 @@ void subsurface_handle_parent_commit(struct wlr_subsurface *subsurface) {
} }
struct wlr_subsurface *wlr_subsurface_try_from_wlr_surface(struct wlr_surface *surface) { struct wlr_subsurface *wlr_subsurface_try_from_wlr_surface(struct wlr_surface *surface) {
if (surface->role != &subsurface_role) { if (surface->role != &subsurface_role || surface->role_resource == NULL) {
return NULL; return NULL;
} }
return (struct wlr_subsurface *)surface->role_data; return subsurface_from_resource(surface->role_resource);
} }
static void subcompositor_handle_destroy(struct wl_client *client, static void subcompositor_handle_destroy(struct wl_client *client,
@ -344,7 +344,7 @@ static void subcompositor_handle_get_subsurface(struct wl_client *client,
wl_resource_set_implementation(subsurface->resource, wl_resource_set_implementation(subsurface->resource,
&subsurface_implementation, subsurface, subsurface_resource_destroy); &subsurface_implementation, subsurface, subsurface_resource_destroy);
wlr_surface_set_role_object(surface, subsurface); wlr_surface_set_role_object(surface, subsurface->resource);
wl_signal_init(&subsurface->events.destroy); wl_signal_init(&subsurface->events.destroy);

View file

@ -412,7 +412,7 @@ void create_xdg_popup(struct wlr_xdg_surface *surface,
&xdg_popup_implementation, surface->popup, &xdg_popup_implementation, surface->popup,
xdg_popup_handle_resource_destroy); xdg_popup_handle_resource_destroy);
wlr_surface_set_role_object(surface->surface, surface); wlr_surface_set_role_object(surface->surface, surface->resource);
surface->role = WLR_XDG_SURFACE_ROLE_POPUP; surface->role = WLR_XDG_SURFACE_ROLE_POPUP;

View file

@ -11,7 +11,10 @@ struct wlr_xdg_surface *wlr_xdg_surface_try_from_wlr_surface(
surface->role != &xdg_popup_surface_role) { surface->role != &xdg_popup_surface_role) {
return NULL; return NULL;
} }
return (struct wlr_xdg_surface *)surface->role_data; if (surface->role_resource == NULL) {
return NULL;
}
return wlr_xdg_surface_from_resource(surface->role_resource);
} }
static void xdg_surface_configure_destroy( static void xdg_surface_configure_destroy(

View file

@ -524,7 +524,7 @@ void create_xdg_toplevel(struct wlr_xdg_surface *surface,
&xdg_toplevel_implementation, surface->toplevel, &xdg_toplevel_implementation, surface->toplevel,
xdg_toplevel_handle_resource_destroy); xdg_toplevel_handle_resource_destroy);
wlr_surface_set_role_object(surface->surface, surface); wlr_surface_set_role_object(surface->surface, surface->resource);
surface->role = WLR_XDG_SURFACE_ROLE_TOPLEVEL; surface->role = WLR_XDG_SURFACE_ROLE_TOPLEVEL;
} }

View file

@ -38,7 +38,7 @@ static struct wlr_xwayland_surface_v1 *xwl_surface_from_resource(
} }
static void xwl_surface_role_commit(struct wlr_surface *surface) { static void xwl_surface_role_commit(struct wlr_surface *surface) {
struct wlr_xwayland_surface_v1 *xwl_surface = surface->role_data; struct wlr_xwayland_surface_v1 *xwl_surface = xwl_surface_from_resource(surface->role_resource);
if (xwl_surface->serial != 0 && !xwl_surface->added) { if (xwl_surface->serial != 0 && !xwl_surface->added) {
xwl_surface->added = true; xwl_surface->added = true;
@ -48,7 +48,7 @@ static void xwl_surface_role_commit(struct wlr_surface *surface) {
} }
static void xwl_surface_role_destroy(struct wlr_surface *surface) { static void xwl_surface_role_destroy(struct wlr_surface *surface) {
struct wlr_xwayland_surface_v1 *xwl_surface = surface->role_data; struct wlr_xwayland_surface_v1 *xwl_surface = xwl_surface_from_resource(surface->role_resource);
wl_list_remove(&xwl_surface->surface_destroy.link); wl_list_remove(&xwl_surface->surface_destroy.link);
wl_list_remove(&xwl_surface->link); wl_list_remove(&xwl_surface->link);
wl_resource_set_user_data(xwl_surface->resource, NULL); // make inert wl_resource_set_user_data(xwl_surface->resource, NULL); // make inert
@ -131,7 +131,7 @@ static void shell_handle_get_xwayland_surface(struct wl_client *client,
wl_resource_set_implementation(xwl_surface->resource, &xwl_surface_impl, wl_resource_set_implementation(xwl_surface->resource, &xwl_surface_impl,
xwl_surface, xwl_surface_handle_resource_destroy); xwl_surface, xwl_surface_handle_resource_destroy);
wlr_surface_set_role_object(surface, xwl_surface); wlr_surface_set_role_object(surface, xwl_surface->resource);
wl_list_insert(&shell->surfaces, &xwl_surface->link); wl_list_insert(&shell->surfaces, &xwl_surface->link);