summaryrefslogtreecommitdiff
path: root/gdk/gdkwindow.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/gdkwindow.c')
-rw-r--r--gdk/gdkwindow.c955
1 files changed, 5 insertions, 950 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 59d21d4f2d..9a1616ce86 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -5518,31 +5518,6 @@ point_in_input_window (GdkWindow *window,
return FALSE;
}
-static GdkWindow *
-convert_native_coords_to_toplevel (GdkWindow *window,
- gdouble child_x,
- gdouble child_y,
- gdouble *toplevel_x,
- gdouble *toplevel_y)
-{
- gdouble x, y;
-
- x = child_x;
- y = child_y;
-
- while (!gdk_window_is_toplevel (window))
- {
- x += window->x;
- y += window->y;
- window = window->parent;
- }
-
- *toplevel_x = x;
- *toplevel_y = y;
-
- return window;
-}
-
static void
convert_toplevel_coords_to_window (GdkWindow *window,
gdouble toplevel_x,
@@ -5798,63 +5773,6 @@ static const guint type_masks[] = {
G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
/* send motion events if the right buttons are down */
-static guint
-update_evmask_for_button_motion (guint evmask,
- GdkModifierType mask)
-{
- if (evmask & GDK_BUTTON_MOTION_MASK &&
- mask & (GDK_BUTTON1_MASK |
- GDK_BUTTON2_MASK |
- GDK_BUTTON3_MASK |
- GDK_BUTTON4_MASK |
- GDK_BUTTON5_MASK))
- evmask |= GDK_POINTER_MOTION_MASK;
-
- if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
- (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
- (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
- evmask |= GDK_POINTER_MOTION_MASK;
-
- return evmask;
-}
-
-static gboolean
-is_button_type (GdkEventType type)
-{
- return type == GDK_BUTTON_PRESS ||
- type == GDK_2BUTTON_PRESS ||
- type == GDK_3BUTTON_PRESS ||
- type == GDK_BUTTON_RELEASE ||
- type == GDK_TOUCH_BEGIN ||
- type == GDK_TOUCH_END ||
- type == GDK_TOUCH_CANCEL ||
- type == GDK_SCROLL;
-}
-
-static gboolean
-is_gesture_type (GdkEventType type)
-{
- return (type == GDK_TOUCHPAD_SWIPE ||
- type == GDK_TOUCHPAD_PINCH);
-}
-
-static gboolean
-is_motion_type (GdkEventType type)
-{
- return type == GDK_MOTION_NOTIFY ||
- type == GDK_TOUCH_UPDATE ||
- type == GDK_ENTER_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 *
find_common_ancestor (GdkWindow *win1,
@@ -6580,776 +6498,12 @@ _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
}
}
-/* Don't use for crossing events */
-static GdkWindow *
-get_event_window (GdkDisplay *display,
- GdkDevice *device,
- GdkEventSequence *sequence,
- GdkWindow *pointer_window,
- GdkEventType type,
- GdkModifierType mask,
- guint *evmask_out,
- gboolean pointer_emulated,
- gulong serial)
-{
- 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_get_last_device_grab (display, device);
-
- /* Default value. */
- if (evmask_out)
- *evmask_out = 0;
-
- 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] | emulated_mask))
- {
- if (evmask_out)
- *evmask_out = evmask;
- return touch_grab->window;
- }
- else
- return NULL;
- }
-
- if (grab != NULL && !grab->owner_events)
- {
- evmask = grab->event_mask;
- evmask = update_evmask_for_button_motion (evmask, mask);
-
- grab_window = grab->window;
-
- if (evmask & (type_masks[type] | emulated_mask))
- {
- if (evmask_out)
- *evmask_out = evmask;
- return grab_window;
- }
- else
- return NULL;
- }
-
- while (pointer_window != NULL)
- {
- evmask = pointer_window->event_mask;
- evmask = update_evmask_for_button_motion (evmask, mask);
-
- if (evmask & (type_masks[type] | emulated_mask))
- {
- if (evmask_out)
- *evmask_out = evmask;
- return pointer_window;
- }
-
- pointer_window = pointer_window->parent;
- }
-
- if (grab != NULL &&
- grab->owner_events)
- {
- evmask = grab->event_mask;
- evmask = update_evmask_for_button_motion (evmask, mask);
-
- if (evmask & (type_masks[type] | emulated_mask))
- {
- if (evmask_out)
- *evmask_out = evmask;
- return grab->window;
- }
- else
- return NULL;
- }
-
- return NULL;
-}
-
-static gboolean
-proxy_pointer_event (GdkDisplay *display,
- GdkEvent *source_event,
- gulong serial)
-{
- GdkWindow *toplevel_window, *event_window;
- GdkWindow *pointer_window;
- GdkPointerWindowInfo *pointer_info;
- GdkDevice *device, *source_device;
- GdkEvent *event;
- guint state;
- 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);
- time_ = gdk_event_get_time (source_event);
- device = gdk_event_get_device (source_event);
- source_device = gdk_event_get_source_device (source_event);
- pointer_info = _gdk_display_get_pointer_info (display, device);
- toplevel_window = convert_native_coords_to_toplevel (event_window,
- toplevel_x, toplevel_y,
- &toplevel_x, &toplevel_y);
-
- non_linear = FALSE;
- if ((source_event->type == GDK_LEAVE_NOTIFY ||
- source_event->type == GDK_ENTER_NOTIFY) &&
- (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
- source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
- non_linear = TRUE;
-
- if (pointer_info->need_touch_press_enter &&
- gdk_device_get_source (pointer_info->last_slave) != GDK_SOURCE_TOUCHSCREEN &&
- (source_event->type != GDK_TOUCH_UPDATE ||
- gdk_event_get_pointer_emulated (source_event)))
- {
- pointer_info->need_touch_press_enter = FALSE;
- need_synthetic_enter = TRUE;
- }
-
- /* If we get crossing events with subwindow unexpectedly being NULL
- that means there is a native subwindow that gdk doesn't know about.
- We track these and forward them, with the correct virtual window
- events inbetween.
- This is important to get right, as metacity uses gdk for the frame
- windows, but gdk doesn't know about the client windows reparented
- into the frame. */
- if (((source_event->type == GDK_LEAVE_NOTIFY &&
- source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
- (source_event->type == GDK_ENTER_NOTIFY &&
- (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
- source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
- source_event->crossing.subwindow == NULL)
- {
- /* Left for an unknown (to gdk) subwindow */
-
- /* Send leave events from window under pointer to event window
- that will get the subwindow == NULL window */
- _gdk_synthesize_crossing_events (display,
- pointer_info->window_under_pointer,
- event_window,
- device, source_device,
- source_event->crossing.mode,
- toplevel_x, toplevel_y,
- state, time_,
- source_event,
- serial,
- non_linear);
-
- /* Send subwindow == NULL event */
- send_crossing_event (display,
- toplevel_window,
- event_window,
- source_event->type,
- source_event->crossing.mode,
- source_event->crossing.detail,
- NULL,
- device, source_device,
- toplevel_x, toplevel_y,
- state, time_,
- source_event,
- serial);
-
- _gdk_display_set_window_under_pointer (display, device, NULL);
- return TRUE;
- }
-
- pointer_window = get_pointer_window (display, toplevel_window, device,
- toplevel_x, toplevel_y, serial);
-
- if (((source_event->type == GDK_ENTER_NOTIFY &&
- source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
- (source_event->type == GDK_LEAVE_NOTIFY &&
- (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
- source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
- source_event->crossing.subwindow == NULL)
- {
- /* Entered from an unknown (to gdk) subwindow */
-
- /* Send subwindow == NULL event */
- send_crossing_event (display,
- toplevel_window,
- event_window,
- source_event->type,
- source_event->crossing.mode,
- source_event->crossing.detail,
- NULL,
- device, source_device,
- toplevel_x, toplevel_y,
- state, time_,
- source_event,
- serial);
-
- /* Send enter events from event window to pointer_window */
- _gdk_synthesize_crossing_events (display,
- event_window,
- pointer_window,
- device, source_device,
- source_event->crossing.mode,
- toplevel_x, toplevel_y,
- state, time_,
- source_event,
- serial, non_linear);
- _gdk_display_set_window_under_pointer (display, device, pointer_window);
- return TRUE;
- }
-
- if ((source_event->type != GDK_TOUCH_UPDATE ||
- gdk_event_get_pointer_emulated (source_event)) &&
- pointer_info->window_under_pointer != pointer_window)
- {
- /* Either a toplevel crossing notify that ended up inside a child window,
- or a motion notify that got into another child window */
-
- /* Different than last time, send crossing events */
- _gdk_synthesize_crossing_events (display,
- pointer_info->window_under_pointer,
- pointer_window,
- device, source_device,
- GDK_CROSSING_NORMAL,
- toplevel_x, toplevel_y,
- state, time_,
- source_event,
- serial, non_linear);
- _gdk_display_set_window_under_pointer (display, device, pointer_window);
- }
- else if (source_event->type == GDK_MOTION_NOTIFY ||
- source_event->type == GDK_TOUCH_UPDATE)
- {
- GdkWindow *event_win;
- guint evmask;
- gboolean is_hint;
- GdkEventSequence *sequence;
-
- sequence = gdk_event_get_event_sequence (source_event);
-
- event_win = get_event_window (display,
- device,
- sequence,
- pointer_window,
- 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)
- return TRUE;
-
- /* The last device to interact with the window was a touch device,
- * which synthesized a leave notify event, so synthesize another enter
- * notify to tell the pointer is on the window.
- */
- if (need_synthetic_enter)
- _gdk_synthesize_crossing_events (display,
- NULL, pointer_window,
- device, source_device,
- GDK_CROSSING_DEVICE_SWITCH,
- toplevel_x, toplevel_y,
- state, time_, NULL,
- serial, FALSE);
-
- is_hint = FALSE;
-
- if (event_win &&
- event_type == GDK_MOTION_NOTIFY &&
- (evmask & GDK_POINTER_MOTION_HINT_MASK))
- {
- gulong *device_serial;
-
- device_serial = g_hash_table_lookup (display->motion_hint_info, device);
-
- if (!device_serial ||
- (*device_serial != 0 &&
- serial < *device_serial))
- event_win = NULL; /* Ignore event */
- else
- {
- is_hint = TRUE;
- *device_serial = G_MAXULONG;
- }
- }
-
- if (!event_win)
- return TRUE;
-
- 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);
- gdk_event_set_seat (event, gdk_device_get_seat (device));
- gdk_event_set_device_tool (event, gdk_event_get_device_tool (source_event));
-
- 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.
- We handle our own, including our emulated masks. */
- return TRUE;
-}
-
#define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
GDK_BUTTON2_MASK | \
GDK_BUTTON3_MASK | \
GDK_BUTTON4_MASK | \
GDK_BUTTON5_MASK)
-static gboolean
-proxy_button_event (GdkEvent *source_event,
- gulong serial)
-{
- GdkWindow *toplevel_window, *event_window;
- GdkWindow *event_win;
- GdkWindow *pointer_window;
- GdkWindow *parent;
- GdkEvent *event;
- GdkPointerWindowInfo *pointer_info;
- GdkDeviceGrabInfo *pointer_grab;
- guint state;
- guint32 time_;
- GdkEventType type;
- gdouble toplevel_x, toplevel_y;
- GdkDisplay *display;
- GdkWindow *w;
- GdkDevice *device, *source_device;
- GdkEventMask evmask;
- GdkEventSequence *sequence;
-
- type = source_event->any.type;
- event_window = source_event->any.window;
- gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
- gdk_event_get_state (source_event, &state);
- time_ = gdk_event_get_time (source_event);
- device = gdk_event_get_device (source_event);
- source_device = gdk_event_get_source_device (source_event);
- display = gdk_window_get_display (source_event->any.window);
- toplevel_window = convert_native_coords_to_toplevel (event_window,
- toplevel_x, toplevel_y,
- &toplevel_x, &toplevel_y);
-
- 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 &&
- (!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,
- toplevel_x, toplevel_y,
- NULL, NULL);
-
- /* Find the event window, that gets the grab */
- w = pointer_window;
- while (w != NULL &&
- (parent = w->parent) != NULL &&
- parent->window_type != GDK_WINDOW_ROOT)
- {
- if (w->event_mask & GDK_BUTTON_PRESS_MASK &&
- (type == GDK_BUTTON_PRESS ||
- gdk_event_get_pointer_emulated (source_event)))
- break;
-
- if (type == GDK_TOUCH_BEGIN &&
- w->event_mask & GDK_TOUCH_MASK)
- break;
-
- w = parent;
- }
- pointer_window = w;
-
- if (pointer_window)
- {
- if (type == GDK_TOUCH_BEGIN &&
- pointer_window->event_mask & GDK_TOUCH_MASK)
- {
- _gdk_display_add_touch_grab (display, device, sequence,
- pointer_window, event_window,
- gdk_window_get_events (pointer_window),
- serial, time_);
- }
- else if (type == GDK_BUTTON_PRESS ||
- gdk_event_get_pointer_emulated (source_event))
- {
- _gdk_display_add_device_grab (display,
- device,
- pointer_window,
- event_window,
- GDK_OWNERSHIP_NONE,
- FALSE,
- gdk_window_get_events (pointer_window),
- serial,
- time_,
- TRUE);
- _gdk_display_device_grab_update (display, device,
- source_device, serial);
- }
- }
- }
-
- pointer_window = get_pointer_window (display, toplevel_window, device,
- toplevel_x, toplevel_y,
- serial);
-
- event_win = get_event_window (display,
- device,
- sequence,
- pointer_window,
- type, state,
- &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)
- 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 ||
- (type == GDK_TOUCH_BEGIN &&
- gdk_event_get_pointer_emulated (source_event))) &&
- pointer_info->need_touch_press_enter)
- {
- GdkCrossingMode mode;
-
- /* The last device to interact with the window was a touch device,
- * 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)
- mode = GDK_CROSSING_TOUCH_BEGIN;
- else
- mode = GDK_CROSSING_DEVICE_SWITCH;
-
- pointer_info->need_touch_press_enter = FALSE;
- _gdk_synthesize_crossing_events (display,
- NULL,
- pointer_info->window_under_pointer,
- device, source_device, mode,
- toplevel_x, toplevel_y,
- 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);
-
- switch (type)
- {
- case GDK_BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- event->button.button = source_event->button.button;
- convert_toplevel_coords_to_window (event_win,
- toplevel_x, toplevel_y,
- &event->button.x, &event->button.y);
- 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);
- gdk_event_set_seat (event, gdk_device_get_seat (device));
- gdk_event_set_device_tool (event, gdk_event_get_device_tool (source_event));
-
- 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 ||
- (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)
- {
- /* Synthesize a leave notify event
- * whenever a touch device is released
- */
- pointer_info->need_touch_press_enter = TRUE;
- _gdk_synthesize_crossing_events (display,
- pointer_window, NULL,
- device, source_device,
- GDK_CROSSING_TOUCH_END,
- toplevel_x, toplevel_y,
- state, time_, NULL,
- serial, FALSE);
- }
- return TRUE;
-
- case GDK_TOUCH_BEGIN:
- case GDK_TOUCH_END:
- case GDK_TOUCH_CANCEL:
- convert_toplevel_coords_to_window (event_win,
- toplevel_x, toplevel_y,
- &event->button.x, &event->button.y);
- 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);
-
- if (((type == GDK_TOUCH_END || type == GDK_TOUCH_CANCEL) &&
- gdk_event_get_pointer_emulated (source_event)) &&
- pointer_window == pointer_info->window_under_pointer &&
- gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
- {
- /* Synthesize a leave notify event
- * whenever a touch device is released
- */
- pointer_info->need_touch_press_enter = TRUE;
- _gdk_synthesize_crossing_events (display,
- pointer_window, NULL,
- device, source_device,
- GDK_CROSSING_TOUCH_END,
- toplevel_x, toplevel_y,
- state, time_, NULL,
- serial, FALSE);
- }
- return TRUE;
-
- case GDK_SCROLL:
- event->scroll.direction = source_event->scroll.direction;
- convert_toplevel_coords_to_window (event_win,
- toplevel_x, toplevel_y,
- &event->scroll.x, &event->scroll.y);
- event->scroll.x_root = source_event->scroll.x_root;
- 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;
- event->scroll.is_stop = source_event->scroll.is_stop;
- gdk_event_set_source_device (event, source_device);
- return TRUE;
-
- default:
- return FALSE;
- }
-
- return TRUE; /* Always unlink original, we want to obey the emulated event mask */
-}
-
-static gboolean
-proxy_gesture_event (GdkEvent *source_event,
- gulong serial)
-{
- GdkWindow *toplevel_window, *pointer_window, *event_win;
- GdkDevice *device, *source_device;
- gdouble toplevel_x, toplevel_y;
- GdkDisplay *display;
- GdkEventMask evmask;
- GdkEventType evtype;
- GdkEvent *event;
- guint state;
-
- evtype = source_event->any.type;
- gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
- gdk_event_get_state (source_event, &state);
- device = gdk_event_get_device (source_event);
- source_device = gdk_event_get_source_device (source_event);
- display = gdk_window_get_display (source_event->any.window);
- toplevel_window = convert_native_coords_to_toplevel (source_event->any.window,
- toplevel_x, toplevel_y,
- &toplevel_x, &toplevel_y);
-
- pointer_window = get_pointer_window (display, toplevel_window, device,
- toplevel_x, toplevel_y,
- serial);
-
- event_win = get_event_window (display, device, NULL,
- pointer_window, evtype, state,
- &evmask, FALSE, serial);
- if (!event_win)
- return TRUE;
-
- if ((evmask & GDK_TOUCHPAD_GESTURE_MASK) == 0)
- return TRUE;
-
- event = _gdk_make_event (event_win, evtype, source_event, FALSE);
- gdk_event_set_device (event, device);
- gdk_event_set_source_device (event, source_device);
- gdk_event_set_seat (event, gdk_device_get_seat (device));
-
- switch (evtype)
- {
- case GDK_TOUCHPAD_SWIPE:
- convert_toplevel_coords_to_window (event_win,
- toplevel_x, toplevel_y,
- &event->touchpad_swipe.x,
- &event->touchpad_swipe.y);
- gdk_event_get_root_coords (source_event,
- &event->touchpad_swipe.x_root,
- &event->touchpad_swipe.y_root);
- event->touchpad_swipe.dx = source_event->touchpad_swipe.dx;
- event->touchpad_swipe.dy = source_event->touchpad_swipe.dy;
- event->touchpad_swipe.n_fingers = source_event->touchpad_swipe.n_fingers;
- event->touchpad_swipe.phase = source_event->touchpad_swipe.phase;
- break;
-
- case GDK_TOUCHPAD_PINCH:
- convert_toplevel_coords_to_window (event_win,
- toplevel_x, toplevel_y,
- &event->touchpad_pinch.x,
- &event->touchpad_pinch.y);
- gdk_event_get_root_coords (source_event,
- &event->touchpad_pinch.x_root,
- &event->touchpad_pinch.y_root);
- event->touchpad_pinch.dx = source_event->touchpad_pinch.dx;
- event->touchpad_pinch.dy = source_event->touchpad_pinch.dy;
- event->touchpad_pinch.scale = source_event->touchpad_pinch.scale;
- event->touchpad_pinch.angle_delta = source_event->touchpad_pinch.angle_delta;
- event->touchpad_pinch.n_fingers = source_event->touchpad_pinch.n_fingers;
- event->touchpad_pinch.phase = source_event->touchpad_pinch.phase;
- break;
-
- default:
- break;
- }
-
- return TRUE;
-}
-
#ifdef DEBUG_WINDOW_PRINTING
#ifdef GDK_WINDOWING_X11
@@ -7435,12 +6589,10 @@ _gdk_windowing_got_event (GdkDisplay *display,
gulong serial)
{
GdkWindow *event_window;
- gdouble x, y;
gboolean unlink_event = FALSE;
GdkDeviceGrabInfo *button_release_grab;
GdkPointerWindowInfo *pointer_info = NULL;
GdkDevice *device, *source_device;
- gboolean is_toplevel;
_gdk_display_update_last_event (display, event);
@@ -7494,110 +6646,13 @@ _gdk_windowing_got_event (GdkDisplay *display,
goto out;
}
- if (!(event->type == GDK_TOUCH_CANCEL ||
- is_button_type (event->type) ||
- is_motion_type (event->type) ||
- is_gesture_type (event->type)) ||
- event_window->window_type == GDK_WINDOW_ROOT)
+ if (event_window->window_type == GDK_WINDOW_ROOT)
goto out;
- is_toplevel = gdk_window_is_toplevel (event_window);
-
- if ((event->type == GDK_ENTER_NOTIFY ||
- event->type == GDK_LEAVE_NOTIFY) &&
- (event->crossing.mode == GDK_CROSSING_GRAB ||
- event->crossing.mode == GDK_CROSSING_UNGRAB) &&
- (_gdk_display_has_device_grab (display, device, serial) ||
- event->crossing.detail == GDK_NOTIFY_INFERIOR))
- {
- /* We synthesize all crossing events due to grabs ourselves,
- * so we ignore the native ones caused by our native pointer_grab
- * calls. Otherwise we would proxy these crossing event and cause
- * multiple copies of crossing events for grabs.
- *
- * We do want to handle grabs from other clients though, as for
- * instance alt-tab in metacity causes grabs like these and
- * we want to handle those. Thus the has_pointer_grab check.
- *
- * Implicit grabs on child windows create some grabbing events
- * that are sent before the button press. This means we can't
- * detect these with the has_pointer_grab check (as the implicit
- * grab is only noticed when we get button press event), so we
- * detect these events by checking for INFERIOR enter or leave
- * events. These should never be a problem to filter out.
- */
-
- /* We ended up in this window after some (perhaps other clients)
- * grab, so update the toplevel_under_window state
- */
- if (pointer_info && is_toplevel &&
- event->type == GDK_ENTER_NOTIFY &&
- event->crossing.mode == GDK_CROSSING_UNGRAB)
- {
- if (pointer_info->toplevel_under_pointer)
- g_object_unref (pointer_info->toplevel_under_pointer);
- pointer_info->toplevel_under_pointer = g_object_ref (event_window);
- }
-
- unlink_event = TRUE;
- goto out;
- }
-
- /* Track toplevel_under_pointer */
- if (pointer_info && is_toplevel)
- {
- if (event->type == GDK_ENTER_NOTIFY &&
- event->crossing.detail != GDK_NOTIFY_INFERIOR)
- {
- if (pointer_info->toplevel_under_pointer)
- g_object_unref (pointer_info->toplevel_under_pointer);
- pointer_info->toplevel_under_pointer = g_object_ref (event_window);
- }
- else if (event->type == GDK_LEAVE_NOTIFY &&
- event->crossing.detail != GDK_NOTIFY_INFERIOR &&
- pointer_info->toplevel_under_pointer == event_window)
- {
- if (pointer_info->toplevel_under_pointer)
- g_object_unref (pointer_info->toplevel_under_pointer);
- pointer_info->toplevel_under_pointer = NULL;
- }
- }
-
- if (pointer_info &&
- (!is_touch_type (event->type) ||
- gdk_event_get_pointer_emulated (event)))
- {
- guint old_state, old_button;
-
- /* Store last pointer window and position/state */
- old_state = pointer_info->state;
- old_button = pointer_info->button;
-
- gdk_event_get_coords (event, &x, &y);
- convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
- pointer_info->toplevel_x = x;
- pointer_info->toplevel_y = y;
- gdk_event_get_state (event, &pointer_info->state);
-
- 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 ||
- pointer_info->button != old_button))
- _gdk_display_enable_motion_hints (display, device);
- }
-
- if (is_motion_type (event->type))
- unlink_event = proxy_pointer_event (display, event, serial);
- else if (is_button_type (event->type))
- unlink_event = proxy_button_event (event, serial);
- else if (is_gesture_type (event->type))
- unlink_event = proxy_gesture_event (event, serial);
+ if (event->type == GDK_ENTER_NOTIFY)
+ _gdk_display_set_window_under_pointer (display, device, event_window);
+ else if (event->type == GDK_LEAVE_NOTIFY)
+ _gdk_display_set_window_under_pointer (display, device, NULL);
if ((event->type == GDK_BUTTON_RELEASE ||
event->type == GDK_TOUCH_CANCEL ||