From 8177204ad14b2707cab3d4493d854a37bbeea9ba Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 12 Apr 2022 13:16:13 +0200 Subject: [PATCH] [Linux] fix theme updates on GNOME 42 Prefer `org.gnome.desktop.interface.color-scheme` for determining the UI color scheme. The new setting is available in GNOME 42 and later. https://blogs.gnome.org/alexm/2021/10/04/dark-style-preference/ Fixes: flutter/flutter#101438 --- shell/platform/linux/BUILD.gn | 5 ++- shell/platform/linux/fl_gnome_settings.cc | 35 ++++++++++++++---- .../platform/linux/fl_gnome_settings_test.cc | 27 ++++++++++++++ .../testing/gschemas/ubuntu-22.04.compiled | Bin 0 -> 36311 bytes 4 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 shell/platform/linux/testing/gschemas/ubuntu-22.04.compiled diff --git a/shell/platform/linux/BUILD.gn b/shell/platform/linux/BUILD.gn index a8c2a1c4023d2..f73bb2a46ce3c 100644 --- a/shell/platform/linux/BUILD.gn +++ b/shell/platform/linux/BUILD.gn @@ -180,7 +180,10 @@ test_fixtures("flutter_linux_fixtures") { copy("flutter_linux_gschemas") { testonly = true - sources = [ "testing/gschemas/ubuntu-20.04.compiled" ] + sources = [ + "testing/gschemas/ubuntu-20.04.compiled", + "testing/gschemas/ubuntu-22.04.compiled", + ] outputs = [ "$target_gen_dir/assets/{{source_name_part}}/gschemas.compiled" ] } diff --git a/shell/platform/linux/fl_gnome_settings.cc b/shell/platform/linux/fl_gnome_settings.cc index 977c4c47b780a..d56936b4af432 100644 --- a/shell/platform/linux/fl_gnome_settings.cc +++ b/shell/platform/linux/fl_gnome_settings.cc @@ -10,9 +10,11 @@ static constexpr char kDesktopInterfaceSchema[] = "org.gnome.desktop.interface"; static constexpr char kDesktopTextScalingFactorKey[] = "text-scaling-factor"; static constexpr char kDesktopClockFormatKey[] = "clock-format"; +static constexpr char kDesktopColorSchemeKey[] = "color-scheme"; static constexpr char kDesktopGtkThemeKey[] = "gtk-theme"; static constexpr char kClockFormat12Hour[] = "12h"; +static constexpr char kColorSchemePreferDark[] = "prefer-dark"; static constexpr char kGtkThemeDarkSuffix[] = "-dark"; static constexpr char kInterfaceSettings[] = "interface-settings"; @@ -47,17 +49,32 @@ static FlClockFormat fl_gnome_settings_get_clock_format(FlSettings* settings) { return clock_format; } +static bool has_setting(GSettings* settings, const gchar* key) { + g_autoptr(GSettingsSchema) schema = nullptr; + g_object_get(settings, "settings-schema", &schema, nullptr); + return g_settings_schema_has_key(schema, key); +} + static FlColorScheme fl_gnome_settings_get_color_scheme(FlSettings* settings) { FlGnomeSettings* self = FL_GNOME_SETTINGS(settings); FlColorScheme color_scheme = FL_COLOR_SCHEME_LIGHT; if (self->interface_settings != nullptr) { - // check whether org.gnome.desktop.interface.gtk-theme ends with "-dark" - g_autofree gchar* value = - g_settings_get_string(self->interface_settings, kDesktopGtkThemeKey); - if (g_str_has_suffix(value, kGtkThemeDarkSuffix)) { - color_scheme = FL_COLOR_SCHEME_DARK; + if (has_setting(self->interface_settings, kDesktopColorSchemeKey)) { + // org.gnome.desktop.interface.color-scheme in GNOME 42 and later + g_autofree gchar* value = g_settings_get_string(self->interface_settings, + kDesktopColorSchemeKey); + if (g_strcmp0(value, kColorSchemePreferDark) == 0) { + color_scheme = FL_COLOR_SCHEME_DARK; + } + } else { + // check whether org.gnome.desktop.interface.gtk-theme ends with "-dark" + g_autofree gchar* value = + g_settings_get_string(self->interface_settings, kDesktopGtkThemeKey); + if (g_str_has_suffix(value, kGtkThemeDarkSuffix)) { + color_scheme = FL_COLOR_SCHEME_DARK; + } } } return color_scheme; @@ -82,9 +99,11 @@ static void fl_gnome_settings_set_interface_settings(FlGnomeSettings* self, g_signal_connect_object(settings, "changed::clock-format", G_CALLBACK(fl_settings_emit_changed), self, G_CONNECT_SWAPPED); - g_signal_connect_object(settings, "changed::gtk-theme", - G_CALLBACK(fl_settings_emit_changed), self, - G_CONNECT_SWAPPED); + g_signal_connect_object( + settings, + has_setting(settings, kDesktopColorSchemeKey) ? "changed::color-scheme" + : "changed::gtk-theme", + G_CALLBACK(fl_settings_emit_changed), self, G_CONNECT_SWAPPED); g_signal_connect_object(settings, "changed::text-scaling-factor", G_CALLBACK(fl_settings_emit_changed), self, G_CONNECT_SWAPPED); diff --git a/shell/platform/linux/fl_gnome_settings_test.cc b/shell/platform/linux/fl_gnome_settings_test.cc index f4cd92e0ddafb..e1070ecda74d7 100644 --- a/shell/platform/linux/fl_gnome_settings_test.cc +++ b/shell/platform/linux/fl_gnome_settings_test.cc @@ -52,6 +52,33 @@ TEST_F(FlGnomeSettingsTest, ClockFormat) { EXPECT_EQ(fl_settings_get_clock_format(settings), FL_CLOCK_FORMAT_12H); } +TEST_F(FlGnomeSettingsTest, ColorScheme) { + g_autoptr(GSettings) interface_settings = + create_settings("ubuntu-22.04", "org.gnome.desktop.interface"); + g_settings_set_string(interface_settings, "color-scheme", "default"); + + g_autoptr(FlSettings) settings = FL_SETTINGS( + g_object_new(fl_gnome_settings_get_type(), "interface_settings", + interface_settings, nullptr)); + EXPECT_EQ(fl_settings_get_color_scheme(settings), FL_COLOR_SCHEME_LIGHT); + + flutter::testing::MockSignalHandler settings_changed(settings, "changed"); + EXPECT_SIGNAL(settings_changed).Times(1); + + g_settings_set_string(interface_settings, "color-scheme", "prefer-light"); + EXPECT_EQ(fl_settings_get_color_scheme(settings), FL_COLOR_SCHEME_LIGHT); + + EXPECT_SIGNAL(settings_changed).Times(1); + + g_settings_set_string(interface_settings, "color-scheme", "prefer-dark"); + EXPECT_EQ(fl_settings_get_color_scheme(settings), FL_COLOR_SCHEME_DARK); + + EXPECT_SIGNAL(settings_changed).Times(0); + + g_settings_set_string(interface_settings, "gtk-theme", "Yaru"); + EXPECT_EQ(fl_settings_get_color_scheme(settings), FL_COLOR_SCHEME_DARK); +} + TEST_F(FlGnomeSettingsTest, GtkTheme) { g_autoptr(GSettings) interface_settings = create_settings("ubuntu-20.04", "org.gnome.desktop.interface"); diff --git a/shell/platform/linux/testing/gschemas/ubuntu-22.04.compiled b/shell/platform/linux/testing/gschemas/ubuntu-22.04.compiled new file mode 100644 index 0000000000000000000000000000000000000000..a934f9291111096a44b52f3fc24ef05f4f32ffc7 GIT binary patch literal 36311 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 literal 0 HcmV?d00001