* lists due to some non-native child window.
*/
if (gdk_window_is_toplevel (private) ||
- mask & GDK_BUTTON_PRESS_MASK)
- mask |=
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_SCROLL_MASK;
+ mask & GDK_BUTTON_PRESS_MASK)
+ mask |=
+ GDK_TOUCH_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_SCROLL_MASK;
return mask;
}
GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
- GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
+ GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK,/* GDK_SCROLL= 31 */
0, /* GDK_WINDOW_STATE = 32 */
0, /* GDK_SETTING = 33 */
0, /* GDK_OWNER_CHANGE = 34 */
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 *
find_common_ancestor (GdkWindow *win1,
GdkWindow *win2)
event->touch.state = the_state;
break;
-
case GDK_SCROLL:
event->scroll.time = the_time;
event->scroll.state = the_state;
GdkEvent *event;
guint32 window_event_mask, type_event_mask;
GdkDeviceGrabInfo *grab;
+ GdkTouchGrabInfo *touch_grab = NULL;
GdkPointerWindowInfo *pointer_info;
gboolean block_event = FALSE;
+ GdkEventSequence *sequence;
grab = _gdk_display_has_device_grab (display, device, serial);
pointer_info = _gdk_display_get_pointer_info (display, device);
- if (grab != NULL &&
- !grab->owner_events)
+ sequence = gdk_event_get_event_sequence (event_in_queue);
+ if (sequence)
+ touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial);
+
+ if (touch_grab)
+ {
+ if (window != touch_grab->window)
+ return;
+
+ window_event_mask = touch_grab->event_mask;
+ }
+ else if (grab != NULL &&
+ !grab->owner_events)
{
/* !owner_event => only report events wrt grab window, ignore rest */
if ((GdkWindow *)window != grab->window)
GdkEventType type,
GdkModifierType mask,
guint *evmask_out,
+ gboolean pointer_emulated,
gulong serial)
{
- guint evmask;
+ guint evmask, emulated_mask = 0;
GdkWindow *grab_window;
GdkDeviceGrabInfo *grab;
GdkTouchGrabInfo *touch_grab;
touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial);
- grab = _gdk_display_has_device_grab (display, device, serial);
+ grab = _gdk_display_get_last_device_grab (display, device);
+
+ if (is_touch_type (type) && pointer_emulated)
+ {
+ switch (type)
+ {
+ case GDK_TOUCH_BEGIN:
+ emulated_mask |= GDK_BUTTON_PRESS_MASK;
+ break;
+ case GDK_TOUCH_UPDATE:
+ emulated_mask |= GDK_POINTER_MOTION_MASK;
+ break;
+ case GDK_TOUCH_END:
+ emulated_mask |= GDK_BUTTON_RELEASE_MASK;
+ default:
+ break;
+ }
+ }
if (touch_grab != NULL &&
(!grab || grab->implicit || touch_grab->serial >= grab->serial_start))
evmask = touch_grab->event_mask;
evmask = update_evmask_for_button_motion (evmask, mask);
- if (evmask & type_masks[type])
+ if (evmask & (type_masks[type] | emulated_mask))
{
if (evmask_out)
*evmask_out = evmask;
grab_window = grab->window;
- if (evmask & type_masks[type])
+ if (evmask & (type_masks[type] | emulated_mask))
{
if (evmask_out)
*evmask_out = evmask;
evmask = pointer_window->event_mask;
evmask = update_evmask_for_button_motion (evmask, mask);
- if (evmask & type_masks[type])
+ if (evmask & (type_masks[type] | emulated_mask))
{
if (evmask_out)
*evmask_out = evmask;
evmask = grab->event_mask;
evmask = update_evmask_for_button_motion (evmask, mask);
- if (evmask & type_masks[type])
+ if (evmask & (type_masks[type] | emulated_mask))
{
if (evmask_out)
*evmask_out = evmask;
gdouble toplevel_x, toplevel_y;
guint32 time_;
gboolean non_linear, need_synthetic_enter = FALSE;
+ gint event_type;
+ event_type = source_event->type;
event_window = source_event->any.window;
gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
gdk_event_get_state (source_event, &state);
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_TOUCHPAD)
-
+ (source_event->type != GDK_TOUCH_UPDATE ||
+ _gdk_event_get_pointer_emulated (source_event)))
{
pointer_info->need_touch_press_enter = FALSE;
need_synthetic_enter = TRUE;
source_event->type,
state,
&evmask,
+ _gdk_event_get_pointer_emulated (source_event),
serial);
+ if (event_type == GDK_TOUCH_UPDATE)
+ {
+ if (_gdk_event_get_pointer_emulated (source_event))
+ {
+ /* Touch events emulating pointer events are transformed back
+ * to pointer events if:
+ * 1 - The event window doesn't select for touch events
+ * 2 - There's no touch grab for this sequence, which means
+ * it was started as a pointer sequence, but a device
+ * grab added touch events afterwards, the sequence must
+ * not mutate in this case.
+ */
+ if ((evmask & GDK_TOUCH_MASK) == 0 ||
+ !_gdk_display_has_touch_grab (display, device, sequence, serial))
+ event_type = GDK_MOTION_NOTIFY;
+ }
+ else if ((evmask & GDK_TOUCH_MASK) == 0)
+ return TRUE;
+ }
+
+ if (is_touch_type (source_event->type) && !is_touch_type (event_type))
+ state |= GDK_BUTTON1_MASK;
+
if (event_win &&
gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
gdk_window_get_device_events (event_win, device) == 0)
is_hint = FALSE;
if (event_win &&
+ event_type == GDK_MOTION_NOTIFY &&
(evmask & GDK_POINTER_MOTION_HINT_MASK))
{
gulong *device_serial;
if (!event_win)
return TRUE;
- if (!display->ignore_core_events)
- {
- GdkEventType event_type;
-
- event_type = source_event->type;
-
- event = gdk_event_new (event_type);
- event->any.window = g_object_ref (event_win);
- event->any.send_event = source_event->any.send_event;
- event->motion.time = time_;
- convert_toplevel_coords_to_window (event_win,
- toplevel_x, toplevel_y,
- &event->motion.x, &event->motion.y);
- event->motion.x_root = source_event->motion.x_root;
- event->motion.y_root = source_event->motion.y_root;
- event->motion.state = state;
- event->motion.is_hint = is_hint;
- event->motion.device = source_event->motion.device;
- event->motion.axes = g_memdup (source_event->motion.axes,
- sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
- gdk_event_set_source_device (event, source_device);
-
- /* Just insert the event */
- _gdk_event_queue_insert_after (gdk_window_get_display (event_win),
- source_event, event);
+ event = gdk_event_new (event_type);
+ event->any.window = g_object_ref (event_win);
+ event->any.send_event = source_event->any.send_event;
+
+ gdk_event_set_device (event, gdk_event_get_device (source_event));
+ gdk_event_set_source_device (event, source_device);
+
+ if (event_type == GDK_TOUCH_UPDATE)
+ {
+ event->touch.time = time_;
+ event->touch.state = state | GDK_BUTTON1_MASK;
+ event->touch.sequence = source_event->touch.sequence;
+ event->touch.emulating_pointer = source_event->touch.emulating_pointer;
+ convert_toplevel_coords_to_window (event_win,
+ toplevel_x, toplevel_y,
+ &event->touch.x, &event->touch.y);
+ gdk_event_get_root_coords (source_event,
+ &event->touch.x_root,
+ &event->touch.y_root);
+
+ event->touch.axes = g_memdup (source_event->touch.axes,
+ sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
+ }
+ else
+ {
+ event->motion.time = time_;
+ event->motion.state = state;
+ event->motion.is_hint = is_hint;
+
+ convert_toplevel_coords_to_window (event_win,
+ toplevel_x, toplevel_y,
+ &event->motion.x, &event->motion.y);
+ gdk_event_get_root_coords (source_event,
+ &event->motion.x_root,
+ &event->motion.y_root);
+
+ if (is_touch_type (source_event->type))
+ event->motion.axes = g_memdup (source_event->touch.axes,
+ sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
+ else
+ event->motion.axes = g_memdup (source_event->motion.axes,
+ sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
}
+
+ /* Just insert the event */
+ _gdk_event_queue_insert_after (gdk_window_get_display (event_win),
+ source_event, event);
}
/* unlink all move events from queue.
GdkWindow *parent;
GdkEvent *event;
GdkPointerWindowInfo *pointer_info;
+ GdkDeviceGrabInfo *pointer_grab;
guint state;
guint32 time_;
GdkEventType type;
sequence = gdk_event_get_event_sequence (source_event);
pointer_info = _gdk_display_get_pointer_info (display, device);
+ pointer_grab = _gdk_display_has_device_grab (display, device, serial);
if ((type == GDK_BUTTON_PRESS ||
type == GDK_TOUCH_BEGIN) &&
!source_event->any.send_event &&
- _gdk_display_has_device_grab (display, device, serial) == NULL)
+ (!pointer_grab ||
+ (type == GDK_TOUCH_BEGIN && pointer_grab->implicit &&
+ !_gdk_event_get_pointer_emulated (source_event))))
{
pointer_window =
_gdk_window_find_descendant_at (toplevel_window,
sequence,
pointer_window,
type, state,
- &evmask, serial);
+ &evmask,
+ _gdk_event_get_pointer_emulated (source_event),
+ serial);
+
+ if (type == GDK_TOUCH_BEGIN || type == GDK_TOUCH_END)
+ {
+ if (_gdk_event_get_pointer_emulated (source_event))
+ {
+ if ((evmask & GDK_TOUCH_MASK) == 0 ||
+ !_gdk_display_has_touch_grab (display, device, sequence, serial))
+ {
+ if (type == GDK_TOUCH_BEGIN)
+ type = GDK_BUTTON_PRESS;
+ else if (type == GDK_TOUCH_END)
+ type = GDK_BUTTON_RELEASE;
+ }
+ }
+ else if ((evmask & GDK_TOUCH_MASK) == 0)
+ return TRUE;
+ }
+
+ if (source_event->type == GDK_TOUCH_END && !is_touch_type (type))
+ state |= GDK_BUTTON1_MASK;
- if (event_win == NULL || display->ignore_core_events)
+ if (event_win == NULL)
return TRUE;
if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
gdk_window_get_device_events (event_win, device) == 0)
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)
{
GdkCrossingMode mode;
* which synthesized a leave notify event, so synthesize another enter
* notify to tell the pointer is on the window.
*/
- if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN ||
- gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHPAD)
+ if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
mode = GDK_CROSSING_TOUCH_BEGIN;
else
mode = GDK_CROSSING_DEVICE_SWITCH;
state, time_, source_event,
serial, FALSE);
}
+ else if (type == GDK_SCROLL &&
+ (((evmask & GDK_SMOOTH_SCROLL_MASK) == 0 &&
+ source_event->scroll.direction == GDK_SCROLL_SMOOTH) ||
+ ((evmask & GDK_SMOOTH_SCROLL_MASK) != 0 &&
+ source_event->scroll.direction != GDK_SCROLL_SMOOTH &&
+ _gdk_event_get_pointer_emulated (source_event))))
+ return FALSE;
event = _gdk_make_event (event_win, type, source_event, FALSE);
convert_toplevel_coords_to_window (event_win,
toplevel_x, toplevel_y,
&event->button.x, &event->button.y);
- event->button.x_root = source_event->button.x_root;
- event->button.y_root = source_event->button.y_root;
- event->button.state = state;
- event->button.device = source_event->button.device;
- event->button.axes = g_memdup (source_event->button.axes,
- sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
+ gdk_event_get_root_coords (source_event,
+ &event->button.x_root,
+ &event->button.y_root);
+ gdk_event_set_device (event, gdk_event_get_device (source_event));
gdk_event_set_source_device (event, source_device);
+ if (is_touch_type (source_event->type))
+ {
+ if (type == GDK_BUTTON_RELEASE)
+ event->button.state |= GDK_BUTTON1_MASK;
+ event->button.button = 1;
+ event->button.axes = g_memdup (source_event->touch.axes,
+ sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
+ }
+ else
+ {
+ event->button.button = source_event->button.button;
+ event->button.axes = g_memdup (source_event->button.axes,
+ sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
+ }
+
if (type == GDK_BUTTON_PRESS)
_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 &&
- (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_TOUCHSCREEN)
{
/* Synthesize a leave notify event
* whenever a touch device is released
convert_toplevel_coords_to_window (event_win,
toplevel_x, toplevel_y,
&event->button.x, &event->button.y);
- event->touch.x_root = source_event->touch.x_root;
- event->touch.y_root = source_event->touch.y_root;
+ gdk_event_get_root_coords (source_event,
+ &event->touch.x_root,
+ &event->touch.y_root);
event->touch.state = state;
event->touch.device = source_event->touch.device;
event->touch.axes = g_memdup (source_event->touch.axes,
sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
event->touch.sequence = source_event->touch.sequence;
+ event->touch.emulating_pointer = source_event->touch.emulating_pointer;
gdk_event_set_source_device (event, source_device);
event->scroll.y_root = source_event->scroll.y_root;
event->scroll.state = state;
event->scroll.device = source_event->scroll.device;
+ event->scroll.delta_x = source_event->scroll.delta_x;
+ event->scroll.delta_y = source_event->scroll.delta_y;
gdk_event_set_source_device (event, source_device);
return TRUE;
}
}
- if (pointer_info)
+ if (pointer_info &&
+ (!is_touch_type (event->type) ||
+ _gdk_event_get_pointer_emulated (event)))
{
guint old_state, old_button;
if (event->type == GDK_BUTTON_PRESS ||
event->type == GDK_BUTTON_RELEASE)
pointer_info->button = event->button.button;
+ else if (event->type == GDK_TOUCH_BEGIN ||
+ event->type == GDK_TOUCH_END)
+ pointer_info->button = 1;
if (device &&
(pointer_info->state != old_state ||
/**
* gdk_window_get_frame_extents:
* @window: a toplevel #GdkWindow
- * @rect: rectangle to fill with bounding box of the window frame
+ * @rect: (out): rectangle to fill with bounding box of the window frame
*
* Obtains the bounding box of the window, including window manager
* titlebar/borders if any. The frame position is given in root window