From: Carlos Garnacho Date: Fri, 3 Feb 2023 14:55:09 +0000 (+0100) Subject: gdk/wayland: "Split" GdkWaylandDevice implementation out X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~8^2~4^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=1d4ceac2c5b43f689d773897ec2b041f82f69d7c;p=gtk4.git gdk/wayland: "Split" GdkWaylandDevice implementation out This is a bit spaghetti right now, since seats and devices were heavily entangled there are a number of crossed private API calls that should ideally not be there. Let this be a first step, so more bits may move from the seat implementation to devices. --- diff --git a/gdk/wayland/gdkdevice-wayland-private.h b/gdk/wayland/gdkdevice-wayland-private.h index 5f43cd1fda..233270b4a3 100644 --- a/gdk/wayland/gdkdevice-wayland-private.h +++ b/gdk/wayland/gdkdevice-wayland-private.h @@ -220,6 +220,19 @@ struct _GdkWaylandSeat #define GDK_TYPE_WAYLAND_DEVICE_PAD (gdk_wayland_device_pad_get_type ()) GType gdk_wayland_device_pad_get_type (void); +void gdk_wayland_seat_stop_cursor_animation (GdkWaylandSeat *seat, + GdkWaylandPointerData *pointer); + +GdkWaylandPointerData * gdk_wayland_device_get_pointer (GdkWaylandDevice *wayland_device); + +void gdk_wayland_device_set_pointer (GdkWaylandDevice *wayland_device, + GdkWaylandPointerData *pointer); + +GdkWaylandTouchData * gdk_wayland_device_get_emulating_touch (GdkWaylandDevice *wayland_device); + +void gdk_wayland_device_set_emulating_touch (GdkWaylandDevice *wayland_device, + GdkWaylandTouchData *touch); + void gdk_wayland_device_query_state (GdkDevice *device, GdkSurface *surface, double *win_x, @@ -234,4 +247,21 @@ void gdk_wayland_device_pad_set_feedback (GdkDevice *device, GdkWaylandTabletPadData * gdk_wayland_seat_find_pad (GdkWaylandSeat *seat, GdkDevice *device); +GdkWaylandTabletData * gdk_wayland_seat_find_tablet (GdkWaylandSeat *seat, + GdkDevice *device); + +GdkWaylandTouchData * gdk_wayland_seat_get_touch (GdkWaylandSeat *seat, + uint32_t id); + +void gdk_wayland_device_maybe_emit_grab_crossing (GdkDevice *device, + GdkSurface *window, + guint32 time); + +GdkSurface * gdk_wayland_device_maybe_emit_ungrab_crossing (GdkDevice *device, + guint32 time_); + +gboolean gdk_wayland_device_update_surface_cursor (GdkDevice *device); + +GdkModifierType gdk_wayland_device_get_modifiers (GdkDevice *device); + #endif diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c new file mode 100644 index 0000000000..9cb3cfbfda --- /dev/null +++ b/gdk/wayland/gdkdevice-wayland.c @@ -0,0 +1,745 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2009 Carlos Garnacho + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gdkdevice-wayland-private.h" +#include "gdkprivate-wayland.h" +#include "gdkcursorprivate.h" +#include "gdkeventsprivate.h" + +#define GDK_SLOT_TO_EVENT_SEQUENCE(s) ((GdkEventSequence *) GUINT_TO_POINTER((s) + 1)) +#define GDK_EVENT_SEQUENCE_TO_SLOT(s) (GPOINTER_TO_UINT(s) - 1) + +typedef struct +{ + GdkWaylandTouchData *emulating_touch; /* Only used on wd->logical_touch */ + GdkWaylandPointerData *pointer; +} GdkWaylandDevicePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (GdkWaylandDevice, gdk_wayland_device, GDK_TYPE_DEVICE) + +static void +gdk_wayland_device_set_surface_cursor (GdkDevice *device, + GdkSurface *surface, + GdkCursor *cursor) +{ + GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); + GdkWaylandPointerData *pointer = + gdk_wayland_device_get_pointer (wayland_device); + + if (device == seat->logical_touch) + return; + + if (seat->grab_cursor) + cursor = seat->grab_cursor; + + if (pointer->cursor != NULL && + cursor != NULL && + gdk_cursor_equal (cursor, pointer->cursor)) + return; + + if (cursor == NULL) + { + if (!pointer->cursor_is_default) + { + g_clear_object (&pointer->cursor); + pointer->cursor = gdk_cursor_new_from_name ("default", NULL); + pointer->cursor_is_default = TRUE; + + gdk_wayland_seat_stop_cursor_animation (seat, pointer); + gdk_wayland_device_update_surface_cursor (device); + } + else + { + /* Nothing to do, we'already using the default cursor */ + } + } + else + { + g_set_object (&pointer->cursor, cursor); + pointer->cursor_is_default = FALSE; + + gdk_wayland_seat_stop_cursor_animation (seat, pointer); + gdk_wayland_device_update_surface_cursor (device); + } +} + +static GdkGrabStatus +gdk_wayland_device_grab (GdkDevice *device, + GdkSurface *surface, + gboolean owner_events, + GdkEventMask event_mask, + GdkSurface *confine_to, + GdkCursor *cursor, + guint32 time_) +{ + GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); + GdkWaylandPointerData *pointer = + gdk_wayland_device_get_pointer (wayland_device); + + if (GDK_IS_DRAG_SURFACE (surface) && + gdk_surface_get_mapped (surface)) + { + g_warning ("Surface %p is already mapped at the time of grabbing. " + "gdk_seat_grab() should be used to simultaneously grab input " + "and show this popup. You may find oddities ahead.", + surface); + } + + gdk_wayland_device_maybe_emit_grab_crossing (device, surface, time_); + + if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) + { + /* Device is a keyboard */ + gdk_wayland_surface_inhibit_shortcuts (surface, + gdk_device_get_seat (device)); + return GDK_GRAB_SUCCESS; + } + else + { + /* Device is a pointer */ + if (pointer->grab_surface != NULL && + time_ != 0 && pointer->grab_time > time_) + { + return GDK_GRAB_ALREADY_GRABBED; + } + + if (time_ == 0) + time_ = pointer->time; + + pointer->grab_surface = surface; + pointer->grab_time = time_; + _gdk_wayland_surface_set_grab_seat (surface, GDK_SEAT (wayland_seat)); + + g_clear_object (&wayland_seat->cursor); + + if (cursor) + wayland_seat->cursor = g_object_ref (cursor); + + gdk_wayland_device_update_surface_cursor (device); + } + + return GDK_GRAB_SUCCESS; +} + +static void +gdk_wayland_device_ungrab (GdkDevice *device, + guint32 time_) +{ + GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); + GdkWaylandPointerData *pointer = + gdk_wayland_device_get_pointer (wayland_device); + GdkSurface *prev_focus; + + prev_focus = gdk_wayland_device_maybe_emit_ungrab_crossing (device, time_); + + if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) + { + /* Device is a keyboard */ + if (prev_focus) + gdk_wayland_surface_restore_shortcuts (prev_focus, + gdk_device_get_seat (device)); + } + else + { + /* Device is a pointer */ + gdk_wayland_device_update_surface_cursor (device); + + if (pointer->grab_surface) + _gdk_wayland_surface_set_grab_seat (pointer->grab_surface, + NULL); + } +} + +static GdkSurface * +gdk_wayland_device_surface_at_position (GdkDevice *device, + double *win_x, + double *win_y, + GdkModifierType *mask) +{ + GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); + GdkWaylandPointerData *pointer; + + pointer = gdk_wayland_device_get_pointer (wayland_device); + + if (!pointer) + return NULL; + + if (win_x) + *win_x = pointer->surface_x; + if (win_y) + *win_y = pointer->surface_y; + if (mask) + *mask = gdk_wayland_device_get_modifiers (device); + + return pointer->focus; +} + +static void +gdk_wayland_device_class_init (GdkWaylandDeviceClass *klass) +{ + GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); + + device_class->set_surface_cursor = gdk_wayland_device_set_surface_cursor; + device_class->grab = gdk_wayland_device_grab; + device_class->ungrab = gdk_wayland_device_ungrab; + device_class->surface_at_position = gdk_wayland_device_surface_at_position; +} + +static void +gdk_wayland_device_init (GdkWaylandDevice *device_core) +{ + GdkDevice *device; + + device = GDK_DEVICE (device_core); + + _gdk_device_add_axis (device, GDK_AXIS_X, 0, 0, 1); + _gdk_device_add_axis (device, GDK_AXIS_Y, 0, 0, 1); +} + +GdkWaylandPointerData * +gdk_wayland_device_get_pointer (GdkWaylandDevice *wayland_device) +{ + GdkWaylandDevicePrivate *priv = + gdk_wayland_device_get_instance_private (wayland_device); + + return priv->pointer; +} + +void +gdk_wayland_device_set_pointer (GdkWaylandDevice *wayland_device, + GdkWaylandPointerData *pointer) +{ + GdkWaylandDevicePrivate *priv = + gdk_wayland_device_get_instance_private (wayland_device); + + priv->pointer = pointer; +} + +GdkWaylandTouchData * +gdk_wayland_device_get_emulating_touch (GdkWaylandDevice *wayland_device) +{ + GdkWaylandDevicePrivate *priv = + gdk_wayland_device_get_instance_private (wayland_device); + + return priv->emulating_touch; +} + +void +gdk_wayland_device_set_emulating_touch (GdkWaylandDevice *wayland_device, + GdkWaylandTouchData *touch) +{ + GdkWaylandDevicePrivate *priv = + gdk_wayland_device_get_instance_private (wayland_device); + + priv->emulating_touch = touch; +} + +gboolean +gdk_wayland_device_update_surface_cursor (GdkDevice *device) +{ + GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); + GdkWaylandPointerData *pointer = + gdk_wayland_device_get_pointer (wayland_device); + struct wl_buffer *buffer; + int x, y, w, h, scale; + guint next_image_index, next_image_delay; + gboolean retval = G_SOURCE_REMOVE; + GdkWaylandTabletData *tablet; + + tablet = gdk_wayland_seat_find_tablet (seat, device); + + if (pointer->cursor) + { + buffer = _gdk_wayland_cursor_get_buffer (GDK_WAYLAND_DISPLAY (seat->display), + pointer->cursor, + pointer->current_output_scale, + pointer->cursor_image_index, + &x, &y, &w, &h, &scale); + } + else + { + pointer->cursor_timeout_id = 0; + return G_SOURCE_REMOVE; + } + + if (tablet) + { + if (!tablet->current_tool) + { + pointer->cursor_timeout_id = 0; + return G_SOURCE_REMOVE; + } + + zwp_tablet_tool_v2_set_cursor (tablet->current_tool->wp_tablet_tool, + pointer->enter_serial, + pointer->pointer_surface, + x, y); + } + else if (seat->wl_pointer) + { + wl_pointer_set_cursor (seat->wl_pointer, + pointer->enter_serial, + pointer->pointer_surface, + x, y); + } + else + { + pointer->cursor_timeout_id = 0; + return G_SOURCE_REMOVE; + } + + if (buffer) + { + wl_surface_attach (pointer->pointer_surface, buffer, 0, 0); + wl_surface_set_buffer_scale (pointer->pointer_surface, scale); + wl_surface_damage (pointer->pointer_surface, 0, 0, w, h); + wl_surface_commit (pointer->pointer_surface); + } + else + { + wl_surface_attach (pointer->pointer_surface, NULL, 0, 0); + wl_surface_commit (pointer->pointer_surface); + } + + next_image_index = + _gdk_wayland_cursor_get_next_image_index (GDK_WAYLAND_DISPLAY (seat->display), + pointer->cursor, + pointer->current_output_scale, + pointer->cursor_image_index, + &next_image_delay); + + if (next_image_index != pointer->cursor_image_index) + { + if (next_image_delay != pointer->cursor_image_delay || + pointer->cursor_timeout_id == 0) + { + guint id; + GSource *source; + + gdk_wayland_seat_stop_cursor_animation (seat, pointer); + + /* Queue timeout for next frame */ + id = g_timeout_add (next_image_delay, + (GSourceFunc) gdk_wayland_device_update_surface_cursor, + device); + source = g_main_context_find_source_by_id (NULL, id); + g_source_set_static_name (source, "[gtk] gdk_wayland_device_update_surface_cursor"); + pointer->cursor_timeout_id = id; + } + else + retval = G_SOURCE_CONTINUE; + + pointer->cursor_image_index = next_image_index; + pointer->cursor_image_delay = next_image_delay; + } + else + gdk_wayland_seat_stop_cursor_animation (seat, pointer); + + return retval; +} + +GdkModifierType +gdk_wayland_device_get_modifiers (GdkDevice *device) +{ + GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); + GdkWaylandPointerData *pointer = + gdk_wayland_device_get_pointer (wayland_device); + GdkModifierType mask; + + mask = seat->key_modifiers; + + if (pointer) + mask |= pointer->button_modifiers; + + return mask; +} + +void +gdk_wayland_device_query_state (GdkDevice *device, + GdkSurface *surface, + double *win_x, + double *win_y, + GdkModifierType *mask) +{ + GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); + GdkWaylandPointerData *pointer; + double x, y; + + if (mask) + *mask = gdk_wayland_device_get_modifiers (device); + + pointer = gdk_wayland_device_get_pointer (wayland_device); + + if (pointer->focus == surface) + { + x = pointer->surface_x; + y = pointer->surface_y; + } + else + { + x = y = -1; + } + + if (win_x) + *win_x = x; + if (win_y) + *win_y = y; +} + +GdkSurface * +gdk_wayland_device_get_focus (GdkDevice *device) +{ + GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); + GdkWaylandPointerData *pointer; + + if (device == wayland_seat->logical_keyboard) + return wayland_seat->keyboard_focus; + else + { + pointer = gdk_wayland_device_get_pointer (wayland_device); + + if (pointer) + return pointer->focus; + } + + return NULL; +} + +static void +emulate_touch_crossing (GdkSurface *surface, + GdkSurface *child_surface, + GdkDevice *device, + GdkDevice *source, + GdkWaylandTouchData *touch, + GdkEventType type, + GdkCrossingMode mode, + guint32 time_) +{ + GdkEvent *event; + + event = gdk_crossing_event_new (type, + surface, + device, + time_, + 0, + touch->x, touch->y, + mode, + GDK_NOTIFY_NONLINEAR); + + _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event); +} + +void +gdk_wayland_device_unset_touch_grab (GdkDevice *gdk_device, + GdkEventSequence *sequence) +{ + GdkWaylandSeat *seat; + GdkWaylandTouchData *touch; + GdkEvent *event; + + g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device)); + + seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device)); + touch = gdk_wayland_seat_get_touch (seat, + GDK_EVENT_SEQUENCE_TO_SLOT (sequence)); + + if (touch == + gdk_wayland_device_get_emulating_touch (GDK_WAYLAND_DEVICE (seat->logical_touch))) + { + gdk_wayland_device_set_emulating_touch (GDK_WAYLAND_DEVICE (seat->logical_touch), + NULL); + emulate_touch_crossing (touch->surface, NULL, + seat->logical_touch, seat->touch, + touch, GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, + GDK_CURRENT_TIME); + } + + event = gdk_touch_event_new (GDK_TOUCH_CANCEL, + GDK_SLOT_TO_EVENT_SEQUENCE (touch->id), + touch->surface, + seat->logical_touch, + GDK_CURRENT_TIME, + gdk_wayland_device_get_modifiers (seat->logical_touch), + touch->x, touch->y, + NULL, + touch->initial_touch); + _gdk_wayland_display_deliver_event (seat->display, event); +} + +/** + * gdk_wayland_device_get_wl_seat: (skip) + * @device: (type GdkWaylandDevice): a `GdkDevice` + * + * Returns the Wayland `wl_seat` of a `GdkDevice`. + * + * Returns: (transfer none): a Wayland `wl_seat` + */ +struct wl_seat * +gdk_wayland_device_get_wl_seat (GdkDevice *device) +{ + GdkWaylandSeat *seat; + + g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL); + + seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + return seat->wl_seat; +} + +/** + * gdk_wayland_device_get_wl_pointer: (skip) + * @device: (type GdkWaylandDevice): a `GdkDevice` + * + * Returns the Wayland `wl_pointer` of a `GdkDevice`. + * + * Returns: (transfer none): a Wayland `wl_pointer` + */ +struct wl_pointer * +gdk_wayland_device_get_wl_pointer (GdkDevice *device) +{ + GdkWaylandSeat *seat; + + g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL); + + seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + return seat->wl_pointer; +} + +/** + * gdk_wayland_device_get_wl_keyboard: (skip) + * @device: (type GdkWaylandDevice): a `GdkDevice` + * + * Returns the Wayland `wl_keyboard` of a `GdkDevice`. + * + * Returns: (transfer none): a Wayland `wl_keyboard` + */ +struct wl_keyboard * +gdk_wayland_device_get_wl_keyboard (GdkDevice *device) +{ + GdkWaylandSeat *seat; + + g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL); + + seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + return seat->wl_keyboard; +} + +/** + * gdk_wayland_device_get_xkb_keymap: + * @device: (type GdkWaylandDevice): a `GdkDevice` + * + * Returns the `xkb_keymap` of a `GdkDevice`. + * + * Returns: (transfer none): a `struct xkb_keymap` + * + * Since: 4.4 + */ +struct xkb_keymap * +gdk_wayland_device_get_xkb_keymap (GdkDevice *device) +{ + GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + return _gdk_wayland_keymap_get_xkb_keymap (seat->keymap); +} + +GdkKeymap * +_gdk_wayland_device_get_keymap (GdkDevice *device) +{ + GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); + return seat->keymap; +} + +/** + * gdk_wayland_device_get_data_device: (skip) + * @gdk_device: (type GdkWaylandDevice): a `GdkDevice` + * + * Returns the Wayland `wl_data_device` of a `GdkDevice`. + * + * Returns: (transfer none): a Wayland `wl_data_device` + */ +struct wl_data_device * +gdk_wayland_device_get_data_device (GdkDevice *gdk_device) +{ + GdkWaylandSeat *seat; + + g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device), NULL); + + seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device)); + return seat->data_device; +} + +/** + * gdk_wayland_device_set_selection: (skip) + * @gdk_device: (type GdkWaylandDevice): a `GdkDevice` + * @source: the data source for the selection + * + * Sets the selection of the `GdkDevice. + * + * This is calling wl_data_device_set_selection() on + * the `wl_data_device` of @gdk_device. + */ +void +gdk_wayland_device_set_selection (GdkDevice *gdk_device, + struct wl_data_source *source) +{ + GdkWaylandSeat *seat; + guint32 serial; + + g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device)); + + seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device)); + serial = _gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL); + wl_data_device_set_selection (seat->data_device, source, serial); +} + +/** + * gdk_wayland_device_get_node_path: + * @device: (type GdkWaylandDevice): a `GdkDevice` + * + * Returns the `/dev/input/event*` path of this device. + * + * For `GdkDevice`s that possibly coalesce multiple hardware + * devices (eg. mouse, keyboard, touch,...), this function + * will return %NULL. + * + * This is most notably implemented for devices of type + * %GDK_SOURCE_PEN, %GDK_SOURCE_TABLET_PAD. + * + * Returns: (nullable) (transfer none): the `/dev/input/event*` + * path of this device + */ +const char * +gdk_wayland_device_get_node_path (GdkDevice *device) +{ + GdkWaylandTabletData *tablet; + GdkWaylandTabletPadData *pad; + + GdkSeat *seat; + + g_return_val_if_fail (GDK_IS_DEVICE (device), NULL); + + seat = gdk_device_get_seat (device); + tablet = gdk_wayland_seat_find_tablet (GDK_WAYLAND_SEAT (seat), device); + if (tablet) + return tablet->path; + + pad = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat), device); + if (pad) + return pad->path; + + return NULL; +} + +static void +emulate_focus (GdkSurface *surface, + GdkDevice *device, + gboolean focus_in, + guint32 time_) +{ + GdkEvent *event = gdk_focus_event_new (surface, device, focus_in); + + _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event); +} + +static void +emulate_crossing (GdkSurface *surface, + GdkSurface *child_surface, + GdkDevice *device, + GdkEventType type, + GdkCrossingMode mode, + guint32 time_) +{ + GdkEvent *event; + GdkModifierType state; + double x, y; + + gdk_surface_get_device_position (surface, device, &x, &y, &state); + event = gdk_crossing_event_new (type, + surface, + device, + time_, + state, + x, y, + mode, + GDK_NOTIFY_NONLINEAR); + + _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event); +} + +static void +device_emit_grab_crossing (GdkDevice *device, + GdkSurface *from, + GdkSurface *to, + GdkCrossingMode mode, + guint32 time_) +{ + if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) + { + if (from) + emulate_focus (from, device, FALSE, time_); + if (to) + emulate_focus (to, device, TRUE, time_); + } + else + { + if (from) + emulate_crossing (from, to, device, GDK_LEAVE_NOTIFY, mode, time_); + if (to) + emulate_crossing (to, from, device, GDK_ENTER_NOTIFY, mode, time_); + } +} + +void +gdk_wayland_device_maybe_emit_grab_crossing (GdkDevice *device, + GdkSurface *window, + guint32 time) +{ + GdkSurface *surface = gdk_wayland_device_get_focus (device); + GdkSurface *focus = window; + + if (focus != surface) + device_emit_grab_crossing (device, focus, window, GDK_CROSSING_GRAB, time); +} + +GdkSurface* +gdk_wayland_device_maybe_emit_ungrab_crossing (GdkDevice *device, + guint32 time_) +{ + GdkDeviceGrabInfo *grab; + GdkSurface *focus = NULL; + GdkSurface *surface = NULL; + GdkSurface *prev_focus = NULL; + + focus = gdk_wayland_device_get_focus (device); + grab = _gdk_display_get_last_device_grab (gdk_device_get_display (device), device); + + if (grab) + { + prev_focus = grab->surface; + surface = grab->surface; + } + + if (focus != surface) + device_emit_grab_crossing (device, prev_focus, focus, GDK_CROSSING_UNGRAB, time_); + + return prev_focus; +} diff --git a/gdk/wayland/gdkseat-wayland.c b/gdk/wayland/gdkseat-wayland.c index a5e1ca95f6..d3e31a4920 100644 --- a/gdk/wayland/gdkseat-wayland.c +++ b/gdk/wayland/gdkseat-wayland.c @@ -91,14 +91,6 @@ G_DEFINE_TYPE (GdkWaylandSeat, gdk_wayland_seat, GDK_TYPE_SEAT) -typedef struct -{ - GdkWaylandTouchData *emulating_touch; /* Only used on wd->logical_touch */ - GdkWaylandPointerData *pointer; -} GdkWaylandDevicePrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (GdkWaylandDevice, gdk_wayland_device, GDK_TYPE_DEVICE) - static void init_pointer_data (GdkWaylandPointerData *pointer_data, GdkDisplay *display_wayland, GdkDevice *logical_device); @@ -113,8 +105,9 @@ static void deliver_key_event (GdkWaylandSeat *seat, uint32_t state, gboolean from_key_repeat); -static void -gdk_wayland_pointer_stop_cursor_animation (GdkWaylandPointerData *pointer) +void +gdk_wayland_seat_stop_cursor_animation (GdkWaylandSeat *seat, + GdkWaylandPointerData *pointer) { if (pointer->cursor_timeout_id > 0) { @@ -126,7 +119,7 @@ gdk_wayland_pointer_stop_cursor_animation (GdkWaylandPointerData *pointer) pointer->cursor_image_index = 0; } -static GdkWaylandTabletData * +GdkWaylandTabletData * gdk_wayland_seat_find_tablet (GdkWaylandSeat *seat, GdkDevice *device) { @@ -161,245 +154,6 @@ gdk_wayland_seat_find_pad (GdkWaylandSeat *seat, return NULL; } -static GdkWaylandPointerData * -gdk_wayland_device_get_pointer (GdkWaylandDevice *wayland_device) -{ - GdkWaylandDevicePrivate *priv = - gdk_wayland_device_get_instance_private (wayland_device); - - return priv->pointer; -} - -static void -gdk_wayland_device_set_pointer (GdkWaylandDevice *wayland_device, - GdkWaylandPointerData *pointer) -{ - GdkWaylandDevicePrivate *priv = - gdk_wayland_device_get_instance_private (wayland_device); - - priv->pointer = pointer; -} - -static GdkWaylandTouchData * -gdk_wayland_device_get_emulating_touch (GdkWaylandDevice *wayland_device) -{ - GdkWaylandDevicePrivate *priv = - gdk_wayland_device_get_instance_private (wayland_device); - - return priv->emulating_touch; -} - -static void -gdk_wayland_device_set_emulating_touch (GdkWaylandDevice *wayland_device, - GdkWaylandTouchData *touch) -{ - GdkWaylandDevicePrivate *priv = - gdk_wayland_device_get_instance_private (wayland_device); - - priv->emulating_touch = touch; -} - -static gboolean -gdk_wayland_device_update_surface_cursor (GdkDevice *device) -{ - GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); - GdkWaylandPointerData *pointer = - gdk_wayland_device_get_pointer (wayland_device); - struct wl_buffer *buffer; - int x, y, w, h, scale; - guint next_image_index, next_image_delay; - gboolean retval = G_SOURCE_REMOVE; - GdkWaylandTabletData *tablet; - - tablet = gdk_wayland_seat_find_tablet (seat, device); - - if (pointer->cursor) - { - buffer = _gdk_wayland_cursor_get_buffer (GDK_WAYLAND_DISPLAY (seat->display), - pointer->cursor, - pointer->current_output_scale, - pointer->cursor_image_index, - &x, &y, &w, &h, &scale); - } - else - { - pointer->cursor_timeout_id = 0; - return G_SOURCE_REMOVE; - } - - if (tablet) - { - if (!tablet->current_tool) - { - pointer->cursor_timeout_id = 0; - return G_SOURCE_REMOVE; - } - - zwp_tablet_tool_v2_set_cursor (tablet->current_tool->wp_tablet_tool, - pointer->enter_serial, - pointer->pointer_surface, - x, y); - } - else if (seat->wl_pointer) - { - wl_pointer_set_cursor (seat->wl_pointer, - pointer->enter_serial, - pointer->pointer_surface, - x, y); - } - else - { - pointer->cursor_timeout_id = 0; - return G_SOURCE_REMOVE; - } - - if (buffer) - { - wl_surface_attach (pointer->pointer_surface, buffer, 0, 0); - wl_surface_set_buffer_scale (pointer->pointer_surface, scale); - wl_surface_damage (pointer->pointer_surface, 0, 0, w, h); - wl_surface_commit (pointer->pointer_surface); - } - else - { - wl_surface_attach (pointer->pointer_surface, NULL, 0, 0); - wl_surface_commit (pointer->pointer_surface); - } - - next_image_index = - _gdk_wayland_cursor_get_next_image_index (GDK_WAYLAND_DISPLAY (seat->display), - pointer->cursor, - pointer->current_output_scale, - pointer->cursor_image_index, - &next_image_delay); - - if (next_image_index != pointer->cursor_image_index) - { - if (next_image_delay != pointer->cursor_image_delay || - pointer->cursor_timeout_id == 0) - { - guint id; - GSource *source; - - gdk_wayland_pointer_stop_cursor_animation (pointer); - - /* Queue timeout for next frame */ - id = g_timeout_add (next_image_delay, - (GSourceFunc) gdk_wayland_device_update_surface_cursor, - device); - source = g_main_context_find_source_by_id (NULL, id); - g_source_set_static_name (source, "[gtk] gdk_wayland_device_update_surface_cursor"); - pointer->cursor_timeout_id = id; - } - else - retval = G_SOURCE_CONTINUE; - - pointer->cursor_image_index = next_image_index; - pointer->cursor_image_delay = next_image_delay; - } - else - gdk_wayland_pointer_stop_cursor_animation (pointer); - - return retval; -} - -static void -gdk_wayland_device_set_surface_cursor (GdkDevice *device, - GdkSurface *surface, - GdkCursor *cursor) -{ - GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); - GdkWaylandPointerData *pointer = - gdk_wayland_device_get_pointer (wayland_device); - - if (device == seat->logical_touch) - return; - - if (seat->grab_cursor) - cursor = seat->grab_cursor; - - if (pointer->cursor != NULL && - cursor != NULL && - gdk_cursor_equal (cursor, pointer->cursor)) - return; - - if (cursor == NULL) - { - if (!pointer->cursor_is_default) - { - g_clear_object (&pointer->cursor); - pointer->cursor = gdk_cursor_new_from_name ("default", NULL); - pointer->cursor_is_default = TRUE; - - gdk_wayland_pointer_stop_cursor_animation (pointer); - gdk_wayland_device_update_surface_cursor (device); - } - else - { - /* Nothing to do, we'already using the default cursor */ - } - } - else - { - g_set_object (&pointer->cursor, cursor); - pointer->cursor_is_default = FALSE; - - gdk_wayland_pointer_stop_cursor_animation (pointer); - gdk_wayland_device_update_surface_cursor (device); - } -} - -static GdkModifierType -device_get_modifiers (GdkDevice *device) -{ - GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); - GdkWaylandPointerData *pointer = - gdk_wayland_device_get_pointer (wayland_device); - GdkModifierType mask; - - mask = seat->key_modifiers; - - if (pointer) - mask |= pointer->button_modifiers; - - return mask; -} - -void -gdk_wayland_device_query_state (GdkDevice *device, - GdkSurface *surface, - double *win_x, - double *win_y, - GdkModifierType *mask) -{ - GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); - GdkWaylandPointerData *pointer; - double x, y; - - if (mask) - *mask = device_get_modifiers (device); - - pointer = gdk_wayland_device_get_pointer (wayland_device); - - if (pointer->focus == surface) - { - x = pointer->surface_x; - y = pointer->surface_y; - } - else - { - x = y = -1; - } - - if (win_x) - *win_x = x; - if (win_y) - *win_y = y; -} - static void emulate_crossing (GdkSurface *surface, GdkSurface *child_surface, @@ -449,311 +203,6 @@ emulate_touch_crossing (GdkSurface *surface, _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event); } -static void -emulate_focus (GdkSurface *surface, - GdkDevice *device, - gboolean focus_in, - guint32 time_) -{ - GdkEvent *event = gdk_focus_event_new (surface, device, focus_in); - - _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event); -} - -static void -device_emit_grab_crossing (GdkDevice *device, - GdkSurface *from, - GdkSurface *to, - GdkCrossingMode mode, - guint32 time_) -{ - if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) - { - if (from) - emulate_focus (from, device, FALSE, time_); - if (to) - emulate_focus (to, device, TRUE, time_); - } - else - { - if (from) - emulate_crossing (from, to, device, GDK_LEAVE_NOTIFY, mode, time_); - if (to) - emulate_crossing (to, from, device, GDK_ENTER_NOTIFY, mode, time_); - } -} - -GdkSurface * -gdk_wayland_device_get_focus (GdkDevice *device) -{ - GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); - GdkWaylandPointerData *pointer; - - if (device == wayland_seat->logical_keyboard) - return wayland_seat->keyboard_focus; - else - { - pointer = gdk_wayland_device_get_pointer (wayland_device); - - if (pointer) - return pointer->focus; - } - - return NULL; -} - -static void -device_maybe_emit_grab_crossing (GdkDevice *device, - GdkSurface *window, - guint32 time) -{ - GdkSurface *surface = gdk_wayland_device_get_focus (device); - GdkSurface *focus = window; - - if (focus != surface) - device_emit_grab_crossing (device, focus, window, GDK_CROSSING_GRAB, time); -} - -static GdkSurface* -device_maybe_emit_ungrab_crossing (GdkDevice *device, - guint32 time_) -{ - GdkDeviceGrabInfo *grab; - GdkSurface *focus = NULL; - GdkSurface *surface = NULL; - GdkSurface *prev_focus = NULL; - - focus = gdk_wayland_device_get_focus (device); - grab = _gdk_display_get_last_device_grab (gdk_device_get_display (device), device); - - if (grab) - { - prev_focus = grab->surface; - surface = grab->surface; - } - - if (focus != surface) - device_emit_grab_crossing (device, prev_focus, focus, GDK_CROSSING_UNGRAB, time_); - - return prev_focus; -} - -static GdkGrabStatus -gdk_wayland_device_grab (GdkDevice *device, - GdkSurface *surface, - gboolean owner_events, - GdkEventMask event_mask, - GdkSurface *confine_to, - GdkCursor *cursor, - guint32 time_) -{ - GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); - GdkWaylandPointerData *pointer = - gdk_wayland_device_get_pointer (wayland_device); - - if (GDK_IS_DRAG_SURFACE (surface) && - gdk_surface_get_mapped (surface)) - { - g_warning ("Surface %p is already mapped at the time of grabbing. " - "gdk_seat_grab() should be used to simultaneously grab input " - "and show this popup. You may find oddities ahead.", - surface); - } - - device_maybe_emit_grab_crossing (device, surface, time_); - - if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) - { - /* Device is a keyboard */ - gdk_wayland_surface_inhibit_shortcuts (surface, - gdk_device_get_seat (device)); - return GDK_GRAB_SUCCESS; - } - else - { - /* Device is a pointer */ - if (pointer->grab_surface != NULL && - time_ != 0 && pointer->grab_time > time_) - { - return GDK_GRAB_ALREADY_GRABBED; - } - - if (time_ == 0) - time_ = pointer->time; - - pointer->grab_surface = surface; - pointer->grab_time = time_; - _gdk_wayland_surface_set_grab_seat (surface, GDK_SEAT (wayland_seat)); - - g_clear_object (&wayland_seat->cursor); - - if (cursor) - wayland_seat->cursor = g_object_ref (cursor); - - gdk_wayland_device_update_surface_cursor (device); - } - - return GDK_GRAB_SUCCESS; -} - -static void -gdk_wayland_device_ungrab (GdkDevice *device, - guint32 time_) -{ - GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); - GdkWaylandPointerData *pointer = - gdk_wayland_device_get_pointer (wayland_device); - GdkSurface *prev_focus; - - prev_focus = device_maybe_emit_ungrab_crossing (device, time_); - - if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) - { - /* Device is a keyboard */ - if (prev_focus) - gdk_wayland_surface_restore_shortcuts (prev_focus, - gdk_device_get_seat (device)); - } - else - { - /* Device is a pointer */ - gdk_wayland_device_update_surface_cursor (device); - - if (pointer->grab_surface) - _gdk_wayland_surface_set_grab_seat (pointer->grab_surface, - NULL); - } -} - -static GdkSurface * -gdk_wayland_device_surface_at_position (GdkDevice *device, - double *win_x, - double *win_y, - GdkModifierType *mask) -{ - GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device); - GdkWaylandPointerData *pointer; - - pointer = gdk_wayland_device_get_pointer (wayland_device); - - if (!pointer) - return NULL; - - if (win_x) - *win_x = pointer->surface_x; - if (win_y) - *win_y = pointer->surface_y; - if (mask) - *mask = device_get_modifiers (device); - - return pointer->focus; -} - -static void -gdk_wayland_device_class_init (GdkWaylandDeviceClass *klass) -{ - GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); - - device_class->set_surface_cursor = gdk_wayland_device_set_surface_cursor; - device_class->grab = gdk_wayland_device_grab; - device_class->ungrab = gdk_wayland_device_ungrab; - device_class->surface_at_position = gdk_wayland_device_surface_at_position; -} - -static void -gdk_wayland_device_init (GdkWaylandDevice *device_core) -{ - GdkDevice *device; - - device = GDK_DEVICE (device_core); - - _gdk_device_add_axis (device, GDK_AXIS_X, 0, 0, 1); - _gdk_device_add_axis (device, GDK_AXIS_Y, 0, 0, 1); -} - -/** - * gdk_wayland_device_get_wl_seat: (skip) - * @device: (type GdkWaylandDevice): a `GdkDevice` - * - * Returns the Wayland `wl_seat` of a `GdkDevice`. - * - * Returns: (transfer none): a Wayland `wl_seat` - */ -struct wl_seat * -gdk_wayland_device_get_wl_seat (GdkDevice *device) -{ - GdkWaylandSeat *seat; - - g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL); - - seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - return seat->wl_seat; -} - -/** - * gdk_wayland_device_get_wl_pointer: (skip) - * @device: (type GdkWaylandDevice): a `GdkDevice` - * - * Returns the Wayland `wl_pointer` of a `GdkDevice`. - * - * Returns: (transfer none): a Wayland `wl_pointer` - */ -struct wl_pointer * -gdk_wayland_device_get_wl_pointer (GdkDevice *device) -{ - GdkWaylandSeat *seat; - - g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL); - - seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - return seat->wl_pointer; -} - -/** - * gdk_wayland_device_get_wl_keyboard: (skip) - * @device: (type GdkWaylandDevice): a `GdkDevice` - * - * Returns the Wayland `wl_keyboard` of a `GdkDevice`. - * - * Returns: (transfer none): a Wayland `wl_keyboard` - */ -struct wl_keyboard * -gdk_wayland_device_get_wl_keyboard (GdkDevice *device) -{ - GdkWaylandSeat *seat; - - g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL); - - seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - return seat->wl_keyboard; -} - -/** - * gdk_wayland_device_get_xkb_keymap: - * @device: (type GdkWaylandDevice): a `GdkDevice` - * - * Returns the `xkb_keymap` of a `GdkDevice`. - * - * Returns: (transfer none): a `struct xkb_keymap` - * - * Since: 4.4 - */ -struct xkb_keymap * -gdk_wayland_device_get_xkb_keymap (GdkDevice *device) -{ - GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - return _gdk_wayland_keymap_get_xkb_keymap (seat->keymap); -} - -GdkKeymap * -_gdk_wayland_device_get_keymap (GdkDevice *device) -{ - GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device)); - return seat->keymap; -} - static void gdk_wayland_seat_discard_pending_offer (GdkWaylandSeat *seat) { @@ -1096,7 +545,7 @@ flush_discrete_scroll_event (GdkWaylandSeat *seat, source, NULL, seat->pointer_info.time, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), direction, value120_x, value120_y); @@ -1112,7 +561,7 @@ flush_discrete_scroll_event (GdkWaylandSeat *seat, source, NULL, seat->pointer_info.time, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), direction); } } @@ -1135,7 +584,7 @@ flush_smooth_scroll_event (GdkWaylandSeat *seat, source, NULL, seat->pointer_info.time, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), delta_x, delta_y, is_stop, GDK_SCROLL_UNIT_SURFACE); @@ -1307,7 +756,7 @@ pointer_handle_leave (void *data, g_object_unref (seat->pointer_info.focus); seat->pointer_info.focus = NULL; if (seat->cursor) - gdk_wayland_pointer_stop_cursor_animation (&seat->pointer_info); + gdk_wayland_seat_stop_cursor_animation (seat, &seat->pointer_info); if (display_wayland->seat_version < WL_POINTER_HAS_FRAME) gdk_wayland_seat_flush_frame_event (seat); @@ -1335,7 +784,7 @@ pointer_handle_motion (void *data, seat->logical_pointer, NULL, time, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), seat->pointer_info.surface_x, seat->pointer_info.surface_y, NULL); @@ -1396,7 +845,7 @@ pointer_handle_button (void *data, seat->logical_pointer, NULL, time, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), gdk_button, seat->pointer_info.surface_x, seat->pointer_info.surface_y, @@ -1902,7 +1351,7 @@ deliver_key_event (GdkWaylandSeat *seat, seat->logical_keyboard, time_, key, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), _gdk_wayland_keymap_key_is_modifier (keymap, key), &translated, &no_lock, @@ -2126,7 +1575,7 @@ gdk_wayland_seat_add_touch (GdkWaylandSeat *seat, return touch; } -static GdkWaylandTouchData * +GdkWaylandTouchData * gdk_wayland_seat_get_touch (GdkWaylandSeat *seat, uint32_t id) { @@ -2224,7 +1673,7 @@ touch_handle_down (void *data, touch->surface, seat->logical_touch, time, - device_get_modifiers (seat->logical_touch), + gdk_wayland_device_get_modifiers (seat->logical_touch), touch->x, touch->y, NULL, touch->initial_touch); @@ -2267,7 +1716,7 @@ touch_handle_up (void *data, touch->surface, seat->logical_touch, time, - device_get_modifiers (seat->logical_touch), + gdk_wayland_device_get_modifiers (seat->logical_touch), touch->x, touch->y, NULL, touch->initial_touch); @@ -2315,7 +1764,7 @@ touch_handle_motion (void *data, touch->surface, seat->logical_touch, time, - device_get_modifiers (seat->logical_touch), + gdk_wayland_device_get_modifiers (seat->logical_touch), touch->x, touch->y, NULL, touch->initial_touch); @@ -2357,7 +1806,7 @@ touch_handle_cancel (void *data, touch->surface, seat->logical_touch, GDK_CURRENT_TIME, - device_get_modifiers (seat->logical_touch), + gdk_wayland_device_get_modifiers (seat->logical_touch), touch->x, touch->y, NULL, touch->initial_touch); @@ -2407,7 +1856,7 @@ emit_gesture_swipe_event (GdkWaylandSeat *seat, GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence), seat->logical_pointer, _time, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), phase, seat->pointer_info.surface_x, seat->pointer_info.surface_y, @@ -2501,7 +1950,7 @@ emit_gesture_pinch_event (GdkWaylandSeat *seat, GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence), seat->logical_pointer, _time, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), phase, seat->pointer_info.surface_x, seat->pointer_info.surface_y, @@ -2597,7 +2046,7 @@ emit_gesture_hold_event (GdkWaylandSeat *seat, GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence), seat->logical_pointer, _time, - device_get_modifiers (seat->logical_pointer), + gdk_wayland_device_get_modifiers (seat->logical_pointer), phase, seat->pointer_info.surface_x, seat->pointer_info.surface_y, @@ -3417,7 +2866,8 @@ tablet_tool_handle_proximity_out (void *data, tablet->pointer_info.time); gdk_wayland_tablet_set_frame_event (tablet, event); - gdk_wayland_pointer_stop_cursor_animation (&tablet->pointer_info); + gdk_wayland_seat_stop_cursor_animation (GDK_WAYLAND_SEAT (tool->seat), + &tablet->pointer_info); tablet->pointer_info.pointer_surface_outputs = g_slist_remove (tablet->pointer_info.pointer_surface_outputs, @@ -3453,7 +2903,7 @@ tablet_create_button_event_frame (GdkWaylandTabletData *tablet, tablet->logical_device, tablet->current_tool->tool, tablet->pointer_info.time, - device_get_modifiers (tablet->logical_device), + gdk_wayland_device_get_modifiers (tablet->logical_device), button, tablet->pointer_info.surface_x, tablet->pointer_info.surface_y, @@ -3517,7 +2967,7 @@ tablet_tool_handle_motion (void *data, tablet->logical_device, tool->tool, tablet->pointer_info.time, - device_get_modifiers (tablet->logical_device), + gdk_wayland_device_get_modifiers (tablet->logical_device), tablet->pointer_info.surface_x, tablet->pointer_info.surface_y, tablet_copy_axes (tablet)); @@ -3709,7 +3159,7 @@ tablet_tool_handle_wheel (void *data, tablet->logical_device, tablet->current_tool->tool, tablet->pointer_info.time, - device_get_modifiers (tablet->logical_device), + gdk_wayland_device_get_modifiers (tablet->logical_device), 0, clicks, FALSE, GDK_SCROLL_UNIT_WHEEL); @@ -4531,8 +3981,8 @@ gdk_wayland_seat_grab (GdkSeat *seat, if (wayland_seat->logical_pointer && capabilities & GDK_SEAT_CAPABILITY_POINTER) { - device_maybe_emit_grab_crossing (wayland_seat->logical_pointer, - surface, evtime); + gdk_wayland_device_maybe_emit_grab_crossing (wayland_seat->logical_pointer, + surface, evtime); _gdk_display_add_device_grab (display, wayland_seat->logical_pointer, @@ -4551,8 +4001,8 @@ gdk_wayland_seat_grab (GdkSeat *seat, if (wayland_seat->logical_touch && capabilities & GDK_SEAT_CAPABILITY_TOUCH) { - device_maybe_emit_grab_crossing (wayland_seat->logical_touch, - surface, evtime); + gdk_wayland_device_maybe_emit_grab_crossing (wayland_seat->logical_touch, + surface, evtime); _gdk_display_add_device_grab (display, wayland_seat->logical_touch, @@ -4567,8 +4017,8 @@ gdk_wayland_seat_grab (GdkSeat *seat, if (wayland_seat->logical_keyboard && capabilities & GDK_SEAT_CAPABILITY_KEYBOARD) { - device_maybe_emit_grab_crossing (wayland_seat->logical_keyboard, - surface, evtime); + gdk_wayland_device_maybe_emit_grab_crossing (wayland_seat->logical_keyboard, + surface, evtime); _gdk_display_add_device_grab (display, wayland_seat->logical_keyboard, @@ -4591,9 +4041,9 @@ gdk_wayland_seat_grab (GdkSeat *seat, { GdkWaylandTabletData *tablet = l->data; - device_maybe_emit_grab_crossing (tablet->logical_device, - surface, - evtime); + gdk_wayland_device_maybe_emit_grab_crossing (tablet->logical_device, + surface, + evtime); _gdk_display_add_device_grab (display, tablet->logical_device, @@ -4625,8 +4075,8 @@ gdk_wayland_seat_ungrab (GdkSeat *seat) if (wayland_seat->logical_pointer) { - device_maybe_emit_ungrab_crossing (wayland_seat->logical_pointer, - GDK_CURRENT_TIME); + gdk_wayland_device_maybe_emit_ungrab_crossing (wayland_seat->logical_pointer, + GDK_CURRENT_TIME); gdk_wayland_device_update_surface_cursor (wayland_seat->logical_pointer); } @@ -4635,8 +4085,8 @@ gdk_wayland_seat_ungrab (GdkSeat *seat) { GdkSurface *prev_focus; - prev_focus = device_maybe_emit_ungrab_crossing (wayland_seat->logical_keyboard, - GDK_CURRENT_TIME); + prev_focus = gdk_wayland_device_maybe_emit_ungrab_crossing (wayland_seat->logical_keyboard, + GDK_CURRENT_TIME); if (prev_focus) gdk_wayland_surface_restore_shortcuts (prev_focus, seat); } @@ -4932,43 +4382,6 @@ _gdk_wayland_seat_get_last_implicit_grab_serial (GdkWaylandSeat *seat, return serial; } -void -gdk_wayland_device_unset_touch_grab (GdkDevice *gdk_device, - GdkEventSequence *sequence) -{ - GdkWaylandSeat *seat; - GdkWaylandTouchData *touch; - GdkEvent *event; - - g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device)); - - seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device)); - touch = gdk_wayland_seat_get_touch (seat, - GDK_EVENT_SEQUENCE_TO_SLOT (sequence)); - - if (touch == - gdk_wayland_device_get_emulating_touch (GDK_WAYLAND_DEVICE (seat->logical_touch))) - { - gdk_wayland_device_set_emulating_touch (GDK_WAYLAND_DEVICE (seat->logical_touch), - NULL); - emulate_touch_crossing (touch->surface, NULL, - seat->logical_touch, seat->touch, - touch, GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, - GDK_CURRENT_TIME); - } - - event = gdk_touch_event_new (GDK_TOUCH_CANCEL, - GDK_SLOT_TO_EVENT_SEQUENCE (touch->id), - touch->surface, - seat->logical_touch, - GDK_CURRENT_TIME, - device_get_modifiers (seat->logical_touch), - touch->x, touch->y, - NULL, - touch->initial_touch); - _gdk_wayland_display_deliver_event (seat->display, event); -} - void gdk_wayland_seat_set_global_cursor (GdkSeat *seat, GdkCursor *cursor) @@ -4979,9 +4392,9 @@ gdk_wayland_seat_set_global_cursor (GdkSeat *seat, pointer = gdk_seat_get_pointer (seat); g_set_object (&wayland_seat->grab_cursor, cursor); - gdk_wayland_device_set_surface_cursor (pointer, - gdk_wayland_device_get_focus (pointer), - NULL); + GDK_DEVICE_GET_CLASS (pointer)->set_surface_cursor (pointer, + gdk_wayland_device_get_focus (pointer), + NULL); } void @@ -4993,49 +4406,6 @@ gdk_wayland_seat_set_drag (GdkSeat *seat, g_set_object (&wayland_seat->drag, drag); } -/** - * gdk_wayland_device_get_data_device: (skip) - * @gdk_device: (type GdkWaylandDevice): a `GdkDevice` - * - * Returns the Wayland `wl_data_device` of a `GdkDevice`. - * - * Returns: (transfer none): a Wayland `wl_data_device` - */ -struct wl_data_device * -gdk_wayland_device_get_data_device (GdkDevice *gdk_device) -{ - GdkWaylandSeat *seat; - - g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device), NULL); - - seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device)); - return seat->data_device; -} - -/** - * gdk_wayland_device_set_selection: (skip) - * @gdk_device: (type GdkWaylandDevice): a `GdkDevice` - * @source: the data source for the selection - * - * Sets the selection of the `GdkDevice. - * - * This is calling wl_data_device_set_selection() on - * the `wl_data_device` of @gdk_device. - */ -void -gdk_wayland_device_set_selection (GdkDevice *gdk_device, - struct wl_data_source *source) -{ - GdkWaylandSeat *seat; - guint32 serial; - - g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device)); - - seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device)); - serial = _gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL); - wl_data_device_set_selection (seat->data_device, source, serial); -} - /** * gdk_wayland_seat_get_wl_seat: (skip) * @seat: (type GdkWaylandSeat): a `GdkSeat` @@ -5051,41 +4421,3 @@ gdk_wayland_seat_get_wl_seat (GdkSeat *seat) return GDK_WAYLAND_SEAT (seat)->wl_seat; } - -/** - * gdk_wayland_device_get_node_path: - * @device: (type GdkWaylandDevice): a `GdkDevice` - * - * Returns the `/dev/input/event*` path of this device. - * - * For `GdkDevice`s that possibly coalesce multiple hardware - * devices (eg. mouse, keyboard, touch,...), this function - * will return %NULL. - * - * This is most notably implemented for devices of type - * %GDK_SOURCE_PEN, %GDK_SOURCE_TABLET_PAD. - * - * Returns: (nullable) (transfer none): the `/dev/input/event*` - * path of this device - */ -const char * -gdk_wayland_device_get_node_path (GdkDevice *device) -{ - GdkWaylandTabletData *tablet; - GdkWaylandTabletPadData *pad; - - GdkSeat *seat; - - g_return_val_if_fail (GDK_IS_DEVICE (device), NULL); - - seat = gdk_device_get_seat (device); - tablet = gdk_wayland_seat_find_tablet (GDK_WAYLAND_SEAT (seat), device); - if (tablet) - return tablet->path; - - pad = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat), device); - if (pad) - return pad->path; - - return NULL; -} diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build index 79a770c1f1..48317bdb88 100644 --- a/gdk/wayland/meson.build +++ b/gdk/wayland/meson.build @@ -5,6 +5,7 @@ gdk_wayland_sources = files([ 'gdkcairocontext-wayland.c', 'gdkclipboard-wayland.c', 'gdkcursor-wayland.c', + 'gdkdevice-wayland.c', 'gdkdevicepad-wayland.c', 'gdkdisplay-wayland.c', 'gdkdrag-wayland.c',