[gnome-initial-setup/61-cheesecameradevicemonitor-may-hang-account-page-during-initialization] account: Prevent freeze caused by CheeseCameraDeviceMonitor



commit 09ba650a4ec0a023398f3e720ae6fa42823f5d73
Author: Ondřej Holý <oholy redhat com>
Date:   Thu Jan 16 21:11:56 2020 +0000

    account: Prevent freeze caused by CheeseCameraDeviceMonitor
    
    cheese_camera_device_monitor_new may freeze the whole panel when
    opening for a couple of seconds, or forever in certain cases. This
    is not acceptable. Let's use GAsyncInitable as it is done in g-c-c.
    
    Bump the cheese dependency accordingly.
    
    Updated by Will Thompson for Meson port & to resolve a couple of other
    conflicts. In passing, this patch resolves an issue where the “Take a
    Photo” button was shown on machines with no webcams when compiled with
    Cheese support; when clicked, a gigantic "error" stock icon was shown.
    
    https://gitlab.gnome.org/GNOME/gnome-initial-setup/issues/61
    
    Signed-off-by: Will Thompson <will willthompson co uk>

 .../pages/account/um-photo-dialog.c                | 41 +++++++++++++++++-----
 meson.build                                        |  2 +-
 2 files changed, 34 insertions(+), 9 deletions(-)
---
diff --git a/gnome-initial-setup/pages/account/um-photo-dialog.c 
b/gnome-initial-setup/pages/account/um-photo-dialog.c
index e1d1ad3..9e87f0b 100644
--- a/gnome-initial-setup/pages/account/um-photo-dialog.c
+++ b/gnome-initial-setup/pages/account/um-photo-dialog.c
@@ -50,6 +50,7 @@ struct _UmPhotoDialog {
 
 #ifdef HAVE_CHEESE
         CheeseCameraDeviceMonitor *monitor;
+        GCancellable *cancellable;
         guint num_cameras;
 #endif /* HAVE_CHEESE */
 
@@ -134,6 +135,29 @@ device_removed (CheeseCameraDeviceMonitor *monitor,
         update_photo_menu_status (um);
 }
 
+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
@@ -261,14 +285,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 */
 }
 
@@ -357,6 +380,8 @@ um_photo_dialog_dispose (GObject *object)
 #ifdef HAVE_CHEESE
         UmPhotoDialog *um = UM_PHOTO_DIALOG (object);
 
+        g_cancellable_cancel (um->cancellable);
+        g_clear_object (&um->cancellable);
         g_clear_object (&um->monitor);
 #endif
 
diff --git a/meson.build b/meson.build
index 9af4cee..ed7240c 100644
--- a/meson.build
+++ b/meson.build
@@ -44,7 +44,7 @@ endif
 
 # Needed for the 'account' page
 cheese_dep = dependency ('cheese',
-                         version: '>= 3.3.5',
+                         version: '>= 3.28',
                          required: get_option('cheese'))
 cheese_gtk_dep = dependency ('cheese-gtk',
                          version: '>= 3.3.5',


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