gdk: Listen to touch events by default on the native window

GDK will only receive touch events when dealing with a multitouch
device, so these must be transformed to pointer events if the
client-side window receiving the event doesn't listen to touch
events, and the touch sequence the event is from does emulate
the pointer.

If a sequence emulates pointer events, it will result in a
button-press, N motions with GDK_BUTTON1_MASK set and a
button-release event, and it will deliver crossing events
as specified by the current device grab.
This commit is contained in:
Carlos Garnacho
2012-01-05 01:04:15 +01:00
committed by Matthias Clasen
parent 0a80c26cdf
commit 6efe116715

View File

@@ -1243,11 +1243,12 @@ get_native_device_event_mask (GdkWindow *private,
* lists due to some non-native child window. * lists due to some non-native child window.
*/ */
if (gdk_window_is_toplevel (private) || if (gdk_window_is_toplevel (private) ||
mask & GDK_BUTTON_PRESS_MASK) mask & GDK_BUTTON_PRESS_MASK)
mask |= mask |=
GDK_POINTER_MOTION_MASK | GDK_TOUCH_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
GDK_SCROLL_MASK; GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
GDK_SCROLL_MASK;
return mask; return mask;
} }
@@ -8170,6 +8171,15 @@ is_motion_type (GdkEventType type)
type == GDK_LEAVE_NOTIFY; type == GDK_LEAVE_NOTIFY;
} }
static gboolean
is_touch_type (GdkEventType type)
{
return type == GDK_TOUCH_BEGIN ||
type == GDK_TOUCH_UPDATE ||
type == GDK_TOUCH_END ||
type == GDK_TOUCH_CANCEL;
}
static GdkWindow * static GdkWindow *
find_common_ancestor (GdkWindow *win1, find_common_ancestor (GdkWindow *win1,
GdkWindow *win2) GdkWindow *win2)
@@ -9242,8 +9252,9 @@ proxy_pointer_event (GdkDisplay *display,
if (pointer_info->need_touch_press_enter && if (pointer_info->need_touch_press_enter &&
gdk_device_get_source (pointer_info->last_slave) != GDK_SOURCE_TOUCHSCREEN && gdk_device_get_source (pointer_info->last_slave) != GDK_SOURCE_TOUCHSCREEN &&
gdk_device_get_source (pointer_info->last_slave) != GDK_SOURCE_TOUCHPAD) gdk_device_get_source (pointer_info->last_slave) != GDK_SOURCE_TOUCHPAD) &&
(source_event->type != GDK_TOUCH_UPDATE ||
_gdk_event_get_pointer_emulated (source_event))
{ {
pointer_info->need_touch_press_enter = FALSE; pointer_info->need_touch_press_enter = FALSE;
need_synthetic_enter = TRUE; need_synthetic_enter = TRUE;
@@ -9374,6 +9385,15 @@ proxy_pointer_event (GdkDisplay *display,
&evmask, &evmask,
serial); serial);
if ((evmask & GDK_TOUCH_MASK) == 0 &&
source_event->type == GDK_TOUCH_UPDATE)
{
if (_gdk_event_get_pointer_emulated (source_event))
source_event->type = GDK_MOTION_NOTIFY;
else
return TRUE;
}
if (event_win && if (event_win &&
gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER && gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
gdk_window_get_device_events (event_win, device) == 0) gdk_window_get_device_events (event_win, device) == 0)
@@ -9560,6 +9580,20 @@ proxy_button_event (GdkEvent *source_event,
type, state, type, state,
&evmask, serial); &evmask, serial);
if ((evmask & GDK_TOUCH_MASK) == 0 &&
(type == GDK_TOUCH_BEGIN || type == GDK_TOUCH_END))
{
if (_gdk_event_get_pointer_emulated (source_event))
{
if (type == GDK_TOUCH_BEGIN)
source_event->type = type = GDK_BUTTON_PRESS;
else if (type == GDK_TOUCH_END)
source_event->type = type = GDK_BUTTON_RELEASE;
}
else
return TRUE;
}
if (event_win == NULL || display->ignore_core_events) if (event_win == NULL || display->ignore_core_events)
return TRUE; return TRUE;
@@ -9567,7 +9601,9 @@ proxy_button_event (GdkEvent *source_event,
gdk_window_get_device_events (event_win, device) == 0) gdk_window_get_device_events (event_win, device) == 0)
return TRUE; return TRUE;
if (type == GDK_BUTTON_PRESS && if ((type == GDK_BUTTON_PRESS ||
(type == GDK_TOUCH_BEGIN &&
_gdk_event_get_pointer_emulated (source_event))) &&
pointer_info->need_touch_press_enter) pointer_info->need_touch_press_enter)
{ {
GdkCrossingMode mode; GdkCrossingMode mode;
@@ -9612,7 +9648,9 @@ proxy_button_event (GdkEvent *source_event,
if (type == GDK_BUTTON_PRESS) if (type == GDK_BUTTON_PRESS)
_gdk_event_button_generate (display, event); _gdk_event_button_generate (display, event);
else if (type == GDK_BUTTON_RELEASE && else if ((type == GDK_BUTTON_RELEASE ||
(type == GDK_TOUCH_END &&
_gdk_event_get_pointer_emulated (source_event))) &&
pointer_window == pointer_info->window_under_pointer && pointer_window == pointer_info->window_under_pointer &&
(gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN || (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN ||
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHPAD)) gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHPAD))
@@ -9892,7 +9930,9 @@ _gdk_windowing_got_event (GdkDisplay *display,
} }
} }
if (pointer_info) if (pointer_info &&
(!is_touch_type (event->type) ||
_gdk_event_get_pointer_emulated (event)))
{ {
guint old_state, old_button; guint old_state, old_button;