[gnome-control-center/rename-app-icons: 1/2] user-accounts: Prevent freeze caused by external cameras



commit 0db6ed9af38a8f1668b8713a0ef07a5d309023a1
Author: Ondrej Holy <oholy redhat com>
Date:   Fri Oct 20 16:19:05 2017 +0200

    user-accounts: Prevent freeze caused by external cameras
    
    cheese_camera_device_monitor_new freezes the whole panel when opening
    for a couple of seconds if external camera is connected. This is not
    acceptable. Probably it is bug in kernel. Let's use GAsyncInitable if
    available.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=783789

 panels/user-accounts/um-photo-dialog.c | 54 +++++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 7 deletions(-)
---
diff --git a/panels/user-accounts/um-photo-dialog.c b/panels/user-accounts/um-photo-dialog.c
index 7fdda4180..3a203c234 100644
--- a/panels/user-accounts/um-photo-dialog.c
+++ b/panels/user-accounts/um-photo-dialog.c
@@ -52,6 +52,8 @@ struct _UmPhotoDialog {
 
 #ifdef HAVE_CHEESE
         CheeseCameraDeviceMonitor *monitor;
+        GCancellable *cancellable;
+        GtkWidget *take_photo_menuitem;
         guint num_cameras;
 #endif /* HAVE_CHEESE */
 
@@ -370,6 +372,30 @@ create_face_widget (gpointer item,
         return image;
 }
 
+static void
+setup_cheese_camera_device_monitor (UmPhotoDialog *um)
+{
+        g_signal_connect (G_OBJECT (um->monitor), "added", G_CALLBACK (device_added), um);
+        g_signal_connect (G_OBJECT (um->monitor), "removed", G_CALLBACK (device_removed), um);
+        cheese_camera_device_monitor_coldplug (um->monitor);
+}
+
+static void
+cheese_camera_device_monitor_new_cb (GObject *source,
+                                     GAsyncResult *result,
+                                     gpointer user_data)
+{
+        UmPhotoDialog *um = user_data;
+        GObject *ret;
+
+        ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, NULL);
+        if (ret == NULL)
+                return;
+
+        um->monitor = CHEESE_CAMERA_DEVICE_MONITOR (ret);
+        setup_cheese_camera_device_monitor (um);
+}
+
 static void
 setup_photo_popup (UmPhotoDialog *um)
 {
@@ -422,12 +448,22 @@ setup_photo_popup (UmPhotoDialog *um)
 #ifdef HAVE_CHEESE
         gtk_widget_set_visible (um->take_picture_button, TRUE);
 
-        um->monitor = cheese_camera_device_monitor_new ();
-        g_signal_connect (G_OBJECT (um->monitor), "added",
-                          G_CALLBACK (device_added), um);
-        g_signal_connect (G_OBJECT (um->monitor), "removed",
-                          G_CALLBACK (device_removed), um);
-        cheese_camera_device_monitor_coldplug (um->monitor);
+        /* Initialize asynchronously if possible in order to prevent freeze when opening. */
+        if (G_TYPE_IS_ASYNC_INITABLE (CHEESE_TYPE_CAMERA_DEVICE_MONITOR))
+        {
+                um->cancellable = g_cancellable_new ();
+                g_async_initable_new_async (CHEESE_TYPE_CAMERA_DEVICE_MONITOR,
+                                            G_PRIORITY_DEFAULT,
+                                            um->cancellable,
+                                            cheese_camera_device_monitor_new_cb,
+                                            um,
+                                            NULL);
+        }
+        else
+        {
+                um->monitor = cheese_camera_device_monitor_new ();
+                setup_cheese_camera_device_monitor (um);
+        }
 #endif /* HAVE_CHEESE */
 }
 
@@ -486,7 +522,11 @@ um_photo_dialog_dispose (GObject *object)
 
         g_clear_object (&um->thumb_factory);
 #ifdef HAVE_CHEESE
-        g_clear_object (&um->monitor);
+        g_cancellable_cancel (um->cancellable);
+        g_clear_object (&um->cancellable);
+
+        if (um->monitor)
+                g_object_unref (um->monitor);
 #endif
         g_clear_object (&um->user);
 


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