[mutter] backends: rate-filter the emission of MetaBackend::last-device-changed signal



commit 741dd674f6b488a123e96bfc109acaa9f5ad1235
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Feb 26 00:45:50 2016 +0100

    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

 src/backends/meta-backend.c |   60 +++++++++++++++++++++++++++++++-----------
 1 files changed, 44 insertions(+), 16 deletions(-)
---
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index e4ef6e3..93c8ad3 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -64,6 +64,8 @@ struct _MetaBackendPrivate
   MetaInputSettings *input_settings;
 
   ClutterActor *stage;
+
+  guint device_update_idle_id;
 };
 typedef struct _MetaBackendPrivate MetaBackendPrivate;
 
@@ -78,6 +80,9 @@ meta_backend_finalize (GObject *object)
   g_clear_object (&priv->monitor_manager);
   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_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
@@ -517,12 +522,44 @@ meta_backend_get_stage (MetaBackend *backend)
   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
 meta_backend_update_last_device (MetaBackend *backend,
                                  int          device_id)
 {
-  ClutterInputDeviceType device_type;
-  MetaCursorTracker *cursor_tracker;
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
   ClutterDeviceManager *manager;
   ClutterInputDevice *device;
 
@@ -536,23 +573,14 @@ meta_backend_update_last_device (MetaBackend *backend,
       clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
     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;
-  g_signal_emit_by_name (backend, "last-device-changed", device_id);
 
-  if (device_type == CLUTTER_KEYBOARD_DEVICE)
-    return;
-
-  switch (device_type)
+  if (priv->device_update_idle_id == 0)
     {
-    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;
+      priv->device_update_idle_id =
+        g_idle_add ((GSourceFunc) update_last_device, backend);
+      g_source_set_name_by_id (priv->device_update_idle_id,
+                               "[mutter] update_last_device");
     }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]