[gnome-control-center/gnome-3-28] user-accounts: Prevent freeze caused by external cameras



commit 61bf17467d00bc9f8ce3f27bdc2c9f0a162e6825
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.
    
    Bump the cheese dependency accordingly.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=783789

 meson.build                            |  2 +-
 panels/user-accounts/um-photo-dialog.c | 42 +++++++++++++++++++++++++++++-----
 2 files changed, 37 insertions(+), 7 deletions(-)
---
diff --git a/meson.build b/meson.build
index bb1d2f15a..b69580252 100644
--- a/meson.build
+++ b/meson.build
@@ -146,7 +146,7 @@ if enable_cheese
 
   cheese_deps = [
     clutter_gtk_dep,
-    dependency('cheese'),
+    dependency('cheese', version: '>= 3.28.0'),
     dependency('cheese-gtk', version: '>= 3.5.91')
   ]
 endif
diff --git a/panels/user-accounts/um-photo-dialog.c b/panels/user-accounts/um-photo-dialog.c
index 7072699ce..66b236057 100644
--- a/panels/user-accounts/um-photo-dialog.c
+++ b/panels/user-accounts/um-photo-dialog.c
@@ -52,6 +52,7 @@ struct _UmPhotoDialog {
 
 #ifdef HAVE_CHEESE
         CheeseCameraDeviceMonitor *monitor;
+        GCancellable *cancellable;
         guint num_cameras;
 #endif /* HAVE_CHEESE */
 
@@ -370,6 +371,32 @@ create_face_widget (gpointer item,
         return image;
 }
 
+#ifdef HAVE_CHEESE
+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);
+}
+#endif /* HAVE_CHEESE */
+
 static void
 setup_photo_popup (UmPhotoDialog *um)
 {
@@ -445,12 +472,13 @@ 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);
+        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);
 #endif /* HAVE_CHEESE */
 }
 
@@ -509,6 +537,8 @@ um_photo_dialog_dispose (GObject *object)
 
         g_clear_object (&um->thumb_factory);
 #ifdef HAVE_CHEESE
+        g_cancellable_cancel (um->cancellable);
+        g_clear_object (&um->cancellable);
         g_clear_object (&um->monitor);
 #endif
         g_clear_object (&um->user);


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