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 0000000000000..a934f92911110 Binary files /dev/null and b/shell/platform/linux/testing/gschemas/ubuntu-22.04.compiled differ