|
|
|
@ -25,10 +25,12 @@
|
|
|
|
|
#include <gdk/gdkwindow.h>
|
|
|
|
|
#include <gdk/gdktypes.h>
|
|
|
|
|
#include "gdkprivate-wayland.h"
|
|
|
|
|
#include "gdkseat-wayland.h"
|
|
|
|
|
#include "gdkwayland.h"
|
|
|
|
|
#include "gdkkeysyms.h"
|
|
|
|
|
#include "gdkdeviceprivate.h"
|
|
|
|
|
#include "gdkdevicemanagerprivate.h"
|
|
|
|
|
#include "gdkseatprivate.h"
|
|
|
|
|
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
|
|
|
|
|
|
|
|
|
#include <xkbcommon/xkbcommon.h>
|
|
|
|
@ -52,8 +54,10 @@ struct _GdkWaylandTouchData
|
|
|
|
|
guint initial_touch : 1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _GdkWaylandDeviceData
|
|
|
|
|
struct _GdkWaylandSeat
|
|
|
|
|
{
|
|
|
|
|
GdkSeat parent_instance;
|
|
|
|
|
|
|
|
|
|
guint32 id;
|
|
|
|
|
struct wl_seat *wl_seat;
|
|
|
|
|
struct wl_pointer *wl_pointer;
|
|
|
|
@ -114,6 +118,8 @@ struct _GdkWaylandDeviceData
|
|
|
|
|
gdouble gesture_scale;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (GdkWaylandSeat, gdk_wayland_seat, GDK_TYPE_SEAT)
|
|
|
|
|
|
|
|
|
|
struct _GdkWaylandDevice
|
|
|
|
|
{
|
|
|
|
|
GdkDevice parent_instance;
|
|
|
|
@ -397,6 +403,7 @@ emulate_crossing (GdkWindow *window,
|
|
|
|
|
event->crossing.detail = GDK_NOTIFY_NONLINEAR;
|
|
|
|
|
gdk_event_set_device (event, device);
|
|
|
|
|
gdk_event_set_source_device (event, device);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
|
|
|
|
|
|
|
|
|
gdk_window_get_device_position_double (window, device,
|
|
|
|
|
&event->crossing.x, &event->crossing.y,
|
|
|
|
@ -427,6 +434,7 @@ emulate_touch_crossing (GdkWindow *window,
|
|
|
|
|
event->crossing.detail = GDK_NOTIFY_NONLINEAR;
|
|
|
|
|
gdk_event_set_device (event, device);
|
|
|
|
|
gdk_event_set_source_device (event, source);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
|
|
|
|
|
|
|
|
|
event->crossing.x = touch->x;
|
|
|
|
|
event->crossing.y = touch->y;
|
|
|
|
@ -449,6 +457,7 @@ emulate_focus (GdkWindow *window,
|
|
|
|
|
event->focus_change.in = focus_in;
|
|
|
|
|
gdk_event_set_device (event, device);
|
|
|
|
|
gdk_event_set_source_device (event, device);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
|
|
|
|
|
|
|
|
|
_gdk_wayland_display_deliver_event (gdk_window_get_display (window), event);
|
|
|
|
|
}
|
|
|
|
@ -942,6 +951,7 @@ pointer_handle_enter (void *data,
|
|
|
|
|
event->crossing.window = g_object_ref (device->pointer_focus);
|
|
|
|
|
gdk_event_set_device (event, device->master_pointer);
|
|
|
|
|
gdk_event_set_source_device (event, device->pointer);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
|
|
|
|
event->crossing.subwindow = NULL;
|
|
|
|
|
event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
|
|
|
|
|
event->crossing.mode = GDK_CROSSING_NORMAL;
|
|
|
|
@ -989,6 +999,7 @@ pointer_handle_leave (void *data,
|
|
|
|
|
event->crossing.window = g_object_ref (device->pointer_focus);
|
|
|
|
|
gdk_event_set_device (event, device->master_pointer);
|
|
|
|
|
gdk_event_set_source_device (event, device->pointer);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
|
|
|
|
event->crossing.subwindow = NULL;
|
|
|
|
|
event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
|
|
|
|
|
event->crossing.mode = GDK_CROSSING_NORMAL;
|
|
|
|
@ -1041,6 +1052,7 @@ pointer_handle_motion (void *data,
|
|
|
|
|
event->motion.window = g_object_ref (device->pointer_focus);
|
|
|
|
|
gdk_event_set_device (event, device->master_pointer);
|
|
|
|
|
gdk_event_set_source_device (event, device->pointer);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
|
|
|
|
event->motion.time = time;
|
|
|
|
|
event->motion.axes = NULL;
|
|
|
|
|
event->motion.state = device->button_modifiers | device->key_modifiers;
|
|
|
|
@ -1105,6 +1117,7 @@ pointer_handle_button (void *data,
|
|
|
|
|
event->button.window = g_object_ref (device->pointer_focus);
|
|
|
|
|
gdk_event_set_device (event, device->master_pointer);
|
|
|
|
|
gdk_event_set_source_device (event, device->pointer);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
|
|
|
|
event->button.time = time;
|
|
|
|
|
event->button.axes = NULL;
|
|
|
|
|
event->button.state = device->button_modifiers | device->key_modifiers;
|
|
|
|
@ -1168,6 +1181,7 @@ pointer_handle_axis (void *data,
|
|
|
|
|
event->scroll.window = g_object_ref (device->pointer_focus);
|
|
|
|
|
gdk_event_set_device (event, device->master_pointer);
|
|
|
|
|
gdk_event_set_source_device (event, device->pointer);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
|
|
|
|
event->scroll.time = time;
|
|
|
|
|
event->scroll.direction = GDK_SCROLL_SMOOTH;
|
|
|
|
|
event->scroll.delta_x = delta_x;
|
|
|
|
@ -1232,6 +1246,7 @@ keyboard_handle_enter (void *data,
|
|
|
|
|
event->focus_change.in = TRUE;
|
|
|
|
|
gdk_event_set_device (event, device->master_keyboard);
|
|
|
|
|
gdk_event_set_source_device (event, device->keyboard);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
|
|
|
|
|
|
|
|
|
GDK_NOTE (EVENTS,
|
|
|
|
|
g_message ("focus in, device %p surface %p",
|
|
|
|
@ -1277,6 +1292,7 @@ keyboard_handle_leave (void *data,
|
|
|
|
|
event->focus_change.in = FALSE;
|
|
|
|
|
gdk_event_set_device (event, device->master_keyboard);
|
|
|
|
|
gdk_event_set_source_device (event, device->keyboard);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_keyboard));
|
|
|
|
|
|
|
|
|
|
g_object_unref (device->keyboard_focus);
|
|
|
|
|
device->keyboard_focus = NULL;
|
|
|
|
@ -1454,6 +1470,7 @@ deliver_key_event (GdkWaylandDeviceData *device,
|
|
|
|
|
event->key.window = device->keyboard_focus ? g_object_ref (device->keyboard_focus) : NULL;
|
|
|
|
|
gdk_event_set_device (event, device->master_keyboard);
|
|
|
|
|
gdk_event_set_source_device (event, device->keyboard);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_keyboard));
|
|
|
|
|
event->key.time = time_;
|
|
|
|
|
event->key.state = device->button_modifiers | device->key_modifiers;
|
|
|
|
|
event->key.group = 0;
|
|
|
|
@ -1617,6 +1634,7 @@ _create_touch_event (GdkWaylandDeviceData *device,
|
|
|
|
|
event->touch.window = g_object_ref (touch->window);
|
|
|
|
|
gdk_event_set_device (event, device->touch_master);
|
|
|
|
|
gdk_event_set_source_device (event, device->touch);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->touch_master));
|
|
|
|
|
event->touch.time = time;
|
|
|
|
|
event->touch.state = device->button_modifiers | device->key_modifiers;
|
|
|
|
|
gdk_event_set_screen (event, display->screen);
|
|
|
|
@ -1785,6 +1803,7 @@ emit_gesture_swipe_event (GdkWaylandDeviceData *device,
|
|
|
|
|
event->touchpad_swipe.window = g_object_ref (device->pointer_focus);
|
|
|
|
|
gdk_event_set_device (event, device->master_pointer);
|
|
|
|
|
gdk_event_set_source_device (event, device->pointer);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
|
|
|
|
event->touchpad_swipe.time = _time;
|
|
|
|
|
event->touchpad_swipe.state = device->button_modifiers | device->key_modifiers;
|
|
|
|
|
gdk_event_set_screen (event, display->screen);
|
|
|
|
@ -1887,6 +1906,7 @@ emit_gesture_pinch_event (GdkWaylandDeviceData *device,
|
|
|
|
|
event->touchpad_pinch.window = g_object_ref (device->pointer_focus);
|
|
|
|
|
gdk_event_set_device (event, device->master_pointer);
|
|
|
|
|
gdk_event_set_source_device (event, device->pointer);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
|
|
|
|
event->touchpad_pinch.time = _time;
|
|
|
|
|
event->touchpad_pinch.state = device->button_modifiers | device->key_modifiers;
|
|
|
|
|
gdk_event_set_screen (event, display->screen);
|
|
|
|
@ -2037,6 +2057,7 @@ seat_handle_capabilities (void *data,
|
|
|
|
|
"has-cursor", TRUE,
|
|
|
|
|
"display", device->display,
|
|
|
|
|
"device-manager", device->device_manager,
|
|
|
|
|
"seat", device,
|
|
|
|
|
NULL);
|
|
|
|
|
_gdk_device_set_associated_device (device->pointer, device->master_pointer);
|
|
|
|
|
GDK_WAYLAND_DEVICE (device->pointer)->device = device;
|
|
|
|
@ -2093,6 +2114,7 @@ seat_handle_capabilities (void *data,
|
|
|
|
|
"has-cursor", FALSE,
|
|
|
|
|
"display", device->display,
|
|
|
|
|
"device-manager", device->device_manager,
|
|
|
|
|
"seat", device,
|
|
|
|
|
NULL);
|
|
|
|
|
_gdk_device_set_associated_device (device->keyboard, device->master_keyboard);
|
|
|
|
|
GDK_WAYLAND_DEVICE (device->keyboard)->device = device;
|
|
|
|
@ -2130,6 +2152,7 @@ seat_handle_capabilities (void *data,
|
|
|
|
|
"has-cursor", TRUE,
|
|
|
|
|
"display", device->display,
|
|
|
|
|
"device-manager", device->device_manager,
|
|
|
|
|
"seat", device,
|
|
|
|
|
NULL);
|
|
|
|
|
GDK_WAYLAND_DEVICE (device->touch_master)->device = device;
|
|
|
|
|
_gdk_device_set_associated_device (device->touch_master, device->master_keyboard);
|
|
|
|
@ -2146,6 +2169,7 @@ seat_handle_capabilities (void *data,
|
|
|
|
|
"has-cursor", FALSE,
|
|
|
|
|
"display", device->display,
|
|
|
|
|
"device-manager", device->device_manager,
|
|
|
|
|
"seat", device,
|
|
|
|
|
NULL);
|
|
|
|
|
_gdk_device_set_associated_device (device->touch, device->touch_master);
|
|
|
|
|
GDK_WAYLAND_DEVICE (device->touch)->device = device;
|
|
|
|
@ -2210,6 +2234,7 @@ init_devices (GdkWaylandDeviceData *device)
|
|
|
|
|
"has-cursor", TRUE,
|
|
|
|
|
"display", device->display,
|
|
|
|
|
"device-manager", device_manager,
|
|
|
|
|
"seat", device,
|
|
|
|
|
NULL);
|
|
|
|
|
GDK_WAYLAND_DEVICE (device->master_pointer)->device = device;
|
|
|
|
|
|
|
|
|
@ -2226,6 +2251,7 @@ init_devices (GdkWaylandDeviceData *device)
|
|
|
|
|
"has-cursor", FALSE,
|
|
|
|
|
"display", device->display,
|
|
|
|
|
"device-manager", device_manager,
|
|
|
|
|
"seat", device,
|
|
|
|
|
NULL);
|
|
|
|
|
GDK_WAYLAND_DEVICE (device->master_keyboard)->device = device;
|
|
|
|
|
|
|
|
|
@ -2328,6 +2354,259 @@ create_foreign_dnd_window (GdkDisplay *display)
|
|
|
|
|
return gdk_window_new (gdk_screen_get_root_window (screen), &attrs, mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_seat_finalize (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (object);
|
|
|
|
|
|
|
|
|
|
seat_handle_capabilities (seat, seat->wl_seat, 0);
|
|
|
|
|
g_object_unref (seat->keymap);
|
|
|
|
|
wl_surface_destroy (seat->pointer_surface);
|
|
|
|
|
/* FIXME: destroy data_device */
|
|
|
|
|
g_clear_object (&seat->keyboard_settings);
|
|
|
|
|
g_clear_object (&seat->drop_context);
|
|
|
|
|
g_hash_table_destroy (seat->touches);
|
|
|
|
|
gdk_window_destroy (seat->foreign_dnd_window);
|
|
|
|
|
stop_key_repeat (seat);
|
|
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (gdk_wayland_seat_parent_class)->finalize (object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GdkSeatCapabilities
|
|
|
|
|
gdk_wayland_seat_get_capabilities (GdkSeat *seat)
|
|
|
|
|
{
|
|
|
|
|
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
|
|
|
|
GdkSeatCapabilities caps = 0;
|
|
|
|
|
|
|
|
|
|
if (wayland_seat->master_pointer)
|
|
|
|
|
caps |= GDK_SEAT_CAPABILITY_POINTER;
|
|
|
|
|
if (wayland_seat->master_keyboard)
|
|
|
|
|
caps |= GDK_SEAT_CAPABILITY_KEYBOARD;
|
|
|
|
|
if (wayland_seat->touch_master)
|
|
|
|
|
caps |= GDK_SEAT_CAPABILITY_TOUCH;
|
|
|
|
|
|
|
|
|
|
return caps;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GdkGrabStatus
|
|
|
|
|
gdk_wayland_seat_grab (GdkSeat *seat,
|
|
|
|
|
GdkWindow *window,
|
|
|
|
|
GdkSeatCapabilities capabilities,
|
|
|
|
|
gboolean owner_events,
|
|
|
|
|
GdkCursor *cursor,
|
|
|
|
|
const GdkEvent *event,
|
|
|
|
|
GdkSeatGrabPrepareFunc prepare_func,
|
|
|
|
|
gpointer prepare_func_data)
|
|
|
|
|
{
|
|
|
|
|
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
|
|
|
|
guint32 evtime = event ? gdk_event_get_time (event) : GDK_CURRENT_TIME;
|
|
|
|
|
GdkDisplay *display = gdk_seat_get_display (seat);
|
|
|
|
|
GdkWindow *native;
|
|
|
|
|
|
|
|
|
|
native = gdk_window_get_toplevel (window);
|
|
|
|
|
|
|
|
|
|
while (native->window_type == GDK_WINDOW_OFFSCREEN)
|
|
|
|
|
{
|
|
|
|
|
native = gdk_offscreen_window_get_embedder (native);
|
|
|
|
|
|
|
|
|
|
if (native == NULL ||
|
|
|
|
|
(!_gdk_window_has_impl (native) &&
|
|
|
|
|
!gdk_window_is_viewable (native)))
|
|
|
|
|
return GDK_GRAB_NOT_VIEWABLE;
|
|
|
|
|
|
|
|
|
|
native = gdk_window_get_toplevel (native);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (native == NULL || GDK_WINDOW_DESTROYED (native))
|
|
|
|
|
return GDK_GRAB_NOT_VIEWABLE;
|
|
|
|
|
|
|
|
|
|
wayland_seat->pointer_grab_window = window;
|
|
|
|
|
wayland_seat->pointer_grab_time = evtime;
|
|
|
|
|
_gdk_wayland_window_set_grab_seat (window, seat);
|
|
|
|
|
|
|
|
|
|
if (prepare_func)
|
|
|
|
|
(prepare_func) (seat, window, prepare_func_data);
|
|
|
|
|
|
|
|
|
|
if (!gdk_window_is_visible (window))
|
|
|
|
|
{
|
|
|
|
|
_gdk_wayland_window_set_grab_seat (window, NULL);
|
|
|
|
|
g_critical ("Window %p has not been made visible in GdkSeatGrabPrepareFunc",
|
|
|
|
|
window);
|
|
|
|
|
return GDK_GRAB_NOT_VIEWABLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (capabilities & GDK_SEAT_CAPABILITY_POINTER)
|
|
|
|
|
{
|
|
|
|
|
GdkWindow *prev_focus = gdk_wayland_device_get_focus (wayland_seat->master_pointer);
|
|
|
|
|
|
|
|
|
|
if (prev_focus != window)
|
|
|
|
|
device_emit_grab_crossing (wayland_seat->master_pointer, prev_focus,
|
|
|
|
|
window, GDK_CROSSING_GRAB, evtime);
|
|
|
|
|
|
|
|
|
|
_gdk_display_add_device_grab (display,
|
|
|
|
|
wayland_seat->master_pointer,
|
|
|
|
|
window,
|
|
|
|
|
native,
|
|
|
|
|
GDK_OWNERSHIP_NONE,
|
|
|
|
|
owner_events,
|
|
|
|
|
GDK_ALL_EVENTS_MASK,
|
|
|
|
|
_gdk_display_get_next_serial (display),
|
|
|
|
|
evtime,
|
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
|
|
g_set_object (&wayland_seat->cursor, cursor);
|
|
|
|
|
gdk_wayland_device_update_window_cursor (wayland_seat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (capabilities & GDK_SEAT_CAPABILITY_TOUCH)
|
|
|
|
|
{
|
|
|
|
|
GdkWindow *prev_focus = gdk_wayland_device_get_focus (wayland_seat->touch_master);
|
|
|
|
|
|
|
|
|
|
if (prev_focus != window)
|
|
|
|
|
device_emit_grab_crossing (wayland_seat->touch_master, prev_focus,
|
|
|
|
|
window, GDK_CROSSING_GRAB, evtime);
|
|
|
|
|
|
|
|
|
|
_gdk_display_add_device_grab (display,
|
|
|
|
|
wayland_seat->touch_master,
|
|
|
|
|
window,
|
|
|
|
|
native,
|
|
|
|
|
GDK_OWNERSHIP_NONE,
|
|
|
|
|
owner_events,
|
|
|
|
|
GDK_ALL_EVENTS_MASK,
|
|
|
|
|
_gdk_display_get_next_serial (display),
|
|
|
|
|
evtime,
|
|
|
|
|
FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
|
|
|
|
|
{
|
|
|
|
|
GdkWindow *prev_focus = gdk_wayland_device_get_focus (wayland_seat->master_keyboard);
|
|
|
|
|
|
|
|
|
|
if (prev_focus != window)
|
|
|
|
|
device_emit_grab_crossing (wayland_seat->master_keyboard, prev_focus,
|
|
|
|
|
window, GDK_CROSSING_GRAB, evtime);
|
|
|
|
|
|
|
|
|
|
_gdk_display_add_device_grab (display,
|
|
|
|
|
wayland_seat->master_keyboard,
|
|
|
|
|
window,
|
|
|
|
|
native,
|
|
|
|
|
GDK_OWNERSHIP_NONE,
|
|
|
|
|
owner_events,
|
|
|
|
|
GDK_ALL_EVENTS_MASK,
|
|
|
|
|
_gdk_display_get_next_serial (display),
|
|
|
|
|
evtime,
|
|
|
|
|
FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return GDK_GRAB_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_seat_ungrab (GdkSeat *seat)
|
|
|
|
|
{
|
|
|
|
|
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
|
|
|
|
GdkDisplay *display = gdk_seat_get_display (seat);;
|
|
|
|
|
GdkDeviceGrabInfo *grab;
|
|
|
|
|
|
|
|
|
|
if (wayland_seat->master_pointer)
|
|
|
|
|
{
|
|
|
|
|
GdkWindow *focus, *prev_focus = NULL;
|
|
|
|
|
|
|
|
|
|
grab = _gdk_display_get_last_device_grab (display, wayland_seat->master_pointer);
|
|
|
|
|
|
|
|
|
|
if (grab)
|
|
|
|
|
{
|
|
|
|
|
grab->serial_end = grab->serial_start;
|
|
|
|
|
prev_focus = grab->window;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
focus = gdk_wayland_device_get_focus (wayland_seat->master_pointer);
|
|
|
|
|
|
|
|
|
|
if (focus != prev_focus)
|
|
|
|
|
device_emit_grab_crossing (wayland_seat->master_pointer, prev_focus,
|
|
|
|
|
focus, GDK_CROSSING_UNGRAB,
|
|
|
|
|
GDK_CURRENT_TIME);
|
|
|
|
|
|
|
|
|
|
gdk_wayland_device_update_window_cursor (wayland_seat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wayland_seat->master_keyboard)
|
|
|
|
|
{
|
|
|
|
|
grab = _gdk_display_get_last_device_grab (display, wayland_seat->master_keyboard);
|
|
|
|
|
|
|
|
|
|
if (grab)
|
|
|
|
|
grab->serial_end = grab->serial_start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wayland_seat->touch_master)
|
|
|
|
|
{
|
|
|
|
|
grab = _gdk_display_get_last_device_grab (display, wayland_seat->touch_master);
|
|
|
|
|
|
|
|
|
|
if (grab)
|
|
|
|
|
grab->serial_end = grab->serial_start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wayland_seat->pointer_grab_window)
|
|
|
|
|
{
|
|
|
|
|
_gdk_wayland_window_set_grab_seat (wayland_seat->pointer_grab_window,
|
|
|
|
|
NULL);
|
|
|
|
|
wayland_seat->pointer_grab_window = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GdkDevice *
|
|
|
|
|
gdk_wayland_seat_get_master (GdkSeat *seat,
|
|
|
|
|
GdkSeatCapabilities capabilities)
|
|
|
|
|
{
|
|
|
|
|
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
|
|
|
|
|
|
|
|
|
if (capabilities == GDK_SEAT_CAPABILITY_POINTER)
|
|
|
|
|
return wayland_seat->master_pointer;
|
|
|
|
|
else if (capabilities == GDK_SEAT_CAPABILITY_KEYBOARD)
|
|
|
|
|
return wayland_seat->master_keyboard;
|
|
|
|
|
else if (capabilities == GDK_SEAT_CAPABILITY_TOUCH)
|
|
|
|
|
return wayland_seat->touch_master;
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GList *
|
|
|
|
|
gdk_wayland_seat_get_slaves (GdkSeat *seat,
|
|
|
|
|
GdkSeatCapabilities capabilities)
|
|
|
|
|
{
|
|
|
|
|
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
|
|
|
|
GList *slaves = NULL;
|
|
|
|
|
|
|
|
|
|
if (capabilities & GDK_SEAT_CAPABILITY_POINTER)
|
|
|
|
|
slaves = g_list_prepend (slaves, wayland_seat->pointer);
|
|
|
|
|
if (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
|
|
|
|
|
slaves = g_list_prepend (slaves, wayland_seat->keyboard);
|
|
|
|
|
if (capabilities & GDK_SEAT_CAPABILITY_TOUCH)
|
|
|
|
|
slaves = g_list_prepend (slaves, wayland_seat->touch);
|
|
|
|
|
|
|
|
|
|
return slaves;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_seat_class_init (GdkWaylandSeatClass *klass)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
|
|
|
|
|
|
|
|
|
|
object_class->finalize = gdk_wayland_seat_finalize;
|
|
|
|
|
|
|
|
|
|
seat_class->get_capabilities = gdk_wayland_seat_get_capabilities;
|
|
|
|
|
seat_class->grab = gdk_wayland_seat_grab;
|
|
|
|
|
seat_class->ungrab = gdk_wayland_seat_ungrab;
|
|
|
|
|
seat_class->get_master = gdk_wayland_seat_get_master;
|
|
|
|
|
seat_class->get_slaves = gdk_wayland_seat_get_slaves;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_seat_init (GdkWaylandSeat *seat)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
_gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager,
|
|
|
|
|
guint32 id,
|
|
|
|
@ -2335,70 +2614,65 @@ _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager,
|
|
|
|
|
{
|
|
|
|
|
GdkDisplay *display;
|
|
|
|
|
GdkWaylandDisplay *display_wayland;
|
|
|
|
|
GdkWaylandDeviceData *device;
|
|
|
|
|
GdkWaylandSeat *seat;
|
|
|
|
|
|
|
|
|
|
display = gdk_device_manager_get_display (device_manager);
|
|
|
|
|
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
|
|
|
|
|
|
|
|
|
device = g_new0 (GdkWaylandDeviceData, 1);
|
|
|
|
|
device->id = id;
|
|
|
|
|
device->keymap = _gdk_wayland_keymap_new ();
|
|
|
|
|
device->display = display;
|
|
|
|
|
device->device_manager = device_manager;
|
|
|
|
|
device->touches = g_hash_table_new_full (NULL, NULL, NULL,
|
|
|
|
|
(GDestroyNotify) g_free);
|
|
|
|
|
device->foreign_dnd_window = create_foreign_dnd_window (display);
|
|
|
|
|
device->wl_seat = wl_seat;
|
|
|
|
|
seat = g_object_new (GDK_TYPE_WAYLAND_SEAT,
|
|
|
|
|
"display", display,
|
|
|
|
|
NULL);
|
|
|
|
|
seat->id = id;
|
|
|
|
|
seat->keymap = _gdk_wayland_keymap_new ();
|
|
|
|
|
seat->display = display;
|
|
|
|
|
seat->device_manager = device_manager;
|
|
|
|
|
seat->touches = g_hash_table_new_full (NULL, NULL, NULL,
|
|
|
|
|
(GDestroyNotify) g_free);
|
|
|
|
|
seat->foreign_dnd_window = create_foreign_dnd_window (display);
|
|
|
|
|
seat->wl_seat = wl_seat;
|
|
|
|
|
|
|
|
|
|
device->pending_selection = GDK_NONE;
|
|
|
|
|
seat->pending_selection = GDK_NONE;
|
|
|
|
|
|
|
|
|
|
wl_seat_add_listener (device->wl_seat, &seat_listener, device);
|
|
|
|
|
wl_seat_set_user_data (device->wl_seat, device);
|
|
|
|
|
wl_seat_add_listener (seat->wl_seat, &seat_listener, seat);
|
|
|
|
|
wl_seat_set_user_data (seat->wl_seat, seat);
|
|
|
|
|
|
|
|
|
|
device->data_device =
|
|
|
|
|
seat->data_device =
|
|
|
|
|
wl_data_device_manager_get_data_device (display_wayland->data_device_manager,
|
|
|
|
|
device->wl_seat);
|
|
|
|
|
device->drop_context = _gdk_wayland_drop_context_new (device->data_device);
|
|
|
|
|
wl_data_device_add_listener (device->data_device,
|
|
|
|
|
&data_device_listener, device);
|
|
|
|
|
seat->wl_seat);
|
|
|
|
|
seat->drop_context = _gdk_wayland_drop_context_new (seat->data_device);
|
|
|
|
|
wl_data_device_add_listener (seat->data_device,
|
|
|
|
|
&data_device_listener, seat);
|
|
|
|
|
|
|
|
|
|
device->current_output_scale = 1;
|
|
|
|
|
device->pointer_surface =
|
|
|
|
|
seat->current_output_scale = 1;
|
|
|
|
|
seat->pointer_surface =
|
|
|
|
|
wl_compositor_create_surface (display_wayland->compositor);
|
|
|
|
|
wl_surface_add_listener (device->pointer_surface,
|
|
|
|
|
wl_surface_add_listener (seat->pointer_surface,
|
|
|
|
|
&pointer_surface_listener,
|
|
|
|
|
device);
|
|
|
|
|
seat);
|
|
|
|
|
|
|
|
|
|
init_devices (device);
|
|
|
|
|
init_devices (seat);
|
|
|
|
|
|
|
|
|
|
gdk_display_add_seat (display, GDK_SEAT (seat));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
_gdk_wayland_device_manager_remove_seat (GdkDeviceManager *manager,
|
|
|
|
|
guint32 id)
|
|
|
|
|
{
|
|
|
|
|
GdkWaylandDeviceManager *device_manager = GDK_WAYLAND_DEVICE_MANAGER (manager);
|
|
|
|
|
GdkDisplay *display = gdk_device_manager_get_display (manager);
|
|
|
|
|
GList *l;
|
|
|
|
|
|
|
|
|
|
for (l = device_manager->devices; l != NULL; l = l->next)
|
|
|
|
|
l = gdk_display_list_seats (display);
|
|
|
|
|
|
|
|
|
|
while (l)
|
|
|
|
|
{
|
|
|
|
|
GdkWaylandDevice *wayland_device = l->data;
|
|
|
|
|
GdkWaylandDeviceData *device = wayland_device->device;
|
|
|
|
|
GdkWaylandSeat *seat = l->data;
|
|
|
|
|
|
|
|
|
|
if (device->id == id)
|
|
|
|
|
{
|
|
|
|
|
seat_handle_capabilities (device, device->wl_seat, 0);
|
|
|
|
|
g_object_unref (device->keymap);
|
|
|
|
|
wl_surface_destroy (device->pointer_surface);
|
|
|
|
|
/* FIXME: destroy data_device */
|
|
|
|
|
g_clear_object (&device->keyboard_settings);
|
|
|
|
|
g_clear_object (&device->drop_context);
|
|
|
|
|
g_hash_table_destroy (device->touches);
|
|
|
|
|
gdk_window_destroy (device->foreign_dnd_window);
|
|
|
|
|
stop_key_repeat (device);
|
|
|
|
|
g_free (device);
|
|
|
|
|
if (seat->id != id)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
gdk_display_remove_seat (display, GDK_SEAT (seat));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2615,6 +2889,15 @@ gdk_wayland_device_unset_grab (GdkDevice *gdk_device)
|
|
|
|
|
device->button_modifiers = 0;
|
|
|
|
|
gdk_event_set_device (event, gdk_device);
|
|
|
|
|
gdk_event_set_source_device (event, gdk_device);
|
|
|
|
|
gdk_event_set_seat (event, gdk_device_get_seat (gdk_device));
|
|
|
|
|
|
|
|
|
|
_gdk_wayland_display_deliver_event (gdk_device_get_display (gdk_device), event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct wl_seat *
|
|
|
|
|
gdk_wayland_seat_get_wl_seat (GdkSeat *seat)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (GDK_IS_WAYLAND_SEAT (seat), NULL);
|
|
|
|
|
|
|
|
|
|
return GDK_WAYLAND_SEAT (seat)->wl_seat;
|
|
|
|
|
}
|
|
|
|
|