[mutter/wip/carlosg/input-thread: 18/43] backends/native: Make some MetaSeatImpl API "async"
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/carlosg/input-thread: 18/43] backends/native: Make some MetaSeatImpl API "async"
- Date: Fri, 27 Nov 2020 13:25:23 +0000 (UTC)
commit 6899e98e4fb7a756544c42607df446e481f080c0
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Aug 12 15:37:43 2020 +0200
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.
src/backends/native/meta-seat-impl.c | 250 +++++++++++++++++++++++++++++------
src/backends/native/meta-seat-impl.h | 5 +
2 files changed, 211 insertions(+), 44 deletions(-)
---
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
index a3cfef9d12..69be7c9762 100644
--- a/src/backends/native/meta-seat-impl.c
+++ b/src/backends/native/meta-seat-impl.c
@@ -137,6 +137,23 @@ void meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat_impl,
float *dy);
void meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat_impl);
+void
+meta_seat_impl_run_input_task (MetaSeatImpl *seat_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, seat_impl->input_context);
+ g_source_unref (source);
+}
+
void
meta_seat_impl_sync_leds (MetaSeatImpl *seat_impl)
{
@@ -2720,12 +2737,36 @@ meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl)
return g_object_ref (seat_impl->keymap);
}
+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
meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl,
int x,
int y)
{
- notify_absolute_motion (seat_impl->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_impl, NULL, NULL, NULL);
+ g_task_set_task_data (task, point, (GDestroyNotify) graphene_point_free);
+ meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) warp_pointer);
+ g_object_unref (task);
}
gboolean
@@ -2737,6 +2778,7 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl,
{
MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
gboolean retval = FALSE;
+ ClutterModifierType mods = 0;
g_rw_lock_reader_lock (&seat_impl->state_lock);
@@ -2756,8 +2798,8 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl,
coords->y = touch_state->coords.y;
}
- if (modifiers)
- *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb, 0);
+ if (seat_impl->xkb)
+ mods = meta_xkb_translate_modifiers (seat_impl->xkb, 0);
retval = TRUE;
}
@@ -2769,15 +2811,18 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl,
coords->y = device_native->pointer_y;
}
- if (modifiers)
+ if (seat_impl->xkb)
{
- *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb,
- seat_impl->button_state);
+ mods = meta_xkb_translate_modifiers (seat_impl->xkb,
+ seat_impl->button_state);
}
retval = TRUE;
}
+ if (modifiers)
+ *modifiers = mods;
+
out:
g_rw_lock_reader_unlock (&seat_impl->state_lock);
return retval;
@@ -2926,6 +2971,30 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl)
g_rw_lock_writer_unlock (&seat_impl->state_lock);
}
+static gboolean
+release_devices (GTask *task)
+{
+ MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+
+ if (seat_impl->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_impl->libinput);
+ process_events (seat_impl);
+
+ seat_impl->released = TRUE;
+ }
+
+ g_task_return_boolean (task, TRUE);
+
+ return G_SOURCE_REMOVE;
+}
+
/**
* meta_seat_impl_release_devices:
*
@@ -2939,18 +3008,38 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl)
void
meta_seat_impl_release_devices (MetaSeatImpl *seat_impl)
{
+ GTask *task;
+
+ g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+ task = g_task_new (seat_impl, NULL, NULL, NULL);
+ meta_seat_impl_run_input_task (seat_impl, task,
+ (GSourceFunc) release_devices);
+ g_object_unref (task);
+}
+
+static gboolean
+reclaim_devices (GTask *task)
+{
+ MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+
if (seat_impl->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");
- return;
+ libinput_resume (seat_impl->libinput);
+ meta_seat_impl_update_xkb_state (seat_impl);
+ process_events (seat_impl);
+
+ seat_impl->released = FALSE;
+ }
+ else
+ {
+ g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without "
+ "previous call to meta_seat_impl_release_devices");
}
- libinput_suspend (seat_impl->libinput);
- process_events (seat_impl);
+ g_task_return_boolean (task, TRUE);
- seat_impl->released = TRUE;
+ return G_SOURCE_REMOVE;
}
/**
@@ -2967,18 +3056,29 @@ meta_seat_impl_release_devices (MetaSeatImpl *seat_impl)
void
meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl)
{
- if (!seat_impl->released)
- {
- g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without "
- "previous call to meta_seat_impl_release_devices");
- return;
- }
+ GTask *task;
+
+ g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+ task = g_task_new (seat_impl, NULL, NULL, NULL);
+ meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) reclaim_devices);
+ g_object_unref (task);
+}
+
+static gboolean
+set_keyboard_map (GTask *task)
+{
+ MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+ struct xkb_keymap *xkb_keymap = g_task_get_task_data (task);
+ MetaKeymapNative *keymap;
+
+ keymap = seat_impl->keymap;
+ meta_keymap_native_set_keyboard_map (keymap, xkb_keymap);
- libinput_resume (seat_impl->libinput);
meta_seat_impl_update_xkb_state (seat_impl);
- process_events (seat_impl);
+ g_task_return_boolean (task, TRUE);
- seat_impl->released = FALSE;
+ return G_SOURCE_REMOVE;
}
/**
@@ -2995,35 +3095,29 @@ void
meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl,
struct xkb_keymap *xkb_keymap)
{
- MetaKeymapNative *keymap;
+ GTask *task;
g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
g_return_if_fail (xkb_keymap != NULL);
- keymap = seat_impl->keymap;
- meta_keymap_native_set_keyboard_map (keymap, xkb_keymap);
-
- meta_seat_impl_update_xkb_state (seat_impl);
+ task = g_task_new (seat_impl, NULL, NULL, NULL);
+ g_task_set_task_data (task,
+ xkb_keymap_ref (xkb_keymap),
+ (GDestroyNotify) xkb_keymap_unref);
+ meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) set_keyboard_map);
+ g_object_unref (task);
}
-/**
- * meta_seat_impl_set_keyboard_layout_index: (skip)
- * @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_impl,
- xkb_layout_index_t idx)
+static gboolean
+set_keyboard_layout_index (GTask *task)
{
+ MetaSeatImpl *seat_impl = 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 latched_mods;
xkb_mod_mask_t locked_mods;
struct xkb_state *state;
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
g_rw_lock_writer_lock (&seat_impl->state_lock);
state = seat_impl->xkb;
@@ -3038,8 +3132,35 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl,
seat_impl->layout_idx = idx;
g_rw_lock_writer_unlock (&seat_impl->state_lock);
+
+ g_task_return_boolean (task, TRUE);
+
+ return G_SOURCE_REMOVE;
+}
+
+/**
+ * meta_seat_impl_set_keyboard_layout_index: (skip)
+ * @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_impl,
+ xkb_layout_index_t idx)
+{
+ GTask *task;
+
+ g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+ task = g_task_new (seat_impl, NULL, NULL, NULL);
+ g_task_set_task_data (task, GUINT_TO_POINTER (idx), NULL);
+ meta_seat_impl_run_input_task (seat_impl, task,
+ (GSourceFunc) set_keyboard_layout_index);
+ g_object_unref (task);
}
+
/**
* meta_seat_impl_set_keyboard_repeat:
* @seat: the #ClutterSeat created by the evdev backend
@@ -3077,25 +3198,66 @@ meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat_impl)
return seat_impl->barrier_manager;
}
-void
-meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat_impl,
- MetaPointerConstraintImpl *constraint_impl)
+static gboolean
+set_pointer_constraint (GTask *task)
{
+ MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+ MetaPointerConstraintImpl *constraint_impl = g_task_get_task_data (task);
+
if (!g_set_object (&seat_impl->pointer_constraint, constraint_impl))
- return;
+ return G_SOURCE_REMOVE;
if (constraint_impl)
{
meta_pointer_constraint_impl_ensure_constrained (constraint_impl,
seat_impl->core_pointer);
}
+
+ g_task_return_boolean (task, TRUE);
+
+ return G_SOURCE_REMOVE;
+}
+
+void
+meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat,
+ MetaPointerConstraintImpl *constraint_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 (constraint_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
meta_seat_impl_set_viewports (MetaSeatImpl *seat_impl,
MetaViewportInfo *viewports)
{
- g_set_object (&seat_impl->viewports, viewports);
+ GTask *task;
+
+ g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+ task = g_task_new (seat_impl, NULL, NULL, NULL);
+ g_task_set_task_data (task, g_object_ref (viewports), g_object_unref);
+ meta_seat_impl_run_input_task (seat_impl, task,
+ (GSourceFunc) set_viewports);
+ g_object_unref (task);
}
MetaSeatImpl *
diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h
index 92d97b7328..30b52ffb0a 100644
--- a/src/backends/native/meta-seat-impl.h
+++ b/src/backends/native/meta-seat-impl.h
@@ -54,6 +54,7 @@ struct _MetaSeatImpl
{
GObject parent_instance;
+ GMainContext *input_context;
MetaSeatNative *seat_native;
char *seat_id;
MetaEventSource *event_source;
@@ -116,6 +117,10 @@ G_DECLARE_FINAL_TYPE (MetaSeatImpl, meta_seat_impl,
MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat_native,
const char *seat_id);
+void meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl,
+ GTask *task,
+ GSourceFunc dispatch_func);
+
void meta_seat_impl_notify_key (MetaSeatImpl *seat_impl,
ClutterInputDevice *device,
uint64_t time_us,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]