backends: rate-filter the emission of MetaBackend::last-device-changed signal
It indirectly triggers expensive operations in gnome-shell (js/ui/keyboard.js), which turns out too expensive if we happen to operate the shell simultaneously with 2 devices that will trigger the operations there. So just rate limit the signal emission, defer to an idle and just emit the last device gotten. Worst that will happen is that we may possibly emit the signal on the same device consecutively. https://bugzilla.gnome.org/show_bug.cgi?id=753527
This commit is contained in:
parent
821d737e2c
commit
741dd674f6
@ -64,6 +64,8 @@ struct _MetaBackendPrivate
|
|||||||
MetaInputSettings *input_settings;
|
MetaInputSettings *input_settings;
|
||||||
|
|
||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
|
|
||||||
|
guint device_update_idle_id;
|
||||||
};
|
};
|
||||||
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
||||||
|
|
||||||
@ -78,6 +80,9 @@ meta_backend_finalize (GObject *object)
|
|||||||
g_clear_object (&priv->monitor_manager);
|
g_clear_object (&priv->monitor_manager);
|
||||||
g_clear_object (&priv->input_settings);
|
g_clear_object (&priv->input_settings);
|
||||||
|
|
||||||
|
if (priv->device_update_idle_id)
|
||||||
|
g_source_remove (priv->device_update_idle_id);
|
||||||
|
|
||||||
g_hash_table_destroy (backend->device_monitors);
|
g_hash_table_destroy (backend->device_monitors);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||||
@ -517,12 +522,44 @@ meta_backend_get_stage (MetaBackend *backend)
|
|||||||
return priv->stage;
|
return priv->stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
update_last_device (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
ClutterInputDeviceType device_type;
|
||||||
|
ClutterDeviceManager *manager;
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
|
||||||
|
priv->device_update_idle_id = 0;
|
||||||
|
manager = clutter_device_manager_get_default ();
|
||||||
|
device = clutter_device_manager_get_device (manager,
|
||||||
|
backend->current_device_id);
|
||||||
|
device_type = clutter_input_device_get_device_type (device);
|
||||||
|
|
||||||
|
g_signal_emit_by_name (backend, "last-device-changed",
|
||||||
|
backend->current_device_id);
|
||||||
|
|
||||||
|
switch (device_type)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEYBOARD_DEVICE:
|
||||||
|
break;
|
||||||
|
case CLUTTER_TOUCHSCREEN_DEVICE:
|
||||||
|
meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_backend_update_last_device (MetaBackend *backend,
|
meta_backend_update_last_device (MetaBackend *backend,
|
||||||
int device_id)
|
int device_id)
|
||||||
{
|
{
|
||||||
ClutterInputDeviceType device_type;
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
MetaCursorTracker *cursor_tracker;
|
|
||||||
ClutterDeviceManager *manager;
|
ClutterDeviceManager *manager;
|
||||||
ClutterInputDevice *device;
|
ClutterInputDevice *device;
|
||||||
|
|
||||||
@ -536,23 +573,14 @@ meta_backend_update_last_device (MetaBackend *backend,
|
|||||||
clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
device_type = clutter_input_device_get_device_type (device);
|
|
||||||
|
|
||||||
cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
|
||||||
backend->current_device_id = device_id;
|
backend->current_device_id = device_id;
|
||||||
g_signal_emit_by_name (backend, "last-device-changed", device_id);
|
|
||||||
|
|
||||||
if (device_type == CLUTTER_KEYBOARD_DEVICE)
|
if (priv->device_update_idle_id == 0)
|
||||||
return;
|
|
||||||
|
|
||||||
switch (device_type)
|
|
||||||
{
|
{
|
||||||
case CLUTTER_TOUCHSCREEN_DEVICE:
|
priv->device_update_idle_id =
|
||||||
meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
|
g_idle_add ((GSourceFunc) update_last_device, backend);
|
||||||
break;
|
g_source_set_name_by_id (priv->device_update_idle_id,
|
||||||
default:
|
"[mutter] update_last_device");
|
||||||
meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user