[mutter] color: Handle profiles not initializing succesfully



commit 94e1f8702dc281b0a4e84c8c742648b14e4ee610
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Tue Sep 13 18:25:25 2022 +0200

    color: Handle profiles not initializing succesfully
    
    We might fail with some part of the color profile construction and
    initialization. For example there might be a system wide profile with
    the same ID as one we attempt to add from a local ICC directory. When
    this happens, we should drop these profiles, and use the ones from the
    system instead.
    
    Profiles may fail to initialize for other reasons too, e.g.
    unpredictable colord errors, or other I/O issues.
    
    Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2429
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2622>

 src/backends/meta-color-device.c  |  9 +++++++++
 src/backends/meta-color-profile.c | 38 ++++++++++++++++++++++++++------------
 src/backends/meta-color-store.c   |  8 ++++++++
 3 files changed, 43 insertions(+), 12 deletions(-)
---
diff --git a/src/backends/meta-color-device.c b/src/backends/meta-color-device.c
index 0c58cd8ed2..519097ff37 100644
--- a/src/backends/meta-color-device.c
+++ b/src/backends/meta-color-device.c
@@ -396,8 +396,17 @@ on_cd_device_connected (GObject      *source_object,
 
 static void
 on_profile_ready (MetaColorProfile *color_profile,
+                  gboolean          success,
                   MetaColorDevice  *color_device)
 {
+  if (!success)
+    {
+      g_clear_object (&color_device->device_profile);
+      g_cancellable_cancel (color_device->cancellable);
+      meta_color_device_notify_ready (color_device, FALSE);
+      return;
+    }
+
   color_device->pending_state &= ~PENDING_PROFILE_READY;
   maybe_finish_setup (color_device);
 }
diff --git a/src/backends/meta-color-profile.c b/src/backends/meta-color-profile.c
index 0a72583de8..396732249e 100644
--- a/src/backends/meta-color-profile.c
+++ b/src/backends/meta-color-profile.c
@@ -165,7 +165,8 @@ meta_color_profile_class_init (MetaColorProfileClass *klass)
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_LAST, 0,
                   NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
+                  G_TYPE_NONE, 1,
+                  G_TYPE_BOOLEAN);
 }
 
 static void
@@ -190,18 +191,20 @@ on_cd_profile_connected (GObject      *source_object,
       g_warning ("Failed to connect to colord profile %s: %s",
                  color_profile->cd_profile_id,
                  error->message);
-    }
-  else
-    {
-      g_warn_if_fail (g_strcmp0 (cd_profile_get_id (cd_profile),
-                                 color_profile->cd_profile_id) == 0);
 
-      meta_topic (META_DEBUG_COLOR, "Color profile '%s' connected",
-                  color_profile->cd_profile_id);
+      color_profile->is_ready = TRUE;
+      g_signal_emit (color_profile, signals[READY], 0, FALSE);
+      return;
     }
 
+  g_warn_if_fail (g_strcmp0 (cd_profile_get_id (cd_profile),
+                             color_profile->cd_profile_id) == 0);
+
+  meta_topic (META_DEBUG_COLOR, "Color profile '%s' connected",
+              color_profile->cd_profile_id);
+
   color_profile->is_ready = TRUE;
-  g_signal_emit (color_profile, signals[READY], 0);
+  g_signal_emit (color_profile, signals[READY], 0, TRUE);
 }
 
 static void
@@ -220,10 +223,21 @@ on_cd_profile_created (GObject      *source_object,
       if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
         return;
 
-      g_warning ("Failed to create colord color profile: %s", error->message);
+      if (g_error_matches (error,
+                           CD_CLIENT_ERROR, CD_CLIENT_ERROR_ALREADY_EXISTS))
+        {
+          meta_topic (META_DEBUG_COLOR, "Tried to create duplicate profile %s",
+                      color_profile->cd_profile_id);
+        }
+      else
+        {
+          g_warning ("Failed to create colord color profile %s: %s",
+                     color_profile->cd_profile_id,
+                     error->message);
+        }
 
       color_profile->is_ready = TRUE;
-      g_signal_emit (color_profile, signals[READY], 0);
+      g_signal_emit (color_profile, signals[READY], 0, FALSE);
       return;
     }
 
@@ -299,7 +313,7 @@ notify_ready_idle (gpointer user_data)
 
   color_profile->notify_ready_id = 0;
   color_profile->is_ready = TRUE;
-  g_signal_emit (color_profile, signals[READY], 0);
+  g_signal_emit (color_profile, signals[READY], 0, TRUE);
 
   return G_SOURCE_REMOVE;
 }
diff --git a/src/backends/meta-color-store.c b/src/backends/meta-color-store.c
index 60608b6f64..f8624274c1 100644
--- a/src/backends/meta-color-store.c
+++ b/src/backends/meta-color-store.c
@@ -87,8 +87,16 @@ meta_color_store_init (MetaColorStore *color_store)
 
 static void
 on_directory_profile_ready (MetaColorProfile *color_profile,
+                            gboolean          success,
                             MetaColorStore   *color_store)
 {
+  if (!success)
+    {
+      g_hash_table_remove (color_store->pending_local_profiles,
+                           meta_color_profile_get_file_path (color_profile));
+      return;
+    }
+
   g_object_ref (color_profile);
 
   if (!g_hash_table_steal (color_store->pending_local_profiles,


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