mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
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>
This commit is contained in:
parent
cf76e694d7
commit
a7c4e8cefa
@ -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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user