[mutter] clutter/pick-stack: Use exclusive bottom/right box borders when picking
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] clutter/pick-stack: Use exclusive bottom/right box borders when picking
- Date: Tue, 4 May 2021 15:09:42 +0000 (UTC)
commit a7c4e8cefa8eb0b9f85471975d49be4c4d0d20de
Author: Sebastian Keller <skeller gnome org>
Date: Tue Apr 27 18:10:51 2021 +0200
clutter/pick-stack: Use exclusive bottom/right box borders when picking
The graphene functions used by clutter for picking assume that boxes are
inclusive in both there start and end coordinates, so picking at y
coordinate 32 for an actor with the height 32 placed at y coordinate 0
would still be considered a hit. This however is wrong as 32 is the
first position that is not in the actor anymore.
Usually this would not be much of a problem, because motion events are
rarely ever at exactly these borders and even if they are there will be
another motion event soon after. But since actors in gnome-shell usually
are aligned with the pixel grid and on X11 enter/leave events are
generated by the X server at integer coordinates, this case is much
more likely for those.
This can cause issues with Firefox which when using client side
decorations, still requests MWM_DECOR_BORDER via _MOTIF_WM_HINTS to have
mutter draw a border + shadow. This means that the Firefox window even
when using CSD is still reparented. For such windows we receive among
others XI_RawMotion and XI_Enter events, but no XI_Motion events. And
the raw motion events are discarded after an enter event, because that
sets has_pointer_focus to TRUE in MetaSeatX11. So when moving the cursor
from the panel to a maximized Firefox window the last event clutter
receives is the enter event at exactly integer coordinates. Since the
panel is 32px tall and the generated enter event is at y position 32,
the picking code will pick a panel actor and the focus will remain on it
as long as the cursor does not leave the Firefox window.
Fix this by excluding the bottom and right border of a box when picking.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4041
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1842>
clutter/clutter/clutter-pick-stack.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
---
diff --git a/clutter/clutter/clutter-pick-stack.c b/clutter/clutter/clutter-pick-stack.c
index 2a18fa3d38..3e56ad704c 100644
--- a/clutter/clutter/clutter-pick-stack.c
+++ b/clutter/clutter/clutter-pick-stack.c
@@ -126,10 +126,28 @@ ray_intersects_input_region (Record *rec,
if (G_LIKELY (is_axis_aligned_2d_rectangle (rec->vertices)))
{
graphene_box_t box;
+ graphene_box_t right_border;
+ graphene_box_t bottom_border;
+
+ /* Graphene considers both the start and end coordinates of boxes to be
+ * inclusive, while the vertices of a clutter actor are exclusive. So we
+ * need to manually exclude hits on these borders
+ */
graphene_box_init_from_points (&box, 4, rec->vertices);
- return graphene_box_contains_point (&box, point) ||
- graphene_ray_intersects_box (ray, &box);
+ graphene_box_init_from_points (&right_border, 2, rec->vertices + 1);
+ graphene_box_init_from_points (&bottom_border, 2, rec->vertices + 2);
+
+ /* Fast path for actors without 3D transforms */
+ if (graphene_box_contains_point (&box, point))
+ {
+ return !graphene_box_contains_point (&right_border, point) &&
+ !graphene_box_contains_point (&bottom_border, point);
+ }
+
+ return graphene_ray_intersects_box (ray, &box) &&
+ !graphene_ray_intersects_box (ray, &right_border) &&
+ !graphene_ray_intersects_box (ray, &bottom_border);
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]