mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
seat: Listen for ClutterDeviceManager signals in order to update capabilities
The capability flags are determined from the device types of the slave devices that are currently attached. This also happens whenever a device is added or removed, so the capabilities are kept up to date, and clients know about these. On VT switch, all slave devices are temporarily removed, so the cascade of signals will make the seat end up with capabililities=0 while input is suspended. https://bugzilla.gnome.org/show_bug.cgi?id=733563
This commit is contained in:
parent
f55737ec06
commit
ac448bd42b
@ -27,6 +27,9 @@
|
||||
#include "meta-wayland-versions.h"
|
||||
#include "meta-wayland-data-device.h"
|
||||
|
||||
#define CAPABILITY_ENABLED(prev, cur, capability) ((cur & (capability)) && !(prev & (capability)))
|
||||
#define CAPABILITY_DISABLED(prev, cur, capability) ((prev & (capability)) && !(cur & (capability)))
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
@ -86,27 +89,136 @@ bind_seat (struct wl_client *client,
|
||||
wl_resource_set_implementation (resource, &seat_interface, seat, unbind_resource);
|
||||
wl_list_insert (&seat->base_resource_list, wl_resource_get_link (resource));
|
||||
|
||||
wl_seat_send_capabilities (resource,
|
||||
WL_SEAT_CAPABILITY_POINTER |
|
||||
WL_SEAT_CAPABILITY_KEYBOARD |
|
||||
WL_SEAT_CAPABILITY_TOUCH);
|
||||
wl_seat_send_capabilities (resource, seat->capabilities);
|
||||
|
||||
if (version >= WL_SEAT_NAME_SINCE_VERSION)
|
||||
wl_seat_send_name (resource, "seat0");
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
lookup_device_capabilities (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
const GSList *devices, *l;
|
||||
uint32_t capabilities = 0;
|
||||
|
||||
devices = clutter_device_manager_peek_devices (device_manager);
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
ClutterInputDeviceType device_type;
|
||||
|
||||
/* Only look for physical devices, master devices have rather generic
|
||||
* keyboard/pointer device types, which is not truly representative of
|
||||
* the slave devices connected to them.
|
||||
*/
|
||||
if (clutter_input_device_get_device_mode (l->data) == CLUTTER_INPUT_MODE_MASTER)
|
||||
continue;
|
||||
|
||||
device_type = clutter_input_device_get_device_type (l->data);
|
||||
|
||||
switch (device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
capabilities |= WL_SEAT_CAPABILITY_POINTER;
|
||||
break;
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||
break;
|
||||
case CLUTTER_TOUCHSCREEN_DEVICE:
|
||||
capabilities |= WL_SEAT_CAPABILITY_TOUCH;
|
||||
break;
|
||||
default:
|
||||
g_debug ("Ignoring device '%s' with unhandled type %d",
|
||||
clutter_input_device_get_device_name (l->data),
|
||||
device_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
meta_wayland_pointer_init (&seat->pointer, seat->wl_display);
|
||||
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_POINTER))
|
||||
meta_wayland_pointer_release (&seat->pointer);
|
||||
|
||||
if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_KEYBOARD))
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
meta_wayland_keyboard_init (&seat->keyboard, seat->wl_display);
|
||||
display = meta_get_display ();
|
||||
|
||||
/* Post-initialization, ensure the input focus is in sync */
|
||||
if (display)
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
}
|
||||
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_KEYBOARD))
|
||||
meta_wayland_keyboard_release (&seat->keyboard);
|
||||
|
||||
if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_TOUCH))
|
||||
meta_wayland_touch_init (&seat->touch, seat->wl_display);
|
||||
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_TOUCH))
|
||||
meta_wayland_touch_release (&seat->touch);
|
||||
|
||||
/* Broadcast capability changes */
|
||||
wl_resource_for_each (resource, &seat->base_resource_list)
|
||||
{
|
||||
wl_seat_send_capabilities (resource, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_seat_update_capabilities (MetaWaylandSeat *seat,
|
||||
ClutterDeviceManager *device_manager)
|
||||
{
|
||||
uint32_t capabilities;
|
||||
|
||||
capabilities = lookup_device_capabilities (device_manager);
|
||||
meta_wayland_seat_set_capabilities (seat, capabilities);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_seat_devices_updated (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *input_device,
|
||||
MetaWaylandSeat *seat)
|
||||
{
|
||||
meta_wayland_seat_update_capabilities (seat, device_manager);
|
||||
}
|
||||
|
||||
static MetaWaylandSeat *
|
||||
meta_wayland_seat_new (struct wl_display *display)
|
||||
{
|
||||
MetaWaylandSeat *seat = g_new0 (MetaWaylandSeat, 1);
|
||||
ClutterDeviceManager *device_manager;
|
||||
|
||||
wl_list_init (&seat->base_resource_list);
|
||||
seat->wl_display = display;
|
||||
|
||||
meta_wayland_pointer_init (&seat->pointer, display);
|
||||
meta_wayland_keyboard_init (&seat->keyboard, display);
|
||||
meta_wayland_touch_init (&seat->touch, display);
|
||||
meta_wayland_data_device_init (&seat->data_device);
|
||||
|
||||
device_manager = clutter_device_manager_get_default ();
|
||||
meta_wayland_seat_update_capabilities (seat, device_manager);
|
||||
g_signal_connect (device_manager, "device-added",
|
||||
G_CALLBACK (meta_wayland_seat_devices_updated), seat);
|
||||
g_signal_connect (device_manager, "device-removed",
|
||||
G_CALLBACK (meta_wayland_seat_devices_updated), seat);
|
||||
|
||||
wl_global_create (display, &wl_seat_interface, META_WL_SEAT_VERSION, seat, bind_seat);
|
||||
|
||||
return seat;
|
||||
@ -121,9 +233,11 @@ meta_wayland_seat_init (MetaWaylandCompositor *compositor)
|
||||
void
|
||||
meta_wayland_seat_free (MetaWaylandSeat *seat)
|
||||
{
|
||||
meta_wayland_pointer_release (&seat->pointer);
|
||||
meta_wayland_keyboard_release (&seat->keyboard);
|
||||
meta_wayland_touch_release (&seat->touch);
|
||||
ClutterDeviceManager *device_manager;
|
||||
|
||||
device_manager = clutter_device_manager_get_default ();
|
||||
g_signal_handlers_disconnect_by_data (device_manager, seat);
|
||||
meta_wayland_seat_set_capabilities (seat, 0);
|
||||
|
||||
g_slice_free (MetaWaylandSeat, seat);
|
||||
}
|
||||
|
@ -34,11 +34,14 @@
|
||||
struct _MetaWaylandSeat
|
||||
{
|
||||
struct wl_list base_resource_list;
|
||||
struct wl_display *wl_display;
|
||||
|
||||
MetaWaylandPointer pointer;
|
||||
MetaWaylandKeyboard keyboard;
|
||||
MetaWaylandTouch touch;
|
||||
MetaWaylandDataDevice data_device;
|
||||
|
||||
guint capabilities;
|
||||
};
|
||||
|
||||
void meta_wayland_seat_init (MetaWaylandCompositor *compositor);
|
||||
|
Loading…
Reference in New Issue
Block a user