From cb815e88476cac1fb5ce2e369672e4beb4f5d469 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Tue, 6 Feb 2024 21:51:37 +0300 Subject: pointer-constraints: handle inert pointer resources correctly --- types/wlr_pointer_constraints_v1.c | 40 ++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/types/wlr_pointer_constraints_v1.c b/types/wlr_pointer_constraints_v1.c index f29b16d6..f3c8fb74 100644 --- a/types/wlr_pointer_constraints_v1.c +++ b/types/wlr_pointer_constraints_v1.c @@ -194,17 +194,8 @@ static void pointer_constraint_create(struct wl_client *client, pointer_constraints_from_resource(pointer_constraints_resource); struct wlr_surface *surface = wlr_surface_from_resource(surface_resource); - struct wlr_seat *seat = - wlr_seat_client_from_pointer_resource(pointer_resource)->seat; - - if (wlr_pointer_constraints_v1_constraint_for_surface(pointer_constraints, - surface, seat)) { - wl_resource_post_error(pointer_constraints_resource, - ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED, - "a pointer constraint with a wl_pointer of the same wl_seat" - " is already on this surface"); - return; - } + struct wlr_seat_client *seat_client = + wlr_seat_client_from_pointer_resource(pointer_resource); uint32_t version = wl_resource_get_version(pointer_constraints_resource); @@ -218,6 +209,28 @@ static void pointer_constraint_create(struct wl_client *client, return; } + void *impl = locked_pointer ? + (void *)&locked_pointer_impl : (void *)&confined_pointer_impl; + wl_resource_set_implementation(resource, impl, NULL, + pointer_constraint_destroy_resource); + + if (seat_client == NULL) { + // Leave the resource inert + return; + } + + struct wlr_seat *seat = seat_client->seat; + + if (wlr_pointer_constraints_v1_constraint_for_surface(pointer_constraints, + surface, seat)) { + wl_resource_destroy(resource); + wl_resource_post_error(pointer_constraints_resource, + ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED, + "a pointer constraint with a wl_pointer of the same wl_seat" + " is already on this surface"); + return; + } + struct wlr_pointer_constraint_v1 *constraint = calloc(1, sizeof(*constraint)); if (constraint == NULL) { wl_resource_destroy(resource); @@ -260,10 +273,7 @@ static void pointer_constraint_create(struct wl_client *client, constraint->seat_destroy.notify = handle_seat_destroy; wl_signal_add(&seat->events.destroy, &constraint->seat_destroy); - void *impl = locked_pointer ? - (void *)&locked_pointer_impl : (void *)&confined_pointer_impl; - wl_resource_set_implementation(constraint->resource, impl, constraint, - pointer_constraint_destroy_resource); + wl_resource_set_user_data(resource, constraint); wlr_log(WLR_DEBUG, "new %s_pointer %p (res %p)", locked_pointer ? "locked" : "confined", -- cgit v1.2.3