2013-05-03 17:51:22 +00:00
|
|
|
/*
|
|
|
|
* Wayland Support
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 Intel Corporation
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2023-08-07 09:50:23 +00:00
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
2013-05-03 17:51:22 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "wayland/meta-wayland-seat.h"
|
2014-04-22 21:58:01 +00:00
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "wayland/meta-wayland-data-device.h"
|
|
|
|
#include "wayland/meta-wayland-private.h"
|
|
|
|
#include "wayland/meta-wayland-tablet-seat.h"
|
|
|
|
#include "wayland/meta-wayland-versions.h"
|
2013-05-03 17:51:22 +00:00
|
|
|
|
2014-07-23 13:33:03 +00:00
|
|
|
#define CAPABILITY_ENABLED(prev, cur, capability) ((cur & (capability)) && !(prev & (capability)))
|
|
|
|
#define CAPABILITY_DISABLED(prev, cur, capability) ((prev & (capability)) && !(cur & (capability)))
|
|
|
|
|
2013-05-03 17:51:22 +00:00
|
|
|
static void
|
|
|
|
unbind_resource (struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_list_remove (wl_resource_get_link (resource));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
seat_get_pointer (struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
uint32_t id)
|
|
|
|
{
|
|
|
|
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
2016-04-01 08:39:30 +00:00
|
|
|
MetaWaylandPointer *pointer = seat->pointer;
|
2013-05-03 17:51:22 +00:00
|
|
|
|
wayland: Avoid a race in wl_seat capabilities
The way wl_seat capabilities work, by notifying clients of capabilities
changes, and clients consequently requesting the relevant interface
objects (pointer, keyboard, touch) is inherently racy.
On quick VT changes for example, capabilities on the seat will be added
and removed, and by the time the client receives the capability change
notification and requests the relevant keyboard, pointer or touch,
another VT switch might have occurred and the wl_pointer, wl_keyboard or
wl_touch already destroyed, leading to a protocol error which kills the
client.
To avoid this, create the objects when requested regardless of the
capabilities.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1797
Related: https://bugzilla.gnome.org/show_bug.cgi?id=790932
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/77>
2017-11-28 09:54:08 +00:00
|
|
|
meta_wayland_pointer_create_new_resource (pointer, client, resource, id);
|
2013-05-03 17:51:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
seat_get_keyboard (struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
uint32_t id)
|
|
|
|
{
|
|
|
|
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
2016-04-01 08:39:30 +00:00
|
|
|
MetaWaylandKeyboard *keyboard = seat->keyboard;
|
2013-05-03 17:51:22 +00:00
|
|
|
|
wayland: Avoid a race in wl_seat capabilities
The way wl_seat capabilities work, by notifying clients of capabilities
changes, and clients consequently requesting the relevant interface
objects (pointer, keyboard, touch) is inherently racy.
On quick VT changes for example, capabilities on the seat will be added
and removed, and by the time the client receives the capability change
notification and requests the relevant keyboard, pointer or touch,
another VT switch might have occurred and the wl_pointer, wl_keyboard or
wl_touch already destroyed, leading to a protocol error which kills the
client.
To avoid this, create the objects when requested regardless of the
capabilities.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1797
Related: https://bugzilla.gnome.org/show_bug.cgi?id=790932
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/77>
2017-11-28 09:54:08 +00:00
|
|
|
meta_wayland_keyboard_create_new_resource (keyboard, client, resource, id);
|
2013-05-03 17:51:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
seat_get_touch (struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
uint32_t id)
|
|
|
|
{
|
2014-04-24 12:50:47 +00:00
|
|
|
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
2016-04-01 08:39:30 +00:00
|
|
|
MetaWaylandTouch *touch = seat->touch;
|
2014-04-24 12:50:47 +00:00
|
|
|
|
wayland: Avoid a race in wl_seat capabilities
The way wl_seat capabilities work, by notifying clients of capabilities
changes, and clients consequently requesting the relevant interface
objects (pointer, keyboard, touch) is inherently racy.
On quick VT changes for example, capabilities on the seat will be added
and removed, and by the time the client receives the capability change
notification and requests the relevant keyboard, pointer or touch,
another VT switch might have occurred and the wl_pointer, wl_keyboard or
wl_touch already destroyed, leading to a protocol error which kills the
client.
To avoid this, create the objects when requested regardless of the
capabilities.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1797
Related: https://bugzilla.gnome.org/show_bug.cgi?id=790932
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/77>
2017-11-28 09:54:08 +00:00
|
|
|
meta_wayland_touch_create_new_resource (touch, client, resource, id);
|
2013-05-03 17:51:22 +00:00
|
|
|
}
|
|
|
|
|
2020-08-16 23:51:20 +00:00
|
|
|
static void
|
|
|
|
seat_release (struct wl_client *client,
|
|
|
|
struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy (resource);
|
|
|
|
}
|
|
|
|
|
2014-04-17 20:36:45 +00:00
|
|
|
static const struct wl_seat_interface seat_interface = {
|
|
|
|
seat_get_pointer,
|
|
|
|
seat_get_keyboard,
|
2020-08-16 23:51:20 +00:00
|
|
|
seat_get_touch,
|
|
|
|
seat_release
|
2014-04-17 20:36:45 +00:00
|
|
|
};
|
2013-05-03 17:51:22 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
bind_seat (struct wl_client *client,
|
|
|
|
void *data,
|
|
|
|
guint32 version,
|
|
|
|
guint32 id)
|
|
|
|
{
|
|
|
|
MetaWaylandSeat *seat = data;
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
2014-08-04 14:24:59 +00:00
|
|
|
resource = wl_resource_create (client, &wl_seat_interface, version, id);
|
2013-09-10 11:03:37 +00:00
|
|
|
wl_resource_set_implementation (resource, &seat_interface, seat, unbind_resource);
|
2013-05-03 17:51:22 +00:00
|
|
|
wl_list_insert (&seat->base_resource_list, wl_resource_get_link (resource));
|
|
|
|
|
2014-07-23 13:33:03 +00:00
|
|
|
wl_seat_send_capabilities (resource, seat->capabilities);
|
2013-09-10 11:03:37 +00:00
|
|
|
|
2014-05-12 21:00:49 +00:00
|
|
|
if (version >= WL_SEAT_NAME_SINCE_VERSION)
|
2013-09-10 11:03:37 +00:00
|
|
|
wl_seat_send_name (resource, "seat0");
|
2013-05-03 17:51:22 +00:00
|
|
|
}
|
|
|
|
|
2014-07-23 13:33:03 +00:00
|
|
|
static uint32_t
|
2019-10-04 12:01:19 +00:00
|
|
|
lookup_device_capabilities (ClutterSeat *seat)
|
2014-07-23 13:33:03 +00:00
|
|
|
{
|
2019-10-04 12:01:19 +00:00
|
|
|
GList *devices, *l;
|
2014-07-23 13:33:03 +00:00
|
|
|
uint32_t capabilities = 0;
|
|
|
|
|
2019-10-04 12:01:19 +00:00
|
|
|
devices = clutter_seat_list_devices (seat);
|
2014-07-23 13:33:03 +00:00
|
|
|
|
|
|
|
for (l = devices; l; l = l->next)
|
|
|
|
{
|
2022-03-08 16:26:43 +00:00
|
|
|
ClutterInputCapabilities device_capabilities;
|
2014-07-23 13:33:03 +00:00
|
|
|
|
2020-08-31 16:47:23 +00:00
|
|
|
/* Only look for physical devices, logical devices have rather generic
|
2014-07-23 13:33:03 +00:00
|
|
|
* keyboard/pointer device types, which is not truly representative of
|
2020-08-31 16:47:23 +00:00
|
|
|
* the physical devices connected to them.
|
2014-07-23 13:33:03 +00:00
|
|
|
*/
|
2020-08-31 16:47:23 +00:00
|
|
|
if (clutter_input_device_get_device_mode (l->data) == CLUTTER_INPUT_MODE_LOGICAL)
|
2014-07-23 13:33:03 +00:00
|
|
|
continue;
|
|
|
|
|
2022-03-08 16:26:43 +00:00
|
|
|
device_capabilities = clutter_input_device_get_capabilities (l->data);
|
|
|
|
|
|
|
|
if (device_capabilities & CLUTTER_INPUT_CAPABILITY_POINTER)
|
|
|
|
capabilities |= WL_SEAT_CAPABILITY_POINTER;
|
|
|
|
if (device_capabilities & CLUTTER_INPUT_CAPABILITY_KEYBOARD)
|
|
|
|
capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
|
|
|
|
if (device_capabilities & CLUTTER_INPUT_CAPABILITY_TOUCH)
|
|
|
|
capabilities |= WL_SEAT_CAPABILITY_TOUCH;
|
2014-07-23 13:33:03 +00:00
|
|
|
}
|
|
|
|
|
2019-10-04 12:01:19 +00:00
|
|
|
g_list_free (devices);
|
|
|
|
|
2014-07-23 13:33:03 +00:00
|
|
|
return capabilities;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_wayland_seat_set_capabilities (MetaWaylandSeat *seat,
|
|
|
|
uint32_t flags)
|
|
|
|
{
|
|
|
|
struct wl_resource *resource;
|
|
|
|
uint32_t prev_flags;
|
|
|
|
|
|
|
|
prev_flags = seat->capabilities;
|
|
|
|
|
|
|
|
if (prev_flags == flags)
|
|
|
|
return;
|
|
|
|
|
|
|
|
seat->capabilities = flags;
|
|
|
|
|
|
|
|
if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_POINTER))
|
2016-09-12 15:20:36 +00:00
|
|
|
meta_wayland_pointer_enable (seat->pointer);
|
2014-07-23 13:33:03 +00:00
|
|
|
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_POINTER))
|
2016-04-01 08:39:30 +00:00
|
|
|
meta_wayland_pointer_disable (seat->pointer);
|
2014-07-23 13:33:03 +00:00
|
|
|
|
|
|
|
if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_KEYBOARD))
|
|
|
|
{
|
2022-05-30 21:48:44 +00:00
|
|
|
MetaWaylandCompositor *compositor =
|
|
|
|
meta_wayland_seat_get_compositor (seat);
|
|
|
|
MetaContext *context = meta_wayland_compositor_get_context (compositor);
|
2014-07-23 13:33:03 +00:00
|
|
|
MetaDisplay *display;
|
|
|
|
|
2016-09-12 15:20:36 +00:00
|
|
|
meta_wayland_keyboard_enable (seat->keyboard);
|
2014-07-23 13:33:03 +00:00
|
|
|
|
|
|
|
/* Post-initialization, ensure the input focus is in sync */
|
2022-05-30 21:48:44 +00:00
|
|
|
display = meta_context_get_display (context);
|
2014-07-23 13:33:03 +00:00
|
|
|
if (display)
|
|
|
|
meta_display_sync_wayland_input_focus (display);
|
|
|
|
}
|
|
|
|
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_KEYBOARD))
|
2016-04-01 08:39:30 +00:00
|
|
|
meta_wayland_keyboard_disable (seat->keyboard);
|
2014-07-23 13:33:03 +00:00
|
|
|
|
|
|
|
if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_TOUCH))
|
2016-09-12 15:20:36 +00:00
|
|
|
meta_wayland_touch_enable (seat->touch);
|
2014-07-23 13:33:03 +00:00
|
|
|
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_TOUCH))
|
2016-04-01 08:39:30 +00:00
|
|
|
meta_wayland_touch_disable (seat->touch);
|
2014-07-23 13:33:03 +00:00
|
|
|
|
|
|
|
/* Broadcast capability changes */
|
|
|
|
wl_resource_for_each (resource, &seat->base_resource_list)
|
|
|
|
{
|
|
|
|
wl_seat_send_capabilities (resource, flags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-10-04 12:01:19 +00:00
|
|
|
meta_wayland_seat_update_capabilities (MetaWaylandSeat *seat,
|
|
|
|
ClutterSeat *clutter_seat)
|
2014-07-23 13:33:03 +00:00
|
|
|
{
|
|
|
|
uint32_t capabilities;
|
|
|
|
|
2019-10-04 12:01:19 +00:00
|
|
|
capabilities = lookup_device_capabilities (clutter_seat);
|
2014-07-23 13:33:03 +00:00
|
|
|
meta_wayland_seat_set_capabilities (seat, capabilities);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-10-04 12:01:19 +00:00
|
|
|
meta_wayland_seat_devices_updated (ClutterSeat *clutter_seat,
|
|
|
|
ClutterInputDevice *input_device,
|
|
|
|
MetaWaylandSeat *seat)
|
2014-07-23 13:33:03 +00:00
|
|
|
{
|
2019-10-04 12:01:19 +00:00
|
|
|
meta_wayland_seat_update_capabilities (seat, clutter_seat);
|
2014-07-23 13:33:03 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 22:05:44 +00:00
|
|
|
static MetaWaylandSeat *
|
2016-01-26 12:31:48 +00:00
|
|
|
meta_wayland_seat_new (MetaWaylandCompositor *compositor,
|
|
|
|
struct wl_display *display)
|
2013-05-03 17:51:22 +00:00
|
|
|
{
|
2022-05-30 21:48:44 +00:00
|
|
|
MetaWaylandSeat *seat;
|
2019-10-04 12:01:19 +00:00
|
|
|
ClutterSeat *clutter_seat;
|
2013-05-03 17:51:22 +00:00
|
|
|
|
2022-05-30 21:48:44 +00:00
|
|
|
seat = g_new0 (MetaWaylandSeat, 1);
|
|
|
|
seat->compositor = compositor;
|
|
|
|
|
2013-05-03 17:51:22 +00:00
|
|
|
wl_list_init (&seat->base_resource_list);
|
2014-07-23 13:33:03 +00:00
|
|
|
seat->wl_display = display;
|
2013-05-03 17:51:22 +00:00
|
|
|
|
2016-09-12 15:20:36 +00:00
|
|
|
seat->pointer = g_object_new (META_TYPE_WAYLAND_POINTER,
|
|
|
|
"seat", seat,
|
|
|
|
NULL);
|
|
|
|
seat->keyboard = g_object_new (META_TYPE_WAYLAND_KEYBOARD,
|
|
|
|
"seat", seat,
|
|
|
|
NULL);
|
|
|
|
seat->touch = g_object_new (META_TYPE_WAYLAND_TOUCH,
|
|
|
|
"seat", seat,
|
|
|
|
NULL);
|
2016-04-01 08:39:30 +00:00
|
|
|
|
2018-08-13 16:59:02 +00:00
|
|
|
seat->text_input = meta_wayland_text_input_new (seat);
|
2017-12-06 11:55:25 +00:00
|
|
|
|
2022-05-30 21:48:44 +00:00
|
|
|
meta_wayland_data_device_init (&seat->data_device, seat);
|
|
|
|
meta_wayland_data_device_primary_init (&seat->primary_data_device, seat);
|
2013-05-03 17:51:22 +00:00
|
|
|
|
2019-10-04 12:01:19 +00:00
|
|
|
clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
|
|
|
meta_wayland_seat_update_capabilities (seat, clutter_seat);
|
|
|
|
g_signal_connect (clutter_seat, "device-added",
|
2014-07-23 13:33:03 +00:00
|
|
|
G_CALLBACK (meta_wayland_seat_devices_updated), seat);
|
2019-10-04 12:01:19 +00:00
|
|
|
g_signal_connect (clutter_seat, "device-removed",
|
2014-07-23 13:33:03 +00:00
|
|
|
G_CALLBACK (meta_wayland_seat_devices_updated), seat);
|
|
|
|
|
2013-09-10 11:45:27 +00:00
|
|
|
wl_global_create (display, &wl_seat_interface, META_WL_SEAT_VERSION, seat, bind_seat);
|
2013-05-03 17:51:22 +00:00
|
|
|
|
2016-01-26 12:31:48 +00:00
|
|
|
meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
|
|
|
|
|
2013-05-03 17:51:22 +00:00
|
|
|
return seat;
|
|
|
|
}
|
|
|
|
|
2014-04-22 22:05:44 +00:00
|
|
|
void
|
|
|
|
meta_wayland_seat_init (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
2016-01-26 12:31:48 +00:00
|
|
|
compositor->seat = meta_wayland_seat_new (compositor,
|
|
|
|
compositor->wayland_display);
|
2014-04-22 22:05:44 +00:00
|
|
|
}
|
|
|
|
|
2014-04-17 22:57:25 +00:00
|
|
|
void
|
|
|
|
meta_wayland_seat_free (MetaWaylandSeat *seat)
|
|
|
|
{
|
2019-10-04 12:01:19 +00:00
|
|
|
ClutterSeat *clutter_seat;
|
2014-07-23 13:33:03 +00:00
|
|
|
|
2019-10-04 12:01:19 +00:00
|
|
|
clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
|
|
|
g_signal_handlers_disconnect_by_data (clutter_seat, seat);
|
2014-07-23 13:33:03 +00:00
|
|
|
meta_wayland_seat_set_capabilities (seat, 0);
|
2014-04-17 22:57:25 +00:00
|
|
|
|
2016-04-01 08:39:30 +00:00
|
|
|
g_object_unref (seat->pointer);
|
|
|
|
g_object_unref (seat->keyboard);
|
|
|
|
g_object_unref (seat->touch);
|
2021-04-12 12:57:27 +00:00
|
|
|
|
2018-08-13 16:59:02 +00:00
|
|
|
meta_wayland_text_input_destroy (seat->text_input);
|
2016-04-01 08:39:30 +00:00
|
|
|
|
2019-05-17 19:56:31 +00:00
|
|
|
g_free (seat);
|
2014-04-17 22:57:25 +00:00
|
|
|
}
|
|
|
|
|
2015-09-17 14:13:31 +00:00
|
|
|
static gboolean
|
|
|
|
event_is_synthesized_crossing (const ClutterEvent *event)
|
|
|
|
{
|
|
|
|
ClutterInputDevice *device;
|
2023-08-04 10:33:33 +00:00
|
|
|
ClutterEventType event_type;
|
2015-09-17 14:13:31 +00:00
|
|
|
|
2023-08-04 10:33:33 +00:00
|
|
|
event_type = clutter_event_type (event);
|
|
|
|
|
|
|
|
if (event_type != CLUTTER_ENTER && event_type != CLUTTER_LEAVE)
|
2015-09-17 14:13:31 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
device = clutter_event_get_source_device (event);
|
2020-08-31 16:47:23 +00:00
|
|
|
return clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_LOGICAL;
|
2015-09-17 14:13:31 +00:00
|
|
|
}
|
|
|
|
|
2015-02-18 15:43:18 +00:00
|
|
|
static gboolean
|
|
|
|
event_from_supported_hardware_device (MetaWaylandSeat *seat,
|
|
|
|
const ClutterEvent *event)
|
|
|
|
{
|
2022-03-08 16:26:43 +00:00
|
|
|
ClutterInputDevice *input_device;
|
|
|
|
ClutterInputMode input_mode;
|
|
|
|
ClutterInputCapabilities capabilities;
|
|
|
|
gboolean hardware_device = FALSE;
|
|
|
|
gboolean supported_device = FALSE;
|
2015-02-18 15:43:18 +00:00
|
|
|
|
|
|
|
input_device = clutter_event_get_source_device (event);
|
|
|
|
|
|
|
|
if (input_device == NULL)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
input_mode = clutter_input_device_get_device_mode (input_device);
|
|
|
|
|
2020-08-31 16:47:23 +00:00
|
|
|
if (input_mode != CLUTTER_INPUT_MODE_PHYSICAL)
|
2015-02-18 15:43:18 +00:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
hardware_device = TRUE;
|
|
|
|
|
2022-03-08 16:26:43 +00:00
|
|
|
capabilities = clutter_input_device_get_capabilities (input_device);
|
2015-02-18 15:43:18 +00:00
|
|
|
|
2022-03-08 16:26:43 +00:00
|
|
|
if ((capabilities &
|
|
|
|
(CLUTTER_INPUT_CAPABILITY_POINTER |
|
|
|
|
CLUTTER_INPUT_CAPABILITY_KEYBOARD |
|
|
|
|
CLUTTER_INPUT_CAPABILITY_TOUCH)) != 0)
|
|
|
|
supported_device = TRUE;
|
2015-02-18 15:43:18 +00:00
|
|
|
|
|
|
|
out:
|
|
|
|
return hardware_device && supported_device;
|
|
|
|
}
|
|
|
|
|
2014-04-17 23:07:43 +00:00
|
|
|
void
|
|
|
|
meta_wayland_seat_update (MetaWaylandSeat *seat,
|
|
|
|
const ClutterEvent *event)
|
|
|
|
{
|
2018-04-24 12:22:03 +00:00
|
|
|
if (!(clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_INPUT_METHOD) &&
|
|
|
|
!event_from_supported_hardware_device (seat, event) &&
|
2015-09-17 14:13:31 +00:00
|
|
|
!event_is_synthesized_crossing (event))
|
2015-02-18 15:43:18 +00:00
|
|
|
return;
|
|
|
|
|
2023-08-04 10:33:33 +00:00
|
|
|
switch (clutter_event_type (event))
|
2014-04-17 23:07:43 +00:00
|
|
|
{
|
|
|
|
case CLUTTER_MOTION:
|
|
|
|
case CLUTTER_BUTTON_PRESS:
|
|
|
|
case CLUTTER_BUTTON_RELEASE:
|
|
|
|
case CLUTTER_SCROLL:
|
2015-09-17 14:13:31 +00:00
|
|
|
case CLUTTER_ENTER:
|
|
|
|
case CLUTTER_LEAVE:
|
2016-09-21 03:52:41 +00:00
|
|
|
if (meta_wayland_seat_has_pointer (seat))
|
2016-04-01 08:39:30 +00:00
|
|
|
meta_wayland_pointer_update (seat->pointer, event);
|
2014-04-17 23:07:43 +00:00
|
|
|
break;
|
2014-04-17 21:52:11 +00:00
|
|
|
|
2014-04-17 23:07:43 +00:00
|
|
|
case CLUTTER_KEY_PRESS:
|
|
|
|
case CLUTTER_KEY_RELEASE:
|
2016-09-21 03:52:41 +00:00
|
|
|
if (meta_wayland_seat_has_keyboard (seat))
|
2016-04-01 08:39:30 +00:00
|
|
|
meta_wayland_keyboard_update (seat->keyboard, (const ClutterKeyEvent *) event);
|
2014-04-17 23:07:43 +00:00
|
|
|
break;
|
2014-04-17 21:52:11 +00:00
|
|
|
|
2014-04-24 12:50:47 +00:00
|
|
|
case CLUTTER_TOUCH_BEGIN:
|
|
|
|
case CLUTTER_TOUCH_UPDATE:
|
|
|
|
case CLUTTER_TOUCH_END:
|
2016-09-21 03:52:41 +00:00
|
|
|
if (meta_wayland_seat_has_touch (seat))
|
2016-04-01 08:39:30 +00:00
|
|
|
meta_wayland_touch_update (seat->touch, event);
|
2014-04-24 12:50:47 +00:00
|
|
|
break;
|
|
|
|
|
2014-04-17 23:07:43 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-13 20:41:29 +00:00
|
|
|
gboolean
|
|
|
|
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
|
|
|
const ClutterEvent *event)
|
|
|
|
{
|
2023-08-04 10:33:33 +00:00
|
|
|
ClutterEventType event_type;
|
|
|
|
|
2018-04-24 12:22:03 +00:00
|
|
|
if (!(clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_INPUT_METHOD) &&
|
|
|
|
!event_from_supported_hardware_device (seat, event))
|
2015-02-18 15:43:18 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2023-08-04 10:33:33 +00:00
|
|
|
event_type = clutter_event_type (event);
|
|
|
|
|
|
|
|
if (event_type == CLUTTER_BUTTON_PRESS ||
|
|
|
|
event_type == CLUTTER_TOUCH_BEGIN)
|
2021-07-27 14:50:50 +00:00
|
|
|
{
|
|
|
|
meta_wayland_text_input_handle_event (seat->text_input, event);
|
|
|
|
}
|
|
|
|
|
2023-08-04 10:33:33 +00:00
|
|
|
switch (event_type)
|
2013-05-03 17:51:22 +00:00
|
|
|
{
|
|
|
|
case CLUTTER_MOTION:
|
|
|
|
case CLUTTER_BUTTON_PRESS:
|
|
|
|
case CLUTTER_BUTTON_RELEASE:
|
2014-04-17 23:10:39 +00:00
|
|
|
case CLUTTER_SCROLL:
|
2015-07-22 14:43:25 +00:00
|
|
|
case CLUTTER_TOUCHPAD_SWIPE:
|
2015-07-22 14:46:55 +00:00
|
|
|
case CLUTTER_TOUCHPAD_PINCH:
|
2021-04-18 18:24:52 +00:00
|
|
|
case CLUTTER_TOUCHPAD_HOLD:
|
2016-09-21 03:52:41 +00:00
|
|
|
if (meta_wayland_seat_has_pointer (seat))
|
2016-04-01 08:39:30 +00:00
|
|
|
return meta_wayland_pointer_handle_event (seat->pointer, event);
|
2014-04-17 23:10:39 +00:00
|
|
|
|
2018-01-17 13:00:44 +00:00
|
|
|
break;
|
2013-05-03 17:51:22 +00:00
|
|
|
case CLUTTER_KEY_PRESS:
|
|
|
|
case CLUTTER_KEY_RELEASE:
|
2016-09-21 03:52:41 +00:00
|
|
|
if (meta_wayland_seat_has_keyboard (seat))
|
2016-04-01 08:39:30 +00:00
|
|
|
return meta_wayland_keyboard_handle_event (seat->keyboard,
|
wayland: Don't handle input events after capability was removed
The seat capability updating is synchronous, but input events are
asynchronous (first queued then emitted). This means we may end up in a
situation where we from libinput first may receive a key event,
immediately followed by a device-removed event. Clutter will first
queue the key event, then remove the device, immediately triggering the
seat capability removal.
Later, when the clutter stage processes the queued events, the
previously queued key event will be processed, eventually making it
into MetaWaylandSeat. Before this patch, MetaWaylandSeat would still
forward the key event to MetaWaylandKeyboard, even though it had
'released' it. Doing this would cause referencing potentially freed
memory, such as the xkb state that was unreferenced when the seat
removed the capability.
In order to avoid processing these lingering events, for now, just drop
them on the floor if the capability has been removed.
Eventually, the event queuing etc needs to be redesigned to work better
when used in a Wayland compositor, but for now at least don't access
freed memory.
https://bugzilla.gnome.org/show_bug.cgi?id=770727
2016-09-02 03:50:29 +00:00
|
|
|
(const ClutterKeyEvent *) event);
|
2018-01-17 13:00:44 +00:00
|
|
|
break;
|
2014-04-24 12:50:47 +00:00
|
|
|
case CLUTTER_TOUCH_BEGIN:
|
|
|
|
case CLUTTER_TOUCH_UPDATE:
|
|
|
|
case CLUTTER_TOUCH_END:
|
2016-09-21 03:52:41 +00:00
|
|
|
if (meta_wayland_seat_has_touch (seat))
|
2016-04-01 08:39:30 +00:00
|
|
|
return meta_wayland_touch_handle_event (seat->touch, event);
|
2013-05-03 17:51:22 +00:00
|
|
|
|
2020-02-17 10:25:14 +00:00
|
|
|
break;
|
|
|
|
case CLUTTER_IM_COMMIT:
|
|
|
|
case CLUTTER_IM_DELETE:
|
|
|
|
case CLUTTER_IM_PREEDIT:
|
|
|
|
if (meta_wayland_text_input_handle_event (seat->text_input, event))
|
|
|
|
return TRUE;
|
|
|
|
|
2018-01-17 13:00:44 +00:00
|
|
|
break;
|
2013-05-03 17:51:22 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-09-04 13:01:11 +00:00
|
|
|
|
|
|
|
return FALSE;
|
2013-05-03 17:51:22 +00:00
|
|
|
}
|
|
|
|
|
2014-07-10 14:13:54 +00:00
|
|
|
void
|
|
|
|
meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
|
|
|
|
MetaWaylandSurface *surface)
|
|
|
|
{
|
2022-05-30 21:48:44 +00:00
|
|
|
MetaWaylandCompositor *compositor = meta_wayland_seat_get_compositor (seat);
|
2016-05-10 15:29:57 +00:00
|
|
|
MetaWaylandTabletSeat *tablet_seat;
|
|
|
|
|
2016-09-21 03:52:41 +00:00
|
|
|
if (meta_wayland_seat_has_keyboard (seat))
|
2016-05-10 15:29:57 +00:00
|
|
|
{
|
2016-04-01 08:39:30 +00:00
|
|
|
meta_wayland_keyboard_set_focus (seat->keyboard, surface);
|
2016-05-10 15:29:57 +00:00
|
|
|
meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
|
2020-05-13 16:07:27 +00:00
|
|
|
meta_wayland_data_device_primary_set_keyboard_focus (&seat->primary_data_device);
|
2016-05-10 15:29:57 +00:00
|
|
|
}
|
2015-02-18 15:43:42 +00:00
|
|
|
|
2016-05-10 15:29:57 +00:00
|
|
|
tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
|
|
|
|
meta_wayland_tablet_seat_set_pad_focus (tablet_seat, surface);
|
2017-12-06 11:55:25 +00:00
|
|
|
|
2018-08-13 16:59:02 +00:00
|
|
|
meta_wayland_text_input_set_focus (seat->text_input, surface);
|
2014-07-10 14:13:54 +00:00
|
|
|
}
|
|
|
|
|
2014-05-22 14:57:02 +00:00
|
|
|
gboolean
|
2022-10-21 17:36:59 +00:00
|
|
|
meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
|
|
|
|
MetaWaylandSurface *surface,
|
|
|
|
uint32_t serial,
|
|
|
|
gboolean require_pressed,
|
|
|
|
ClutterInputDevice **device_out,
|
|
|
|
ClutterEventSequence **sequence_out,
|
|
|
|
float *x,
|
|
|
|
float *y)
|
2014-05-22 14:57:02 +00:00
|
|
|
{
|
2017-06-23 15:02:21 +00:00
|
|
|
MetaWaylandCompositor *compositor;
|
|
|
|
MetaWaylandTabletSeat *tablet_seat;
|
|
|
|
GList *tools, *l;
|
2014-07-21 23:28:39 +00:00
|
|
|
|
2022-05-30 21:48:44 +00:00
|
|
|
compositor = meta_wayland_seat_get_compositor (seat);
|
2017-06-23 15:02:21 +00:00
|
|
|
tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
|
|
|
|
tools = g_hash_table_get_values (tablet_seat->tools);
|
2014-07-21 23:28:39 +00:00
|
|
|
|
2017-06-23 15:02:21 +00:00
|
|
|
if (meta_wayland_seat_has_touch (seat))
|
2014-07-21 23:28:39 +00:00
|
|
|
{
|
2017-06-23 15:02:21 +00:00
|
|
|
ClutterEventSequence *sequence;
|
2023-09-02 13:52:57 +00:00
|
|
|
|
2017-06-23 15:02:21 +00:00
|
|
|
sequence = meta_wayland_touch_find_grab_sequence (seat->touch,
|
|
|
|
surface,
|
|
|
|
serial);
|
|
|
|
if (sequence)
|
|
|
|
{
|
2023-09-02 13:52:57 +00:00
|
|
|
ClutterSeat *clutter_seat =
|
|
|
|
clutter_backend_get_default_seat (clutter_get_default_backend ());
|
|
|
|
|
2022-10-21 17:36:59 +00:00
|
|
|
if (device_out)
|
2023-09-02 13:52:57 +00:00
|
|
|
*device_out = clutter_seat_get_pointer (clutter_seat);
|
2022-10-21 17:36:59 +00:00
|
|
|
if (sequence_out)
|
|
|
|
*sequence_out = sequence;
|
|
|
|
|
2017-06-23 15:02:21 +00:00
|
|
|
meta_wayland_touch_get_press_coords (seat->touch, sequence, x, y);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2014-07-21 23:28:39 +00:00
|
|
|
}
|
2015-02-18 15:43:42 +00:00
|
|
|
|
2017-06-23 15:02:21 +00:00
|
|
|
if (meta_wayland_seat_has_pointer (seat))
|
|
|
|
{
|
|
|
|
if ((!require_pressed || seat->pointer->button_count > 0) &&
|
|
|
|
meta_wayland_pointer_can_grab_surface (seat->pointer, surface, serial))
|
2015-02-18 15:43:42 +00:00
|
|
|
{
|
2022-10-21 17:36:59 +00:00
|
|
|
if (device_out)
|
|
|
|
*device_out = seat->pointer->device;
|
|
|
|
if (sequence_out)
|
|
|
|
*sequence_out = NULL;
|
|
|
|
|
2015-02-18 15:43:42 +00:00
|
|
|
if (x)
|
2016-04-01 08:39:30 +00:00
|
|
|
*x = seat->pointer->grab_x;
|
2015-02-18 15:43:42 +00:00
|
|
|
if (y)
|
2016-04-01 08:39:30 +00:00
|
|
|
*y = seat->pointer->grab_y;
|
2017-06-23 15:02:21 +00:00
|
|
|
|
|
|
|
return TRUE;
|
2015-02-18 15:43:42 +00:00
|
|
|
}
|
|
|
|
}
|
2014-07-21 23:28:39 +00:00
|
|
|
|
2017-06-23 15:02:21 +00:00
|
|
|
for (l = tools; l; l = l->next)
|
|
|
|
{
|
|
|
|
MetaWaylandTabletTool *tool = l->data;
|
|
|
|
|
|
|
|
if ((!require_pressed || tool->button_count > 0) &&
|
|
|
|
meta_wayland_tablet_tool_can_grab_surface (tool, surface, serial))
|
|
|
|
{
|
2022-10-21 17:36:59 +00:00
|
|
|
if (device_out)
|
|
|
|
*device_out = tool->device;
|
|
|
|
if (sequence_out)
|
|
|
|
*sequence_out = NULL;
|
|
|
|
|
2017-06-23 15:02:21 +00:00
|
|
|
if (x)
|
|
|
|
*x = tool->grab_x;
|
|
|
|
if (y)
|
|
|
|
*y = tool->grab_y;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
2014-05-22 14:57:02 +00:00
|
|
|
}
|
2015-10-09 14:42:06 +00:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_wayland_seat_can_popup (MetaWaylandSeat *seat,
|
|
|
|
uint32_t serial)
|
|
|
|
{
|
2019-10-28 17:07:31 +00:00
|
|
|
MetaWaylandCompositor *compositor;
|
|
|
|
MetaWaylandTabletSeat *tablet_seat;
|
|
|
|
|
2022-05-30 21:48:44 +00:00
|
|
|
compositor = meta_wayland_seat_get_compositor (seat);
|
2019-10-28 17:07:31 +00:00
|
|
|
tablet_seat =
|
|
|
|
meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
|
|
|
|
|
2016-04-01 08:39:30 +00:00
|
|
|
return (meta_wayland_pointer_can_popup (seat->pointer, serial) ||
|
|
|
|
meta_wayland_keyboard_can_popup (seat->keyboard, serial) ||
|
2019-10-28 17:07:31 +00:00
|
|
|
meta_wayland_touch_can_popup (seat->touch, serial) ||
|
|
|
|
meta_wayland_tablet_seat_can_popup (tablet_seat, serial));
|
2015-10-09 14:42:06 +00:00
|
|
|
}
|
2016-09-12 15:12:40 +00:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_wayland_seat_has_keyboard (MetaWaylandSeat *seat)
|
|
|
|
{
|
|
|
|
return (seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_wayland_seat_has_pointer (MetaWaylandSeat *seat)
|
|
|
|
{
|
|
|
|
return (seat->capabilities & WL_SEAT_CAPABILITY_POINTER) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_wayland_seat_has_touch (MetaWaylandSeat *seat)
|
|
|
|
{
|
|
|
|
return (seat->capabilities & WL_SEAT_CAPABILITY_TOUCH) != 0;
|
|
|
|
}
|
2022-05-30 21:48:44 +00:00
|
|
|
|
|
|
|
MetaWaylandCompositor *
|
|
|
|
meta_wayland_seat_get_compositor (MetaWaylandSeat *seat)
|
|
|
|
{
|
|
|
|
return seat->compositor;
|
|
|
|
}
|
2022-09-29 13:05:10 +00:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_wayland_seat_is_grabbed (MetaWaylandSeat *seat)
|
|
|
|
{
|
|
|
|
if (meta_wayland_seat_has_pointer (seat) &&
|
|
|
|
meta_wayland_pointer_is_grabbed (seat->pointer))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (meta_wayland_seat_has_keyboard (seat) &&
|
|
|
|
meta_wayland_keyboard_is_grabbed (seat->keyboard))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|