1
0
Fork 0

seat-impl: Keep track of virtual input devices too

Virtual input devices too are dealt with inside the input thread, as
without this, things like touch mode won't get updated correctly.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3812>
This commit is contained in:
Jonas Ådahl 2024-06-14 22:03:29 +02:00 committed by Marge Bot
parent 54ba9448ed
commit 5fc60eac9d
5 changed files with 126 additions and 83 deletions

View file

@ -1575,20 +1575,18 @@ meta_input_device_native_new_in_impl (MetaSeatImpl *seat_impl,
}
/*
* meta_input_device_native_new_virtual:
* meta_input_device_native_new_virtual_in_impl:
* @seat: the seat the device will belong to
* @type: the input device type
*
* Create a new virtual ClutterInputDevice of the given type.
*/
ClutterInputDevice *
meta_input_device_native_new_virtual (ClutterSeat *seat,
ClutterInputDeviceType type,
ClutterInputMode mode)
meta_input_device_native_new_virtual_in_impl (MetaSeatImpl *seat_impl,
ClutterInputDeviceType type,
ClutterInputMode mode)
{
MetaInputDeviceNative *device;
MetaBackend *backend =
meta_seat_native_get_backend (META_SEAT_NATIVE (seat));
const char *name;
switch (type)
@ -1608,11 +1606,11 @@ meta_input_device_native_new_virtual (ClutterSeat *seat,
};
device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE,
"backend", backend,
"backend", meta_seat_impl_get_backend (seat_impl),
"name", name,
"device-type", type,
"device-mode", mode,
"seat", seat,
"seat", seat_impl->seat_native,
NULL);
return CLUTTER_INPUT_DEVICE (device);

View file

@ -135,9 +135,9 @@ GType meta_input_device_native_get_type (void) G_GNUC
ClutterInputDevice * meta_input_device_native_new_in_impl (MetaSeatImpl *seat_impl,
struct libinput_device *libinput_device);
ClutterInputDevice * meta_input_device_native_new_virtual (ClutterSeat *seat,
ClutterInputDeviceType type,
ClutterInputMode mode);
ClutterInputDevice * meta_input_device_native_new_virtual_in_impl (MetaSeatImpl *seat_impl,
ClutterInputDeviceType type,
ClutterInputMode mode);
void meta_input_device_native_update_leds_in_impl (MetaInputDeviceNative *device,
enum libinput_led leds);

View file

