From 94e1f8702dc281b0a4e84c8c742648b14e4ee610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 13 Sep 2022 18:25:25 +0200 Subject: [PATCH] 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: --- 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 0c58cd8ed..519097ff3 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 0a72583de..396732249 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 60608b6f6..f8624274c 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,