diff options
Diffstat (limited to 'gdk/gdkwindow.c')
-rw-r--r-- | gdk/gdkwindow.c | 955 |
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 || |