| // 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)); |
| } |