backends/native: Allow infinitely small pointer constraint regions

The small catch is that MtkRegion (and pixman regions) "optimize away"
0-size rectangles, so a 0-sized region will always be seen as having
a 0,0 origin. We don't want that, so transfer the origin separately from
the region.

While at it, make the Wayland pointer lock use one such 0-size region,
to avoid the 1x1px wiggle room that it currently has (accounting for subpixel
motion).

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3420>
This commit is contained in:
Carlos Garnacho 2023-11-17 18:15:27 +01:00 committed by Robert Mader
parent c931ed0d81
commit 07d24fe502
7 changed files with 47 additions and 15 deletions

View File

@ -48,6 +48,7 @@ struct _MetaPointerConstraint
{
GObject parent_instance;
MtkRegion *region;
graphene_point_t origin;
double min_edge_distance;
};
@ -81,21 +82,27 @@ meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass)
MetaPointerConstraint *
meta_pointer_constraint_new (const MtkRegion *region,
double min_edge_distance)
meta_pointer_constraint_new (const MtkRegion *region,
graphene_point_t origin,
double min_edge_distance)
{
MetaPointerConstraint *constraint;
constraint = g_object_new (META_TYPE_POINTER_CONSTRAINT, NULL);
constraint->region = mtk_region_copy (region);
constraint->origin = origin;
constraint->min_edge_distance = min_edge_distance;
return constraint;
}
MtkRegion *
meta_pointer_constraint_get_region (MetaPointerConstraint *constraint)
meta_pointer_constraint_get_region (MetaPointerConstraint *constraint,
graphene_point_t *origin)
{
if (origin)
*origin = constraint->origin;
return constraint->region;
}

View File

@ -32,10 +32,12 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (MetaPointerConstraint, meta_pointer_constraint,
META, POINTER_CONSTRAINT, GObject);
MetaPointerConstraint * meta_pointer_constraint_new (const MtkRegion *region,
double min_edge_distance);
MetaPointerConstraint * meta_pointer_constraint_new (const MtkRegion *region,
graphene_point_t origin,
double min_edge_distance);
MtkRegion * meta_pointer_constraint_get_region (MetaPointerConstraint *constraint);
MtkRegion * meta_pointer_constraint_get_region (MetaPointerConstraint *constraint,
graphene_point_t *origin);
double meta_pointer_constraint_get_min_edge_distance (MetaPointerConstraint *constraint);

View File

@ -400,13 +400,15 @@ meta_backend_native_set_pointer_constraint (MetaBackend *backend,
if (constraint)
{
graphene_point_t origin;
double min_edge_distance;
region = meta_pointer_constraint_get_region (constraint);
region = meta_pointer_constraint_get_region (constraint, &origin);
min_edge_distance =
meta_pointer_constraint_get_min_edge_distance (constraint);
constraint_impl = meta_pointer_constraint_impl_native_new (constraint,
region,
origin,
min_edge_distance);
}

View File

@ -33,6 +33,7 @@ struct _MetaPointerConstraintImplNative
MetaPointerConstraintImpl parent;
MetaPointerConstraint *constraint;
MtkRegion *region;
graphene_point_t origin;
double min_edge_distance;
};
@ -461,6 +462,14 @@ meta_pointer_constraint_impl_native_constraint (MetaPointerConstraintImpl *const
constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (constraint_impl);
region = mtk_region_ref (constraint_impl_native->region);
if (mtk_region_is_empty (region))
{
*x_inout = constraint_impl_native->origin.x;
*y_inout = constraint_impl_native->origin.y;
return;
}
x = *x_inout;
y = *y_inout;
@ -589,6 +598,7 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp
{
MetaPointerConstraintImplNative *constraint_impl_native;
graphene_point_t point;
ClutterSeat *seat;
g_autoptr (MtkRegion) region = NULL;
float x;
float y;
@ -596,17 +606,24 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp
constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (constraint_impl);
region = mtk_region_ref (constraint_impl_native->region);
clutter_seat_query_state (clutter_input_device_get_seat (device),
device, NULL, &point, NULL);
seat = clutter_input_device_get_seat (device);
clutter_seat_query_state (seat, device, NULL, &point, NULL);
x = point.x;
y = point.y;
if (!mtk_region_contains_point (region, (int) x, (int) y))
if (mtk_region_is_empty (region))
{
if (x != constraint_impl_native->origin.x ||
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))
{
g_autoptr (GArray) borders = NULL;
float closest_distance_2 = FLT_MAX;
MetaBorder *closest_border = NULL;
ClutterSeat *seat;
unsigned int i;
borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder));
@ -628,7 +645,6 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp
closest_point_behind_border (closest_border, &x, &y);
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
clutter_seat_warp_pointer (seat, x, y);
}
}
@ -667,6 +683,7 @@ meta_pointer_constraint_impl_native_class_init (MetaPointerConstraintImplNativeC
MetaPointerConstraintImpl *
meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint,
const MtkRegion *region,
graphene_point_t origin,
double min_edge_distance)
{
MetaPointerConstraintImplNative *constraint_impl;
@ -676,6 +693,7 @@ meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint,
constraint_impl->constraint = constraint;
constraint_impl->region = mtk_region_copy (region);
constraint_impl->min_edge_distance = min_edge_distance;
constraint_impl->origin = origin;
return META_POINTER_CONSTRAINT_IMPL (constraint_impl);
}

View File

@ -37,6 +37,7 @@ G_DECLARE_FINAL_TYPE (MetaPointerConstraintImplNative,
MetaPointerConstraintImpl * meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint_impl,
const MtkRegion *region,
graphene_point_t origin,
double min_edge_distance);
G_END_DECLS

View File

@ -245,10 +245,10 @@ meta_pointer_confinement_wayland_create_constraint (MetaPointerConfinementWaylan
}
meta_wayland_surface_get_absolute_coordinates (surface, 0, 0, &dx, &dy);
mtk_region_translate (region, dx, dy);
min_edge_distance = wl_fixed_to_double (1) * geometry_scale;
constraint = meta_pointer_constraint_new (g_steal_pointer (&region),
GRAPHENE_POINT_INIT (dx, dy),
min_edge_distance);
return constraint;

View File

@ -74,10 +74,12 @@ meta_pointer_lock_wayland_create_constraint (MetaPointerConfinementWayland *conf
&sx, &sy);
meta_wayland_surface_get_absolute_coordinates (surface, sx, sy, &x, &y);
rect = (MtkRectangle) { .x = x, .y = y, .width = 1, .height = 1 };
rect = (MtkRectangle) { .x = 0, .y = 0, .width = 0, .height = 0 };
region = mtk_region_create_rectangle (&rect);
constraint = meta_pointer_constraint_new (g_steal_pointer (&region), 0.0);
constraint = meta_pointer_constraint_new (g_steal_pointer (&region),
GRAPHENE_POINT_INIT (x, y),
0.0);
return constraint;
}