@ -1639,6 +1639,9 @@ has_pointer (MetaSeatImpl *seat_impl)
static gboolean
device_is_tablet_switch (MetaInputDeviceNative *device_native)
{
if (!device_native->libinput_device)
return FALSE;
if (libinput_device_has_capability (device_native->libinput_device,
LIBINPUT_DEVICE_CAP_SWITCH) &&
libinput_device_switch_has_switch (device_native->libinput_device,
@ -1696,16 +1699,13 @@ update_touch_mode (MetaSeatImpl *seat_impl)
}
}
static ClutterInputDevice *
evdev_add_device (MetaSeatImpl *seat_impl,
struct libinput_device *libinput_device)
static void
meta_seat_impl_take_device (MetaSeatImpl *seat_impl,
ClutterInputDevice *device)
{
ClutterInputDeviceType type;
ClutterInputDevice *device;
gboolean is_touchscreen, is_tablet_switch, is_pointer;
device = meta_input_device_native_new_in_impl (seat_impl, libinput_device);
seat_impl->devices = g_slist_prepend (seat_impl->devices, device);
meta_seat_impl_sync_leds_in_impl (seat_impl);
@ -1736,19 +1736,17 @@ evdev_add_device (MetaSeatImpl *seat_impl,
meta_input_device_native_apply_kbd_a11y_settings_in_impl (keyboard_native,
&kbd_a11y_settings);
}
return device;
}
static void
evdev_remove_device (MetaSeatImpl *seat_impl,
MetaInputDeviceNative *device_native)
meta_seat_impl_remove_device (MetaSeatImpl *seat_impl,
ClutterInputDevice *device)
{
ClutterInputDevice *device;
MetaInputDeviceNative *device_native;
ClutterInputDeviceType device_type;
gboolean is_touchscreen, is_tablet_switch, is_pointer;
device = CLUTTER_INPUT_DEVICE (device_native);
device_native = META_INPUT_DEVICE_NATIVE (device);
seat_impl->devices = g_slist_remove (seat_impl->devices, device);
device_type = clutter_input_device_get_device_type (device);
@ -1791,7 +1789,9 @@ process_base_event (MetaSeatImpl *seat_impl,
case LIBINPUT_EVENT_DEVICE_ADDED:
libinput_device = libinput_event_get_device (event);
device = evdev_add_device (seat_impl, libinput_device);
device = meta_input_device_native_new_in_impl (seat_impl,
libinput_device);
meta_seat_impl_take_device (seat_impl, device);
device_event =
clutter_event_device_notify_new (CLUTTER_DEVICE_ADDED,
CLUTTER_EVENT_NONE,
@ -1811,8 +1811,7 @@ process_base_event (MetaSeatImpl *seat_impl,
CLUTTER_CURRENT_TIME,
device);
meta_input_settings_remove_device (input_settings, device);
evdev_remove_device (seat_impl,
META_INPUT_DEVICE_NATIVE (device));
meta_seat_impl_remove_device (seat_impl, device);
break;
default:
@ -2877,6 +2876,29 @@ init_libinput_source (MetaSeatImpl *seat_impl)
g_source_unref (source);
}
static void
init_core_devices (MetaSeatImpl *seat_impl)
{
ClutterInputDevice *device;
device =
meta_input_device_native_new_virtual_in_impl (seat_impl,
CLUTTER_POINTER_DEVICE,
CLUTTER_INPUT_MODE_LOGICAL);
seat_impl->pointer_x = INITIAL_POINTER_X;
seat_impl->pointer_y = INITIAL_POINTER_Y;
meta_input_device_native_set_coords_in_impl (META_INPUT_DEVICE_NATIVE (device),
seat_impl->pointer_x,
seat_impl->pointer_y);
seat_impl->core_pointer = device;
device =
meta_input_device_native_new_virtual_in_impl (seat_impl,
CLUTTER_KEYBOARD_DEVICE,
CLUTTER_INPUT_MODE_LOGICAL);
seat_impl->core_keyboard = device;
}
static gpointer
input_thread (MetaSeatImpl *seat_impl)
{
@ -2896,6 +2918,8 @@ input_thread (MetaSeatImpl *seat_impl)
"Mutter Input Thread");
#endif
init_core_devices (seat_impl);
priv->device_files =
g_hash_table_new_full (NULL, NULL,
NULL,
@ -2986,31 +3010,6 @@ meta_seat_impl_initable_init (GInitable *initable,
return TRUE;
}
static void
meta_seat_impl_constructed (GObject *object)
{
MetaSeatImpl *seat_impl = META_SEAT_IMPL (object);
ClutterInputDevice *device;
device = meta_input_device_native_new_virtual (
CLUTTER_SEAT (seat_impl->seat_native), CLUTTER_POINTER_DEVICE,
CLUTTER_INPUT_MODE_LOGICAL);
seat_impl->pointer_x = INITIAL_POINTER_X;
seat_impl->pointer_y = INITIAL_POINTER_Y;
meta_input_device_native_set_coords_in_impl (META_INPUT_DEVICE_NATIVE (device),
seat_impl->pointer_x,
seat_impl->pointer_y);
seat_impl->core_pointer = device;
device = meta_input_device_native_new_virtual (
CLUTTER_SEAT (seat_impl->seat_native), CLUTTER_KEYBOARD_DEVICE,
CLUTTER_INPUT_MODE_LOGICAL);
seat_impl->core_keyboard = device;
if (G_OBJECT_CLASS (meta_seat_impl_parent_class)->constructed)
G_OBJECT_CLASS (meta_seat_impl_parent_class)->constructed (object);
}
static void
meta_seat_impl_set_property (GObject *object,
guint prop_id,
@ -3307,7 +3306,6 @@ meta_seat_impl_class_init (MetaSeatImplClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_seat_impl_constructed;
object_class->set_property = meta_seat_impl_set_property;
object_class->get_property = meta_seat_impl_get_property;
object_class->finalize = meta_seat_impl_finalize;
@ -3901,3 +3899,34 @@ meta_seat_impl_get_backend (MetaSeatImpl *seat_impl)
{
return meta_seat_native_get_backend (seat_impl->seat_native);
}
void
meta_seat_impl_add_virtual_input_device (MetaSeatImpl *seat_impl,
ClutterInputDevice *device)
{
ClutterEvent *device_event;
meta_seat_impl_take_device (seat_impl, g_object_ref (device));
device_event =
clutter_event_device_notify_new (CLUTTER_DEVICE_ADDED,
CLUTTER_EVENT_NONE,
CLUTTER_CURRENT_TIME,
device);
queue_event (seat_impl, device_event);
}
void
meta_seat_impl_remove_virtual_input_device (MetaSeatImpl *seat_impl,
ClutterInputDevice *device)
{
ClutterEvent *device_event;
meta_seat_impl_remove_device (seat_impl, device);
device_event = clutter_event_device_notify_new (CLUTTER_DEVICE_REMOVED,
CLUTTER_EVENT_NONE,
CLUTTER_CURRENT_TIME,
device);
queue_event (seat_impl, device_event);
}

View file

@ -257,3 +257,9 @@ void meta_seat_impl_queue_main_thread_idle (MetaSeatImpl *seat_impl,
GDestroyNotify destroy_notify);
MetaBackend * meta_seat_impl_get_backend (MetaSeatImpl *seat_impl);
void meta_seat_impl_add_virtual_input_device (MetaSeatImpl *seat_impl,
ClutterInputDevice *device);
void meta_seat_impl_remove_virtual_input_device (MetaSeatImpl *seat_impl,
ClutterInputDevice *device);

View file

@ -45,6 +45,7 @@ typedef struct _ImplState ImplState;
struct _ImplState
{
MetaSeatImpl *seat_impl;
ClutterInputDevice *device;
int button_count[KEY_CNT];
};
@ -159,14 +160,10 @@ static gboolean
release_device_in_impl (GTask *task)
{
ImplState *impl_state = g_task_get_task_data (task);
ClutterSeat *seat;
MetaSeatImpl *seat_impl;
MetaSeatImpl *seat_impl = impl_state->seat_impl;
int code;
uint64_t time_us;
ClutterEvent *device_event;
seat = clutter_input_device_get_seat (impl_state->device);
seat_impl = META_SEAT_NATIVE (seat)->impl;
time_us = g_get_monotonic_time ();
meta_topic (META_DEBUG_INPUT,
@ -200,11 +197,7 @@ release_device_in_impl (GTask *task)
}
}
device_event = clutter_event_device_notify_new (CLUTTER_DEVICE_REMOVED,
CLUTTER_EVENT_NONE,
time_us,
impl_state->device);
_clutter_event_push (device_event, FALSE);
meta_seat_impl_remove_virtual_input_device (seat_impl, impl_state->device);
g_clear_object (&impl_state->device);
g_task_return_boolean (task, TRUE);
@ -243,7 +236,7 @@ meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevi
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventMotion, 1);
event->time_us = time_us;
@ -288,7 +281,7 @@ meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevi
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventMotion, 1);
event->time_us = time_us;
@ -362,7 +355,7 @@ meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtu
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventButton, 1);
event->time_us = time_us;
@ -432,7 +425,7 @@ meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventKey, 1);
event->time_us = time_us;
@ -622,7 +615,7 @@ meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtu
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventKey, 1);
event->time_us = time_us;
@ -701,7 +694,7 @@ meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevi
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventScroll, 1);
event->time_us = time_us;
@ -762,7 +755,7 @@ meta_virtual_input_device_native_notify_scroll_continuous (ClutterVirtualInputDe
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventScroll, 1);
event->time_us = time_us;
@ -823,7 +816,7 @@ meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *v
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventTouch, 1);
event->time_us = time_us;
@ -883,7 +876,7 @@ meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventTouch, 1);
event->time_us = time_us;
@ -941,7 +934,7 @@ meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *vir
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
GTask *task;
g_return_if_fail (virtual_evdev->impl_state->device != NULL);
g_return_if_fail (virtual_evdev->impl_state != NULL);
event = g_new0 (MetaVirtualEventTouch, 1);
event->time_us = time_us;
@ -1000,6 +993,29 @@ meta_virtual_input_device_native_set_property (GObject *object,
}
}
static gboolean
create_device_in_impl (GTask *task)
{
ImplState *impl_state = g_task_get_task_data (task);
MetaVirtualInputDeviceNative *virtual_evdev =
g_task_get_source_object (task);
MetaSeatImpl *seat_impl = virtual_evdev->seat->impl;
ClutterVirtualInputDevice *virtual_device =
CLUTTER_VIRTUAL_INPUT_DEVICE (virtual_evdev);
ClutterInputDeviceType device_type =
clutter_virtual_input_device_get_device_type (virtual_device);
impl_state->seat_impl = seat_impl;
impl_state->device =
meta_input_device_native_new_virtual_in_impl (seat_impl,
device_type,
CLUTTER_INPUT_MODE_PHYSICAL);
meta_seat_impl_add_virtual_input_device (seat_impl, impl_state->device);
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
static void
meta_virtual_input_device_native_constructed (GObject *object)
{
@ -1008,7 +1024,7 @@ meta_virtual_input_device_native_constructed (GObject *object)
MetaVirtualInputDeviceNative *virtual_evdev =
META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
ClutterInputDeviceType device_type;
ClutterEvent *device_event = NULL;
g_autoptr (GTask) task = NULL;
device_type = clutter_virtual_input_device_get_device_type (virtual_device);
@ -1017,17 +1033,11 @@ meta_virtual_input_device_native_constructed (GObject *object)
device_type, virtual_device);
virtual_evdev->impl_state = g_new0 (ImplState, 1);
virtual_evdev->impl_state->device =
meta_input_device_native_new_virtual (CLUTTER_SEAT (virtual_evdev->seat),
device_type,
CLUTTER_INPUT_MODE_PHYSICAL);
device_event =
clutter_event_device_notify_new (CLUTTER_DEVICE_ADDED,
CLUTTER_EVENT_NONE,
CLUTTER_CURRENT_TIME,
virtual_evdev->impl_state->device);
_clutter_event_push (device_event, FALSE);
task = g_task_new (virtual_device, NULL, NULL, NULL);
g_task_set_task_data (task, virtual_evdev->impl_state, NULL);
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
(GSourceFunc) create_device_in_impl);
}
static void