backend: Dispatch initial burst of events synchronously on init
This will consist of device-added events, meaning before init finishes, we can derive some state that depends on the set of input devices available on startup, such as cursor visibility. This avoids cursor visibility switching between hidden and visibility during startup. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3070>
This commit is contained in:
parent
27606cf1fb
commit
49e6ce459c
@ -688,7 +688,7 @@ clutter_stage_compress_motion (ClutterStage *stage,
|
||||
event->motion.dy_unaccel = dy_unaccel + dst_dy_unaccel;
|
||||
}
|
||||
|
||||
void
|
||||
CLUTTER_EXPORT void
|
||||
_clutter_stage_process_queued_events (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
|
@ -154,6 +154,8 @@ struct _MetaBackendPrivate
|
||||
GList *gpus;
|
||||
GList *hw_cursor_inhibitors;
|
||||
|
||||
gboolean in_init;
|
||||
|
||||
guint device_update_idle_id;
|
||||
|
||||
ClutterInputDevice *current_device;
|
||||
@ -422,8 +424,9 @@ on_device_added (ClutterSeat *seat,
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (device_type == CLUTTER_TOUCHSCREEN_DEVICE ||
|
||||
device_type == CLUTTER_POINTER_DEVICE)
|
||||
if (!priv->in_init &&
|
||||
(device_type == CLUTTER_TOUCHSCREEN_DEVICE ||
|
||||
device_type == CLUTTER_POINTER_DEVICE))
|
||||
{
|
||||
meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker,
|
||||
determine_hotplug_pointer_visibility (seat));
|
||||
@ -446,6 +449,8 @@ on_device_removed (ClutterSeat *seat,
|
||||
MetaBackend *backend = META_BACKEND (user_data);
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
g_warn_if_fail (!priv->in_init);
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) ==
|
||||
CLUTTER_INPUT_MODE_LOGICAL)
|
||||
return;
|
||||
@ -1032,6 +1037,8 @@ update_pointer_visibility_from_event (MetaBackend *backend,
|
||||
ClutterInputDeviceType device_type;
|
||||
uint32_t time_ms;
|
||||
|
||||
g_warn_if_fail (!priv->in_init);
|
||||
|
||||
device = clutter_event_get_source_device (event);
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
time_ms = clutter_event_get_time (event);
|
||||
@ -1063,6 +1070,28 @@ update_pointer_visibility_from_event (MetaBackend *backend,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dispatch_clutter_event (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
ClutterEvent *event;
|
||||
|
||||
event = clutter_event_get ();
|
||||
if (event)
|
||||
{
|
||||
g_warn_if_fail (!priv->in_init ||
|
||||
event->type == CLUTTER_DEVICE_ADDED);
|
||||
|
||||
event->any.stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
clutter_do_event (event);
|
||||
meta_backend_update_from_event (backend, event);
|
||||
clutter_event_free (event);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Mutter is responsible for pulling events off the X queue, so Clutter
|
||||
* doesn't need (and shouldn't) run its normal event source which polls
|
||||
* the X fd, but we do have to deal with dispatching events that accumulate
|
||||
@ -1095,16 +1124,8 @@ clutter_source_dispatch (GSource *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBackendSource *backend_source = (MetaBackendSource *) source;
|
||||
ClutterEvent *event = clutter_event_get ();
|
||||
|
||||
if (event)
|
||||
{
|
||||
event->any.stage =
|
||||
CLUTTER_STAGE (meta_backend_get_stage (backend_source->backend));
|
||||
clutter_do_event (event);
|
||||
meta_backend_update_from_event (backend_source->backend, event);
|
||||
clutter_event_free (event);
|
||||
}
|
||||
dispatch_clutter_event (backend_source->backend);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1205,6 +1226,15 @@ meta_backend_initable_init (GInitable *initable,
|
||||
|
||||
meta_backend_post_init (backend);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (!dispatch_clutter_event (backend))
|
||||
break;
|
||||
}
|
||||
_clutter_stage_process_queued_events (CLUTTER_STAGE (priv->stage));
|
||||
|
||||
priv->in_init = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1217,6 +1247,9 @@ initable_iface_init (GInitableIface *initable_iface)
|
||||
static void
|
||||
meta_backend_init (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
priv->in_init = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1708,8 +1741,12 @@ void
|
||||
meta_backend_update_from_event (MetaBackend *backend,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
update_last_device_from_event (backend, event);
|
||||
update_pointer_visibility_from_event (backend, event);
|
||||
|
||||
if (!priv->in_init)
|
||||
update_pointer_visibility_from_event (backend, event);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2841,6 +2841,8 @@ init_libinput (MetaSeatImpl *seat_impl,
|
||||
|
||||
seat_impl->libinput = libinput;
|
||||
|
||||
process_events (seat_impl);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2877,18 +2879,6 @@ input_thread (MetaSeatImpl *seat_impl)
|
||||
NULL,
|
||||
(GDestroyNotify) meta_device_file_release);
|
||||
|
||||
if (!(seat_impl->flags & META_SEAT_NATIVE_FLAG_NO_LIBINPUT))
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!init_libinput (seat_impl, &error))
|
||||
{
|
||||
g_critical ("Failed to initialize seat: %s", error->message);
|
||||
seat_impl->input_thread_initialized = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
seat_impl->input_settings = meta_input_settings_native_new_in_impl (seat_impl);
|
||||
g_signal_connect_object (seat_impl->input_settings, "kbd-a11y-changed",
|
||||
G_CALLBACK (kbd_a11y_changed_cb), seat_impl, 0);
|
||||
@ -2912,6 +2902,18 @@ input_thread (MetaSeatImpl *seat_impl)
|
||||
if (meta_input_settings_maybe_restore_numlock_state (seat_impl->input_settings))
|
||||
meta_seat_impl_set_keyboard_numlock_in_impl (seat_impl, TRUE);
|
||||
|
||||
if (!(seat_impl->flags & META_SEAT_NATIVE_FLAG_NO_LIBINPUT))
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!init_libinput (seat_impl, &error))
|
||||
{
|
||||
g_critical ("Failed to initialize seat: %s", error->message);
|
||||
seat_impl->input_thread_initialized = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
seat_impl->has_touchscreen = has_touchscreen (seat_impl);
|
||||
seat_impl->has_tablet_switch = has_tablet_switch (seat_impl);
|
||||
update_touch_mode (seat_impl);
|
||||
|
Loading…
Reference in New Issue
Block a user