wayland: Avoid spurious crossing events from master touch device

Only generate crossing events on wl_touch.down for the virtual master
device used for touch events, and only whenever this virtual device
actually moves across surfaces. This behavior resembles better what is
expected in X11, where the pointer is warped to the touch position
on XITouchBegin.

This avoids the double emission of leave events when the pointer
emulating touch is lifted, that crossing event will be instead
generated when/if the focus surface changes.

https://bugzilla.gnome.org/show_bug.cgi?id=766314
This commit is contained in:
Carlos Garnacho 2016-05-12 13:34:42 +02:00
parent 2893526a48
commit 783c302198

View File

@ -2071,6 +2071,33 @@ mimic_pointer_emulating_touch_info (GdkDevice *device,
pointer->surface_y = touch->y; pointer->surface_y = touch->y;
} }
static void
touch_handle_master_pointer_crossing (GdkWaylandSeat *seat,
GdkWaylandTouchData *touch,
uint32_t time)
{
GdkWaylandPointerData *pointer;
pointer = GDK_WAYLAND_DEVICE (seat->touch_master)->pointer;
if (pointer->focus == touch->window)
return;
if (pointer->focus)
{
emulate_touch_crossing (pointer->focus, NULL,
seat->touch_master, seat->touch, touch,
GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, time);
}
if (touch->window)
{
emulate_touch_crossing (touch->window, NULL,
seat->touch_master, seat->touch, touch,
GDK_ENTER_NOTIFY, GDK_CROSSING_NORMAL, time);
}
}
static void static void
touch_handle_down (void *data, touch_handle_down (void *data,
struct wl_touch *wl_touch, struct wl_touch *wl_touch,
@ -2097,9 +2124,7 @@ touch_handle_down (void *data,
if (touch->initial_touch) if (touch->initial_touch)
{ {
emulate_touch_crossing (touch->window, NULL, touch_handle_master_pointer_crossing (seat, touch, time);
seat->touch_master, seat->touch, touch,
GDK_ENTER_NOTIFY, GDK_CROSSING_NORMAL, time);
GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = touch; GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = touch;
mimic_pointer_emulating_touch_info (seat->touch_master, touch); mimic_pointer_emulating_touch_info (seat->touch_master, touch);
} }
@ -2133,16 +2158,7 @@ touch_handle_up (void *data,
_gdk_wayland_display_deliver_event (seat->display, event); _gdk_wayland_display_deliver_event (seat->display, event);
if (touch->initial_touch) if (touch->initial_touch)
{ GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = NULL;
GdkWaylandPointerData *pointer_info;
emulate_touch_crossing (touch->window, NULL,
seat->touch_master, seat->touch, touch,
GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, time);
GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = NULL;
pointer_info = GDK_WAYLAND_DEVICE (seat->touch_master)->pointer;
g_clear_object (&pointer_info->focus);
}
gdk_wayland_seat_remove_touch (seat, id); gdk_wayland_seat_remove_touch (seat, id);
} }
@ -2193,10 +2209,6 @@ touch_handle_cancel (void *data,
{ {
touch = GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch; touch = GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch;
GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch = NULL; GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch = NULL;
emulate_touch_crossing (touch->window, NULL,
wayland_seat->touch_master, wayland_seat->touch,
touch, GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL,
GDK_CURRENT_TIME);
} }
g_hash_table_iter_init (&iter, wayland_seat->touches); g_hash_table_iter_init (&iter, wayland_seat->touches);