aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Primak <vyivel@eclair.cafe>2024-02-06 21:51:37 +0300
committerKirill Primak <vyivel@eclair.cafe>2024-02-06 22:06:09 +0300
commitcb815e88476cac1fb5ce2e369672e4beb4f5d469 (patch)
tree24ecda969c9684e77aaa7ae7d13bfe09473b9d77
parent4cd556ea20d4a598a36e4e2349acb45cc4246383 (diff)
pointer-constraints: handle inert pointer resources correctly
-rw-r--r--types/wlr_pointer_constraints_v1.c40
1 files 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",