From c0537096c242d120b9625f7fc57bb6526e6f38ad Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Fri, 10 May 2024 20:36:37 +0200 Subject: [PATCH 1/5] pointer-constraints/native: Consider origin when checking constraints Since 07d24fe50 regions are not translated to their on-screen coordinates anymore, but are relative to the origin stored in the constraint. This origin however was not considered when checking whether the pointer was within the constraint region. This meant that the constraint region would appear to always be placed at 0,0 instead of on the surface. Fix this by using the cursor position relative to the origin. Fixes: 07d24fe50 ("backends/native: Allow infinitely small pointer constraint regions") Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3409 Part-of: --- .../native/meta-pointer-constraint-native.c | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/backends/native/meta-pointer-constraint-native.c b/src/backends/native/meta-pointer-constraint-native.c index 94ad2437933..e3bbdd739b7 100644 --- a/src/backends/native/meta-pointer-constraint-native.c +++ b/src/backends/native/meta-pointer-constraint-native.c @@ -496,12 +496,12 @@ meta_pointer_constraint_impl_native_constraint (MetaPointerConstraintImpl *const motion = (MetaLine2) { .a = (MetaVector2) { - .x = prev_x, - .y = prev_y, + .x = prev_x - constraint_impl_native->origin.x, + .y = prev_y - constraint_impl_native->origin.y, }, .b = (MetaVector2) { - .x = x, - .y = y, + .x = x - constraint_impl_native->origin.x, + .y = y - constraint_impl_native->origin.y, }, }; directions = get_motion_directions (&motion); @@ -522,8 +522,8 @@ meta_pointer_constraint_impl_native_constraint (MetaPointerConstraintImpl *const } } - *x_inout = motion.b.x; - *y_inout = motion.b.y; + *x_inout = motion.b.x + constraint_impl_native->origin.x; + *y_inout = motion.b.y + constraint_impl_native->origin.y; } static float @@ -602,6 +602,8 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp g_autoptr (MtkRegion) region = NULL; float x; float y; + float rel_x; + float rel_y; constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (constraint_impl); region = mtk_region_ref (constraint_impl_native->region); @@ -610,6 +612,8 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp clutter_seat_query_state (seat, device, NULL, &point, NULL); x = point.x; y = point.y; + rel_x = x - constraint_impl_native->origin.x; + rel_y = y - constraint_impl_native->origin.y; if (mtk_region_is_empty (region)) { @@ -617,9 +621,7 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp y != constraint_impl_native->origin.y) clutter_seat_warp_pointer (seat, x, y); } - else if (!mtk_region_contains_point (region, - (int) x - constraint_impl_native->origin.x, - (int) y - constraint_impl_native->origin.y)) + else if (!mtk_region_contains_point (region, (int) rel_x, (int) rel_y)) { g_autoptr (GArray) borders = NULL; float closest_distance_2 = FLT_MAX; @@ -635,7 +637,7 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp MetaBorder *border = &g_array_index (borders, MetaBorder, i); float distance_2; - distance_2 = point_to_border_distance_2 (border, x, y); + distance_2 = point_to_border_distance_2 (border, rel_x, rel_y); if (distance_2 < closest_distance_2) { closest_border = border; @@ -643,9 +645,11 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp } } - closest_point_behind_border (closest_border, &x, &y); + closest_point_behind_border (closest_border, &rel_x, &rel_y); - clutter_seat_warp_pointer (seat, x, y); + clutter_seat_warp_pointer (seat, + rel_x + constraint_impl_native->origin.x, + rel_y + constraint_impl_native->origin.y); } } -- GitLab From d6868659180b87bcaa424767f4b49d0d9721ef7f Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Sat, 11 May 2024 20:12:26 +0200 Subject: [PATCH 2/5] pointer-constraints/native: Warp locked pointer to correct position In case of empty regions (e.g. when locking the pointer) the pointer was only forced to stay within the boundaries of its current pixel (i.e. culling subpixel position), instead of the position where the pointer lock did start. Fixes: 07d24fe50 ("backends/native: Allow infinitely small pointer constraint regions") Part-of: --- src/backends/native/meta-pointer-constraint-native.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backends/native/meta-pointer-constraint-native.c b/src/backends/native/meta-pointer-constraint-native.c index e3bbdd739b7..390e1445e82 100644 --- a/src/backends/native/meta-pointer-constraint-native.c +++ b/src/backends/native/meta-pointer-constraint-native.c @@ -619,7 +619,11 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp { if (x != constraint_impl_native->origin.x || y != constraint_impl_native->origin.y) - clutter_seat_warp_pointer (seat, x, y); + { + clutter_seat_warp_pointer (seat, + constraint_impl_native->origin.x, + constraint_impl_native->origin.y); + } } else if (!mtk_region_contains_point (region, (int) rel_x, (int) rel_y)) { -- GitLab From d4907a960cc6847104f212488181bd92c268edd5 Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Sun, 12 May 2024 18:08:57 +0200 Subject: [PATCH 3/5] pointer-constraints/native: Fix typo in function name The vfunc is named "constrain" not "constraint". Part-of: --- .../native/meta-pointer-constraint-native.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/backends/native/meta-pointer-constraint-native.c b/src/backends/native/meta-pointer-constraint-native.c index 390e1445e82..fe3a9944766 100644 --- a/src/backends/native/meta-pointer-constraint-native.c +++ b/src/backends/native/meta-pointer-constraint-native.c @@ -443,13 +443,13 @@ get_motion_directions (MetaLine2 *motion) } static void -meta_pointer_constraint_impl_native_constraint (MetaPointerConstraintImpl *constraint_impl, - ClutterInputDevice *device, - uint32_t time, - float prev_x, - float prev_y, - float *x_inout, - float *y_inout) +meta_pointer_constraint_impl_native_constrain (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device, + uint32_t time, + float prev_x, + float prev_y, + float *x_inout, + float *y_inout) { MetaPointerConstraintImplNative *constraint_impl_native; g_autoptr (MtkRegion) region = NULL; @@ -682,7 +682,7 @@ meta_pointer_constraint_impl_native_class_init (MetaPointerConstraintImplNativeC object_class->finalize = meta_pointer_constraint_impl_native_finalize; constraint_impl_class = META_POINTER_CONSTRAINT_IMPL_CLASS (klass); - constraint_impl_class->constrain = meta_pointer_constraint_impl_native_constraint; + constraint_impl_class->constrain = meta_pointer_constraint_impl_native_constrain; constraint_impl_class->ensure_constrained = meta_pointer_constraint_impl_native_ensure_constrained; } -- GitLab From c3e626405f9bf0d0a005a4eb2274215ec3713c1b Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Sun, 12 May 2024 20:02:50 +0200 Subject: [PATCH 4/5] wayland/pointer-constraints: Disconnect focus surface handler early When meta_wayland_pointer_constraint_remove() is called, it can trigger a meta_wayland_event_handler_invalidate_focus() via: meta_wayland_pointer_constraint_destroy() meta_wayland_pointer_constraint_disable() meta_wayland_input_detach_event_handler() meta_wayland_input_invalidate_all_focus() meta_wayland_event_handler_invalidate_focus() Which then would result in a "focus-surface-changed" signal which would call meta_wayland_pointer_constraint_remove() a second time. This happens after surface_remove_pointer_constraints() has already been called in the first meta_wayland_pointer_constraint_remove() call, leading to "data" being NULL. To prevent this issue disconnect the signal handler before calling meta_wayland_pointer_constraint_disable() when destroying a constraint. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3476 Part-of: --- .../meta-wayland-pointer-constraints.c | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/wayland/meta-wayland-pointer-constraints.c b/src/wayland/meta-wayland-pointer-constraints.c index 4f8cc319697..069ee29ba73 100644 --- a/src/wayland/meta-wayland-pointer-constraints.c +++ b/src/wayland/meta-wayland-pointer-constraints.c @@ -433,6 +433,9 @@ meta_wayland_pointer_constraint_disable (MetaWaylandPointerConstraint *constrain void meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint) { + g_clear_signal_handler (&constraint->pointer_focus_surface_handler_id, + constraint->seat->pointer); + if (meta_wayland_pointer_constraint_is_enabled (constraint)) meta_wayland_pointer_constraint_disable (constraint); @@ -1133,18 +1136,6 @@ bind_pointer_constraints (struct wl_client *client, NULL); } -static void -meta_wayland_pointer_constraint_finalize (GObject *object) -{ - MetaWaylandPointerConstraint *constraint = - META_WAYLAND_POINTER_CONSTRAINT (object); - - g_clear_signal_handler (&constraint->pointer_focus_surface_handler_id, - constraint->seat->pointer); - - G_OBJECT_CLASS (meta_wayland_pointer_constraint_parent_class)->finalize (object); -} - void meta_wayland_pointer_constraints_init (MetaWaylandCompositor *compositor) { @@ -1162,11 +1153,6 @@ meta_wayland_pointer_constraint_init (MetaWaylandPointerConstraint *constraint) static void meta_wayland_pointer_constraint_class_init (MetaWaylandPointerConstraintClass *klass) { - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->finalize = meta_wayland_pointer_constraint_finalize; - quark_pending_constraint_state = g_quark_from_static_string ("-meta-wayland-pointer-constraint-pending_state"); quark_surface_pointer_constraints_data = -- GitLab From 650ef9b57fb958f2561efad76c6bfcefcebd5550 Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Sun, 12 May 2024 23:22:08 +0200 Subject: [PATCH 5/5] wayland/pointer-constraints: Don't steal regions for new constraints meta_pointer_constraint_new() does not take ownership of the passed regions but instead creates a copy, resulting in a leak in the calling functions. Part-of: --- src/wayland/meta-pointer-confinement-wayland.c | 2 +- src/wayland/meta-pointer-lock-wayland.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-pointer-confinement-wayland.c b/src/wayland/meta-pointer-confinement-wayland.c index ffb537ab060..5a06207d849 100644 --- a/src/wayland/meta-pointer-confinement-wayland.c +++ b/src/wayland/meta-pointer-confinement-wayland.c @@ -247,7 +247,7 @@ meta_pointer_confinement_wayland_create_constraint (MetaPointerConfinementWaylan meta_wayland_surface_get_absolute_coordinates (surface, 0, 0, &dx, &dy); min_edge_distance = wl_fixed_to_double (1) * geometry_scale; - constraint = meta_pointer_constraint_new (g_steal_pointer (®ion), + constraint = meta_pointer_constraint_new (region, GRAPHENE_POINT_INIT (dx, dy), min_edge_distance); diff --git a/src/wayland/meta-pointer-lock-wayland.c b/src/wayland/meta-pointer-lock-wayland.c index 96d18123665..e2a9b6905dc 100644 --- a/src/wayland/meta-pointer-lock-wayland.c +++ b/src/wayland/meta-pointer-lock-wayland.c @@ -77,7 +77,7 @@ meta_pointer_lock_wayland_create_constraint (MetaPointerConfinementWayland *conf rect = (MtkRectangle) { .x = 0, .y = 0, .width = 0, .height = 0 }; region = mtk_region_create_rectangle (&rect); - constraint = meta_pointer_constraint_new (g_steal_pointer (®ion), + constraint = meta_pointer_constraint_new (region, GRAPHENE_POINT_INIT (x, y), 0.0); -- GitLab