backends/native: Make some MetaSeatImpl API "async"

This API is the one accessed from different bits of the UI thread,
make it "async" (it's basically one-way setters, so API stays the same
in the surface) and able to run in the MetaSeatImpl main context.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403
This commit is contained in:
Carlos Garnacho 2020-08-12 15:37:43 +02:00
parent faec8d29b0
commit 6b8d95d9c4
2 changed files with 216 additions and 47 deletions

View File

@ -136,6 +136,22 @@ void meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat,
float *dy); float *dy);
void meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat); void meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat);
void
meta_seat_impl_run_input_task (MetaSeatImpl *impl,
GTask *task,
GSourceFunc dispatch_func)
{
GSource *source;
source = g_idle_source_new ();
g_source_set_priority (source, G_PRIORITY_HIGH);
g_source_set_callback (source,
dispatch_func,
g_object_ref (task),
g_object_unref);
g_source_attach (source, impl->input_context);
}
void void
meta_seat_impl_set_libinput_seat (MetaSeatImpl *seat, meta_seat_impl_set_libinput_seat (MetaSeatImpl *seat,
struct libinput_seat *libinput_seat) struct libinput_seat *libinput_seat)
@ -2666,12 +2682,35 @@ meta_seat_impl_create_virtual_device (MetaSeatImpl *seat,
NULL); NULL);
} }
static gboolean
warp_pointer (GTask *task)
{
MetaSeatImpl *seat = g_task_get_source_object (task);
graphene_point_t *point;
point = g_task_get_task_data (task);
notify_absolute_motion (seat->core_pointer, 0,
point->x, point->y, NULL);
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
void void
meta_seat_impl_warp_pointer (MetaSeatImpl *seat, meta_seat_impl_warp_pointer (MetaSeatImpl *seat,
int x, int x,
int y) int y)
{ {
notify_absolute_motion (seat->core_pointer, 0, x, y, NULL); graphene_point_t *point;
GTask *task;
point = graphene_point_alloc ();
point->x = x;
point->y = y;
task = g_task_new (seat, NULL, NULL, NULL);
g_task_set_task_data (task, point, (GDestroyNotify) graphene_point_free);
meta_seat_impl_run_input_task (seat, task, (GSourceFunc) warp_pointer);
g_object_unref (task);
} }
gboolean gboolean
@ -2915,6 +2954,29 @@ meta_seat_impl_release_device_id (MetaSeatImpl *seat,
compare_ids); compare_ids);
} }
static gboolean
release_devices (GTask *task)
{
MetaSeatImpl *seat = g_task_get_source_object (task);
if (seat->released)
{
g_warning ("meta_seat_impl_release_devices() shouldn't be called "
"multiple times without a corresponding call to "
"meta_seat_impl_reclaim_devices() first");
}
else
{
libinput_suspend (seat->libinput);
process_events (seat);
seat->released = TRUE;
}
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
/** /**
* meta_seat_impl_release_devices: * meta_seat_impl_release_devices:
* *
@ -2928,20 +2990,36 @@ meta_seat_impl_release_device_id (MetaSeatImpl *seat,
void void
meta_seat_impl_release_devices (MetaSeatImpl *seat) meta_seat_impl_release_devices (MetaSeatImpl *seat)
{ {
GTask *task;
g_return_if_fail (META_IS_SEAT_IMPL (seat)); g_return_if_fail (META_IS_SEAT_IMPL (seat));
task = g_task_new (seat, NULL, NULL, NULL);
meta_seat_impl_run_input_task (seat, task, (GSourceFunc) release_devices);
g_object_unref (task);
}
static gboolean
reclaim_devices (GTask *task)
{
MetaSeatImpl *seat = g_task_get_source_object (task);
if (seat->released) if (seat->released)
{ {
g_warning ("meta_seat_impl_release_devices() shouldn't be called " libinput_resume (seat->libinput);
"multiple times without a corresponding call to " meta_seat_impl_update_xkb_state (seat);
"meta_seat_impl_reclaim_devices() first");
return;
}
libinput_suspend (seat->libinput);
process_events (seat); process_events (seat);
seat->released = TRUE; seat->released = FALSE;
}
else
{
g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without "
"previous call to meta_seat_impl_release_devices");
}
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
} }
/** /**
@ -2958,18 +3036,28 @@ meta_seat_impl_release_devices (MetaSeatImpl *seat)
void void
meta_seat_impl_reclaim_devices (MetaSeatImpl *seat) meta_seat_impl_reclaim_devices (MetaSeatImpl *seat)
{ {
if (!seat->released) GTask *task;
{
g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without " g_return_if_fail (META_IS_SEAT_IMPL (seat));
"previous call to meta_seat_impl_release_devices");
return; task = g_task_new (seat, NULL, NULL, NULL);
} meta_seat_impl_run_input_task (seat, task, (GSourceFunc) reclaim_devices);
g_object_unref (task);
}
static gboolean
set_keyboard_map (GTask *task)
{
MetaSeatImpl *seat = g_task_get_source_object (task);
struct xkb_keymap *xkb_keymap = g_task_get_task_data (task);
MetaKeymapNative *keymap;
keymap = seat->keymap;
meta_keymap_native_set_keyboard_map (keymap, xkb_keymap);
libinput_resume (seat->libinput);
meta_seat_impl_update_xkb_state (seat); meta_seat_impl_update_xkb_state (seat);
process_events (seat); g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
seat->released = FALSE;
} }
/** /**
@ -2986,34 +3074,28 @@ void
meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat, meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat,
struct xkb_keymap *xkb_keymap) struct xkb_keymap *xkb_keymap)
{ {
MetaKeymapNative *keymap; GTask *task;
g_return_if_fail (META_IS_SEAT_IMPL (seat)); g_return_if_fail (META_IS_SEAT_IMPL (seat));
keymap = seat->keymap; task = g_task_new (seat, NULL, NULL, NULL);
meta_keymap_native_set_keyboard_map (keymap, xkb_keymap); g_task_set_task_data (task,
xkb_keymap_ref (xkb_keymap),
meta_seat_impl_update_xkb_state (seat); (GDestroyNotify) xkb_keymap_unref);
meta_seat_impl_run_input_task (seat, task, (GSourceFunc) set_keyboard_map);
g_object_unref (task);
} }
/** static gboolean
* meta_seat_impl_set_keyboard_layout_index: (skip) set_keyboard_layout_index (GTask *task)
* @seat: the #ClutterSeat created by the evdev backend
* @idx: the xkb layout index to set
*
* Sets the xkb layout index on the backend's #xkb_state .
*/
void
meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat,
xkb_layout_index_t idx)
{ {
MetaSeatImpl *seat = g_task_get_source_object (task);
xkb_layout_index_t idx = GPOINTER_TO_UINT (g_task_get_task_data (task));
xkb_mod_mask_t depressed_mods; xkb_mod_mask_t depressed_mods;
xkb_mod_mask_t latched_mods; xkb_mod_mask_t latched_mods;
xkb_mod_mask_t locked_mods; xkb_mod_mask_t locked_mods;
struct xkb_state *state; struct xkb_state *state;
g_return_if_fail (META_IS_SEAT_IMPL (seat));
g_rw_lock_writer_lock (&seat->state_lock); g_rw_lock_writer_lock (&seat->state_lock);
state = seat->xkb; state = seat->xkb;
@ -3028,19 +3110,38 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat,
seat->layout_idx = idx; seat->layout_idx = idx;
g_rw_lock_writer_unlock (&seat->state_lock); g_rw_lock_writer_unlock (&seat->state_lock);
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
} }
/** /**
* meta_seat_impl_set_keyboard_numlock: (skip) * meta_seat_impl_set_keyboard_layout_index: (skip)
* @seat: the #ClutterSeat created by the evdev backend * @seat: the #ClutterSeat created by the evdev backend
* @numlock_set: TRUE to set NumLock ON, FALSE otherwise. * @idx: the xkb layout index to set
* *
* Sets the NumLock state on the backend's #xkb_state . * Sets the xkb layout index on the backend's #xkb_state .
*/ */
void void
meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat, meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat,
gboolean numlock_state) xkb_layout_index_t idx)
{ {
GTask *task;
g_return_if_fail (META_IS_SEAT_IMPL (seat));
task = g_task_new (seat, NULL, NULL, NULL);
g_task_set_task_data (task, GUINT_TO_POINTER (idx), NULL);
meta_seat_impl_run_input_task (seat, task,
(GSourceFunc) set_keyboard_layout_index);
g_object_unref (task);
}
static gboolean
set_keyboard_numlock (GTask *task)
{
MetaSeatImpl *seat = g_task_get_source_object (task);
gboolean numlock_state = GPOINTER_TO_UINT (g_task_get_task_data (task));
xkb_mod_mask_t depressed_mods; xkb_mod_mask_t depressed_mods;
xkb_mod_mask_t latched_mods; xkb_mod_mask_t latched_mods;
xkb_mod_mask_t locked_mods; xkb_mod_mask_t locked_mods;
@ -3049,8 +3150,6 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat,
struct xkb_keymap *xkb_keymap; struct xkb_keymap *xkb_keymap;
MetaKeymapNative *keymap; MetaKeymapNative *keymap;
g_return_if_fail (META_IS_SEAT_IMPL (seat));
g_rw_lock_writer_lock (&seat->state_lock); g_rw_lock_writer_lock (&seat->state_lock);
keymap = seat->keymap; keymap = seat->keymap;
@ -3079,6 +3178,31 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat,
meta_keymap_native_update (seat->keymap); meta_keymap_native_update (seat->keymap);
g_rw_lock_writer_unlock (&seat->state_lock); g_rw_lock_writer_unlock (&seat->state_lock);
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
/**
* meta_seat_impl_set_keyboard_numlock: (skip)
* @seat: the #ClutterSeat created by the evdev backend
* @numlock_set: TRUE to set NumLock ON, FALSE otherwise.
*
* Sets the NumLock state on the backend's #xkb_state .
*/
void
meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat,
gboolean numlock_state)
{
GTask *task;
g_return_if_fail (META_IS_SEAT_IMPL (seat));
task = g_task_new (seat, NULL, NULL, NULL);
g_task_set_task_data (task, GUINT_TO_POINTER (numlock_state), NULL);
meta_seat_impl_run_input_task (seat, task,
(GSourceFunc) set_keyboard_numlock);
g_object_unref (task);
} }
/** /**
@ -3118,22 +3242,62 @@ meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat)
return seat->barrier_manager; return seat->barrier_manager;
} }
void static gboolean
meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat, set_pointer_constraint (GTask *task)
MetaPointerConstraintImpl *impl)
{ {
MetaSeatImpl *seat = g_task_get_source_object (task);
MetaPointerConstraintImpl *impl = g_task_get_task_data (task);
if (g_set_object (&seat->pointer_constraint, impl)) if (g_set_object (&seat->pointer_constraint, impl))
{ {
if (impl) if (impl)
meta_pointer_constraint_impl_ensure_constrained (impl, seat->core_pointer); meta_pointer_constraint_impl_ensure_constrained (impl, seat->core_pointer);
} }
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
void
meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat,
MetaPointerConstraintImpl *impl)
{
GTask *task;
g_return_if_fail (META_IS_SEAT_IMPL (seat));
task = g_task_new (seat, NULL, NULL, NULL);
g_task_set_task_data (task, g_object_ref (impl), g_object_unref);
meta_seat_impl_run_input_task (seat, task,
(GSourceFunc) set_pointer_constraint);
g_object_unref (task);
}
static gboolean
set_viewports (GTask *task)
{
MetaSeatImpl *seat = g_task_get_source_object (task);
MetaViewportInfo *viewports = g_task_get_task_data (task);
g_set_object (&seat->viewports, viewports);
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
} }
void void
meta_seat_impl_set_viewports (MetaSeatImpl *seat, meta_seat_impl_set_viewports (MetaSeatImpl *seat,
MetaViewportInfo *viewports) MetaViewportInfo *viewports)
{ {
g_set_object (&seat->viewports, viewports); GTask *task;
g_return_if_fail (META_IS_SEAT_IMPL (seat));
task = g_task_new (seat, NULL, NULL, NULL);
g_task_set_task_data (task, g_object_ref (viewports), g_object_unref);
meta_seat_impl_run_input_task (seat, task,
(GSourceFunc) set_viewports);
g_object_unref (task);
} }
MetaSeatImpl * MetaSeatImpl *

View File

@ -54,6 +54,7 @@ struct _MetaSeatImpl
{ {
GObject parent_instance; GObject parent_instance;
GMainContext *input_context;
MetaSeatNative *seat; MetaSeatNative *seat;
char *seat_id; char *seat_id;
MetaEventSource *event_source; MetaEventSource *event_source;
@ -120,6 +121,10 @@ G_DECLARE_FINAL_TYPE (MetaSeatImpl, meta_seat_impl,
MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat, MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat,
const gchar *seat_id); const gchar *seat_id);
void meta_seat_impl_run_input_task (MetaSeatImpl *impl,
GTask *task,
GSourceFunc dispatch_func);
void meta_seat_impl_notify_key (MetaSeatImpl *seat, void meta_seat_impl_notify_key (MetaSeatImpl *seat,
ClutterInputDevice *device, ClutterInputDevice *device,
uint64_t time_us, uint64_t time_us,