|  | // Copyright 2013 The Flutter Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "flutter/shell/platform/linux/fl_gnome_settings.h" | 
|  |  | 
|  | #include <gio/gio.h> | 
|  | #include <glib.h> | 
|  |  | 
|  | static constexpr char kDesktopInterfaceSchema[] = "org.gnome.desktop.interface"; | 
|  | static constexpr char kDesktopTextScalingFactorKey[] = "text-scaling-factor"; | 
|  | static constexpr char kDesktopClockFormatKey[] = "clock-format"; | 
|  | static constexpr char kDesktopGtkThemeKey[] = "gtk-theme"; | 
|  |  | 
|  | static constexpr char kClockFormat12Hour[] = "12h"; | 
|  | static constexpr char kGtkThemeDarkSuffix[] = "-dark"; | 
|  | static constexpr char kInterfaceSettings[] = "interface-settings"; | 
|  |  | 
|  | struct _FlGnomeSettings { | 
|  | GObject parent_instance; | 
|  |  | 
|  | GSettings* interface_settings; | 
|  | }; | 
|  |  | 
|  | enum { kProp0, kPropInterfaceSettings, kPropLast }; | 
|  |  | 
|  | static void fl_gnome_settings_iface_init(FlSettingsInterface* iface); | 
|  |  | 
|  | G_DEFINE_TYPE_WITH_CODE(FlGnomeSettings, | 
|  | fl_gnome_settings, | 
|  | G_TYPE_OBJECT, | 
|  | G_IMPLEMENT_INTERFACE(fl_settings_get_type(), | 
|  | fl_gnome_settings_iface_init)) | 
|  |  | 
|  | static FlClockFormat fl_gnome_settings_get_clock_format(FlSettings* settings) { | 
|  | FlGnomeSettings* self = FL_GNOME_SETTINGS(settings); | 
|  |  | 
|  | FlClockFormat clock_format = FL_CLOCK_FORMAT_24H; | 
|  |  | 
|  | if (self->interface_settings != nullptr) { | 
|  | g_autofree gchar* value = | 
|  | g_settings_get_string(self->interface_settings, kDesktopClockFormatKey); | 
|  | if (g_strcmp0(value, kClockFormat12Hour) == 0) { | 
|  | clock_format = FL_CLOCK_FORMAT_12H; | 
|  | } | 
|  | } | 
|  | return clock_format; | 
|  | } | 
|  |  | 
|  | 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; | 
|  | } | 
|  | } | 
|  | return color_scheme; | 
|  | } | 
|  |  | 
|  | static gboolean fl_gnome_settings_get_enable_animations(FlSettings* settings) { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | static gboolean fl_gnome_settings_get_high_contrast(FlSettings* settings) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | static gdouble fl_gnome_settings_get_text_scaling_factor(FlSettings* settings) { | 
|  | FlGnomeSettings* self = FL_GNOME_SETTINGS(settings); | 
|  |  | 
|  | gdouble scaling_factor = 1.0; | 
|  |  | 
|  | if (self->interface_settings != nullptr) { | 
|  | scaling_factor = g_settings_get_double(self->interface_settings, | 
|  | kDesktopTextScalingFactorKey); | 
|  | } | 
|  | return scaling_factor; | 
|  | } | 
|  |  | 
|  | static void fl_gnome_settings_set_interface_settings(FlGnomeSettings* self, | 
|  | GSettings* settings) { | 
|  | g_return_if_fail(G_IS_SETTINGS(settings)); | 
|  |  | 
|  | 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, "changed::text-scaling-factor", | 
|  | G_CALLBACK(fl_settings_emit_changed), self, | 
|  | G_CONNECT_SWAPPED); | 
|  |  | 
|  | self->interface_settings = G_SETTINGS(g_object_ref(settings)); | 
|  | } | 
|  |  | 
|  | static void fl_gnome_settings_set_property(GObject* object, | 
|  | guint prop_id, | 
|  | const GValue* value, | 
|  | GParamSpec* pspec) { | 
|  | FlGnomeSettings* self = FL_GNOME_SETTINGS(object); | 
|  | switch (prop_id) { | 
|  | case kPropInterfaceSettings: | 
|  | fl_gnome_settings_set_interface_settings( | 
|  | self, G_SETTINGS(g_value_get_object(value))); | 
|  | break; | 
|  | default: | 
|  | G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | static void fl_gnome_settings_dispose(GObject* object) { | 
|  | FlGnomeSettings* self = FL_GNOME_SETTINGS(object); | 
|  |  | 
|  | g_clear_object(&self->interface_settings); | 
|  |  | 
|  | G_OBJECT_CLASS(fl_gnome_settings_parent_class)->dispose(object); | 
|  | } | 
|  |  | 
|  | static void fl_gnome_settings_class_init(FlGnomeSettingsClass* klass) { | 
|  | GObjectClass* object_class = G_OBJECT_CLASS(klass); | 
|  | object_class->dispose = fl_gnome_settings_dispose; | 
|  | object_class->set_property = fl_gnome_settings_set_property; | 
|  |  | 
|  | g_object_class_install_property( | 
|  | object_class, kPropInterfaceSettings, | 
|  | g_param_spec_object( | 
|  | kInterfaceSettings, kInterfaceSettings, kDesktopInterfaceSchema, | 
|  | g_settings_get_type(), | 
|  | static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | | 
|  | G_PARAM_STATIC_STRINGS))); | 
|  | } | 
|  |  | 
|  | static void fl_gnome_settings_iface_init(FlSettingsInterface* iface) { | 
|  | iface->get_clock_format = fl_gnome_settings_get_clock_format; | 
|  | iface->get_color_scheme = fl_gnome_settings_get_color_scheme; | 
|  | iface->get_enable_animations = fl_gnome_settings_get_enable_animations; | 
|  | iface->get_high_contrast = fl_gnome_settings_get_high_contrast; | 
|  | iface->get_text_scaling_factor = fl_gnome_settings_get_text_scaling_factor; | 
|  | } | 
|  |  | 
|  | static void fl_gnome_settings_init(FlGnomeSettings* self) {} | 
|  |  | 
|  | static GSettings* create_settings(const gchar* schema_id) { | 
|  | GSettings* settings = nullptr; | 
|  | GSettingsSchemaSource* source = g_settings_schema_source_get_default(); | 
|  | if (source != nullptr) { | 
|  | g_autoptr(GSettingsSchema) schema = | 
|  | g_settings_schema_source_lookup(source, schema_id, TRUE); | 
|  | if (schema != nullptr) { | 
|  | settings = g_settings_new_full(schema, nullptr, nullptr); | 
|  | } | 
|  | } | 
|  | return settings; | 
|  | } | 
|  |  | 
|  | FlSettings* fl_gnome_settings_new() { | 
|  | g_autoptr(GSettings) interface_settings = | 
|  | create_settings(kDesktopInterfaceSchema); | 
|  | return FL_SETTINGS(g_object_new(fl_gnome_settings_get_type(), | 
|  | kInterfaceSettings, interface_settings, | 
|  | nullptr)); | 
|  | } |