Advertisement
Guest User

adw-style-manager-new.c

a guest
Oct 6th, 2023
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.75 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2021 Purism SPC
  3.  *
  4.  * SPDX-License-Identifier: LGPL-2.1-or-later
  5.  *
  6.  * Author: Alice Mikhaylenko <alice.mikhaylenko@puri.sm>
  7.  */
  8.  
  9. #include "config.h"
  10.  
  11. #include "adw-style-manager-private.h"
  12.  
  13. #include "adw-main-private.h"
  14. #include "adw-settings-private.h"
  15. #include <gtk/gtk.h>
  16.  
  17. #define SWITCH_DURATION 250
  18.  
  19. /**
  20.  * AdwColorScheme:
  21.  * @ADW_COLOR_SCHEME_DEFAULT: Inherit the parent color-scheme. When set on the
  22.  *   `AdwStyleManager` returned by [func@StyleManager.get_default], it's
  23.  *   equivalent to `ADW_COLOR_SCHEME_PREFER_LIGHT`.
  24.  * @ADW_COLOR_SCHEME_FORCE_LIGHT: Always use light appearance.
  25.  * @ADW_COLOR_SCHEME_PREFER_LIGHT: Use light appearance unless the system
  26.  *   prefers dark colors.
  27.  * @ADW_COLOR_SCHEME_PREFER_DARK: Use dark appearance unless the system prefers
  28.  *   prefers light colors.
  29.  * @ADW_COLOR_SCHEME_FORCE_DARK: Always use dark appearance.
  30.  *
  31.  * Application color schemes for [property@StyleManager:color-scheme].
  32.  */
  33.  
  34. /**
  35.  * AdwStyleManager:
  36.  *
  37.  * A class for managing application-wide styling.
  38.  *
  39.  * `AdwStyleManager` provides a way to query and influence the application
  40.  * styles, such as whether to use dark or high contrast appearance.
  41.  *
  42.  * It allows to set the color scheme via the
  43.  * [property@StyleManager:color-scheme] property, and to query the current
  44.  * appearance, as well as whether a system-wide color scheme preference exists.
  45.  */
  46.  
  47. struct _AdwStyleManager
  48. {
  49.   GObject parent_instance;
  50.  
  51.   GdkDisplay *display;
  52.   AdwSettings *settings;
  53.   GtkCssProvider *provider;
  54.   GtkCssProvider *colors_provider;
  55.  
  56.   AdwColorScheme color_scheme;
  57.   gboolean dark;
  58.   gboolean setting_dark;
  59.  
  60.   GtkCssProvider *animations_provider;
  61.   guint animation_timeout_id;
  62. };
  63.  
  64. G_DEFINE_FINAL_TYPE (AdwStyleManager, adw_style_manager, G_TYPE_OBJECT);
  65.  
  66. enum {
  67.   PROP_0,
  68.   PROP_DISPLAY,
  69.   PROP_COLOR_SCHEME,
  70.   PROP_SYSTEM_SUPPORTS_COLOR_SCHEMES,
  71.   PROP_DARK,
  72.   PROP_HIGH_CONTRAST,
  73.   LAST_PROP,
  74. };
  75.  
  76. static GParamSpec *props[LAST_PROP];
  77.  
  78. static GHashTable *display_style_managers = NULL;
  79. static AdwStyleManager *default_instance = NULL;
  80.  
  81. static void
  82. warn_prefer_dark_theme (AdwStyleManager *self)
  83. {
  84.   if (self->setting_dark)
  85.     return;
  86.  
  87.   g_warning ("Using GtkSettings:gtk-application-prefer-dark-theme with "
  88.              "libadwaita is unsupported. Please use "
  89.              "AdwStyleManager:color-scheme instead.");
  90. }
  91.  
  92. static void
  93. unregister_display (GdkDisplay *display)
  94. {
  95.   g_assert (g_hash_table_contains (display_style_managers, display));
  96.  
  97.   g_hash_table_remove (display_style_managers, display);
  98. }
  99.  
  100. static void
  101. register_display (GdkDisplayManager *display_manager,
  102.                   GdkDisplay        *display)
  103. {
  104.   AdwStyleManager *style_manager;
  105.  
  106.   style_manager = g_object_new (ADW_TYPE_STYLE_MANAGER,
  107.                                 "display", display,
  108.                                 NULL);
  109.  
  110.   g_assert (!g_hash_table_contains (display_style_managers, display));
  111.  
  112.   g_hash_table_insert (display_style_managers, display, style_manager);
  113.  
  114.   g_signal_connect (display,
  115.                     "closed",
  116.                     G_CALLBACK (unregister_display),
  117.                     NULL);
  118. }
  119.  
  120. static void
  121. enable_animations_cb (AdwStyleManager *self)
  122. {
  123.   gtk_style_context_remove_provider_for_display (self->display,
  124.                                                  GTK_STYLE_PROVIDER (self->animations_provider));
  125.  
  126.   self->animation_timeout_id = 0;
  127. }
  128.  
  129. static void
  130. update_stylesheet (AdwStyleManager *self)
  131. {
  132.   GtkSettings *gtk_settings;
  133.  
  134.   if (!self->display)
  135.     return;
  136.  
  137.   gtk_settings = gtk_settings_get_for_display (self->display);
  138.  
  139.   if (self->animation_timeout_id)
  140.     g_clear_handle_id (&self->animation_timeout_id, g_source_remove);
  141.  
  142.   gtk_style_context_add_provider_for_display (self->display,
  143.                                               GTK_STYLE_PROVIDER (self->animations_provider),
  144.                                               10000);
  145.  
  146.   self->setting_dark = TRUE;
  147.  
  148.   g_object_set (gtk_settings,
  149.                 "gtk-application-prefer-dark-theme", self->dark,
  150.                 NULL);
  151.  
  152.   self->setting_dark = FALSE;
  153.  
  154.   if (self->provider) {
  155.     if (adw_settings_get_high_contrast (self->settings))
  156.       gtk_css_provider_load_from_resource (self->provider,
  157.                                            "/org/gnome/Adwaita/styles/base-hc.css");
  158.     else
  159.       gtk_css_provider_load_from_resource (self->provider,
  160.                                            "/org/gnome/Adwaita/styles/base.css");
  161.   }
  162.  
  163.   if (self->colors_provider) {
  164.     if (self->dark)
  165.       gtk_css_provider_load_from_resource (self->colors_provider,
  166.                                            "/org/gnome/Adwaita/styles/defaults-dark.css");
  167.     else
  168.       gtk_css_provider_load_from_resource (self->colors_provider,
  169.                                            "/org/gnome/Adwaita/styles/defaults-light.css");
  170.   }
  171.  
  172.   self->animation_timeout_id =
  173.     g_timeout_add_once (SWITCH_DURATION,
  174.                         (GSourceOnceFunc) enable_animations_cb,
  175.                         self);
  176. }
  177.  
  178. static gboolean
  179. get_is_dark (AdwStyleManager *self)
  180. {
  181.   AdwSystemColorScheme system_scheme = adw_settings_get_color_scheme (self->settings);
  182.  
  183.   switch (self->color_scheme) {
  184.   case ADW_COLOR_SCHEME_DEFAULT:
  185.     if (self->display)
  186.       return get_is_dark (default_instance);
  187.     return (system_scheme == ADW_SYSTEM_COLOR_SCHEME_PREFER_DARK);
  188.   case ADW_COLOR_SCHEME_FORCE_LIGHT:
  189.     return FALSE;
  190.   case ADW_COLOR_SCHEME_PREFER_LIGHT:
  191.     return system_scheme == ADW_SYSTEM_COLOR_SCHEME_PREFER_DARK;
  192.   case ADW_COLOR_SCHEME_PREFER_DARK:
  193.     return system_scheme != ADW_SYSTEM_COLOR_SCHEME_PREFER_LIGHT;
  194.   case ADW_COLOR_SCHEME_FORCE_DARK:
  195.     return TRUE;
  196.   default:
  197.     g_assert_not_reached ();
  198.   }
  199. }
  200.  
  201. static void
  202. update_dark (AdwStyleManager *self)
  203. {
  204.   gboolean dark = get_is_dark (self);
  205.  
  206.   if (dark == self->dark)
  207.     return;
  208.  
  209.   self->dark = dark;
  210.  
  211.   update_stylesheet (self);
  212.  
  213.   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DARK]);
  214. }
  215.  
  216. static void
  217. notify_system_supports_color_schemes_cb (AdwStyleManager *self)
  218. {
  219.   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SYSTEM_SUPPORTS_COLOR_SCHEMES]);
  220. }
  221.  
  222. static void
  223. notify_high_contrast_cb (AdwStyleManager *self)
  224. {
  225.   update_stylesheet (self);
  226.  
  227.   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HIGH_CONTRAST]);
  228. }
  229.  
  230. adw_style_manager_theme_changed(GSettings *settings, const char *key, GdkDisplay *display)
  231. {
  232.   char *theme = g_settings_get_string(settings, "gtk-theme");
  233.   if (!theme) {
  234.     theme = "Adwaita-empty";
  235.   }
  236.   gboolean is_dark_variant = NULL != strstr(theme, "-dark");
  237.  
  238.   g_object_set (gtk_settings_get_for_display (display),
  239.                 "gtk-theme-name", theme,
  240.                 "gtk-application-prefer-dark-theme", is_dark_variant,
  241.                 NULL);
  242. }
  243.  
  244. static void
  245. adw_style_manager_constructed (GObject *object)
  246. {
  247.   AdwStyleManager *self = ADW_STYLE_MANAGER (object);
  248.  
  249.   G_OBJECT_CLASS (adw_style_manager_parent_class)->constructed (object);
  250.  
  251.   if (self->display) {
  252.     GtkSettings *settings = gtk_settings_get_for_display (self->display);
  253.     gboolean prefer_dark_theme;
  254.  
  255.  
  256.     if (prefer_dark_theme)
  257.       warn_prefer_dark_theme (self);
  258.  
  259.     g_signal_connect_object (settings,
  260.                              "notify::gtk-application-prefer-dark-theme",
  261.                              G_CALLBACK (warn_prefer_dark_theme),
  262.                              self,
  263.                              G_CONNECT_SWAPPED);
  264.  
  265.     if (!adw_is_granite_present () && !g_getenv ("GTK_THEME")) {
  266.       g_object_set (gtk_settings_get_for_display (self->display),
  267.                     "gtk-theme-name", "Adwaita-empty",
  268.                     NULL);
  269.    
  270.     GSettingsSchemaSource *schema_source =
  271.         g_settings_schema_source_get_default();
  272.     GSettingsSchema *schema = g_settings_schema_source_lookup(
  273.         schema_source, "org.gnome.desktop.interface", true);
  274.     GSettings *interface_settings = g_settings_new_full(schema, NULL, NULL);
  275.  
  276.     adw_style_manager_theme_changed(interface_settings, "gtk-theme", self->display);
  277.     g_signal_connect (interface_settings, "changed", G_CALLBACK (adw_style_manager_theme_changed), self->display);          
  278.  
  279.     }
  280.  
  281.     self->animations_provider = gtk_css_provider_new ();
  282.     gtk_css_provider_load_from_string (self->animations_provider,
  283.                                        "* { transition: none; }");
  284.   }
  285.  
  286.   self->settings = adw_settings_get_default ();
  287.  
  288.   g_signal_connect_object (self->settings,
  289.                            "notify::system-supports-color-schemes",
  290.                            G_CALLBACK (notify_system_supports_color_schemes_cb),
  291.                            self,
  292.                            G_CONNECT_SWAPPED);
  293.   g_signal_connect_object (self->settings,
  294.                            "notify::color-scheme",
  295.                            G_CALLBACK (update_dark),
  296.                            self,
  297.                            G_CONNECT_SWAPPED);
  298.   g_signal_connect_object (self->settings,
  299.                            "notify::high-contrast",
  300.                            G_CALLBACK (notify_high_contrast_cb),
  301.                            self,
  302.                            G_CONNECT_SWAPPED);
  303.  
  304.   update_dark (self);
  305.   update_stylesheet (self);
  306. }
  307.  
  308. static void
  309. adw_style_manager_dispose (GObject *object)
  310. {
  311.   AdwStyleManager *self = ADW_STYLE_MANAGER (object);
  312.  
  313.   g_clear_handle_id (&self->animation_timeout_id, g_source_remove);
  314.   g_clear_object (&self->provider);
  315.   g_clear_object (&self->colors_provider);
  316.   g_clear_object (&self->animations_provider);
  317.  
  318.   G_OBJECT_CLASS (adw_style_manager_parent_class)->dispose (object);
  319. }
  320.  
  321. static void
  322. adw_style_manager_get_property (GObject    *object,
  323.                                 guint       prop_id,
  324.                                 GValue     *value,
  325.                                 GParamSpec *pspec)
  326. {
  327.   AdwStyleManager *self = ADW_STYLE_MANAGER (object);
  328.  
  329.   switch (prop_id) {
  330.   case PROP_DISPLAY:
  331.     g_value_set_object (value, adw_style_manager_get_display (self));
  332.     break;
  333.  
  334.   case PROP_COLOR_SCHEME:
  335.     g_value_set_enum (value, adw_style_manager_get_color_scheme (self));
  336.     break;
  337.  
  338.   case PROP_SYSTEM_SUPPORTS_COLOR_SCHEMES:
  339.     g_value_set_boolean (value, adw_style_manager_get_system_supports_color_schemes (self));
  340.     break;
  341.  
  342.   case PROP_DARK:
  343.     g_value_set_boolean (value, adw_style_manager_get_dark (self));
  344.     break;
  345.  
  346.   case PROP_HIGH_CONTRAST:
  347.     g_value_set_boolean (value, adw_style_manager_get_high_contrast (self));
  348.     break;
  349.  
  350.   default:
  351.     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  352.   }
  353. }
  354.  
  355. static void
  356. adw_style_manager_set_property (GObject      *object,
  357.                                 guint         prop_id,
  358.                                 const GValue *value,
  359.                                 GParamSpec   *pspec)
  360. {
  361.   AdwStyleManager *self = ADW_STYLE_MANAGER (object);
  362.  
  363.   switch (prop_id) {
  364.   case PROP_DISPLAY:
  365.     self->display = g_value_get_object (value);
  366.     break;
  367.  
  368.   case PROP_COLOR_SCHEME:
  369.     adw_style_manager_set_color_scheme (self, g_value_get_enum (value));
  370.     break;
  371.  
  372.   default:
  373.     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  374.   }
  375. }
  376.  
  377. static void
  378. adw_style_manager_class_init (AdwStyleManagerClass *klass)
  379. {
  380.   GObjectClass *object_class = G_OBJECT_CLASS (klass);
  381.  
  382.   object_class->constructed = adw_style_manager_constructed;
  383.   object_class->dispose = adw_style_manager_dispose;
  384.   object_class->get_property = adw_style_manager_get_property;
  385.   object_class->set_property = adw_style_manager_set_property;
  386.  
  387.   /**
  388.    * AdwStyleManager:display: (attributes org.gtk.Property.get=adw_style_manager_get_display)
  389.    *
  390.    * The display the style manager is associated with.
  391.    *
  392.    * The display will be `NULL` for the style manager returned by
  393.    * [func@StyleManager.get_default].
  394.    */
  395.   props[PROP_DISPLAY] =
  396.     g_param_spec_object ("display", NULL, NULL,
  397.                          GDK_TYPE_DISPLAY,
  398.                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
  399.  
  400.   /**
  401.    * AdwStyleManager:color-scheme: (attributes org.gtk.Property.get=adw_style_manager_get_color_scheme org.gtk.Property.set=adw_style_manager_set_color_scheme)
  402.    *
  403.    * The requested application color scheme.
  404.    *
  405.    * The effective appearance will be decided based on the application color
  406.    * scheme and the system preferred color scheme. The
  407.    * [property@StyleManager:dark] property can be used to query the current
  408.    * effective appearance.
  409.    *
  410.    * The `ADW_COLOR_SCHEME_PREFER_LIGHT` color scheme results in the application
  411.    * using light appearance unless the system prefers dark colors. This is the
  412.    * default value.
  413.    *
  414.    * The `ADW_COLOR_SCHEME_PREFER_DARK` color scheme results in the application
  415.    * using dark appearance, but can still switch to the light appearance if the
  416.    * system can prefers it, for example, when the high contrast preference is
  417.    * enabled.
  418.    *
  419.    * The `ADW_COLOR_SCHEME_FORCE_LIGHT` and `ADW_COLOR_SCHEME_FORCE_DARK` values
  420.    * ignore the system preference entirely. They are useful if the application
  421.    * wants to match its UI to its content or to provide a separate color scheme
  422.    * switcher.
  423.    *
  424.    * If a per-[class@Gdk.Display] style manager has its color scheme set to
  425.    * `ADW_COLOR_SCHEME_DEFAULT`, it will inherit the color scheme from the
  426.    * default style manager.
  427.    *
  428.    * For the default style manager, `ADW_COLOR_SCHEME_DEFAULT` is equivalent to
  429.    * `ADW_COLOR_SCHEME_PREFER_LIGHT`.
  430.    *
  431.    * The [property@StyleManager:system-supports-color-schemes] property can be
  432.    * used to check if the current environment provides a color scheme
  433.    * preference.
  434.    */
  435.   props[PROP_COLOR_SCHEME] =
  436.     g_param_spec_enum ("color-scheme", NULL, NULL,
  437.                        ADW_TYPE_COLOR_SCHEME,
  438.                        ADW_COLOR_SCHEME_DEFAULT,
  439.                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
  440.  
  441.   /**
  442.    * AdwStyleManager:system-supports-color-schemes: (attributes org.gtk.Property.get=adw_style_manager_get_system_supports_color_schemes)
  443.    *
  444.    * Whether the system supports color schemes.
  445.    *
  446.    * This property can be used to check if the current environment provides a
  447.    * color scheme preference. For example, applications might want to show a
  448.    * separate appearance switcher if it's set to `FALSE`.
  449.    *
  450.    * See [property@StyleManager:color-scheme].
  451.    */
  452.   props[PROP_SYSTEM_SUPPORTS_COLOR_SCHEMES] =
  453.     g_param_spec_boolean ("system-supports-color-schemes", NULL, NULL,
  454.                           FALSE,
  455.                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
  456.  
  457.   /**
  458.    * AdwStyleManager:dark: (attributes org.gtk.Property.get=adw_style_manager_get_dark)
  459.    *
  460.    * Whether the application is using dark appearance.
  461.    *
  462.    * This property can be used to query the current appearance, as requested via
  463.    * [property@StyleManager:color-scheme].
  464.    */
  465.   props[PROP_DARK] =
  466.     g_param_spec_boolean ("dark", NULL, NULL,
  467.                           FALSE,
  468.                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
  469.  
  470.   /**
  471.    * AdwStyleManager:high-contrast: (attributes org.gtk.Property.get=adw_style_manager_get_high_contrast)
  472.    *
  473.    * Whether the application is using high contrast appearance.
  474.    *
  475.    * This cannot be overridden by applications.
  476.    */
  477.   props[PROP_HIGH_CONTRAST] =
  478.     g_param_spec_boolean ("high-contrast", NULL, NULL,
  479.                           FALSE,
  480.                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
  481.  
  482.   g_object_class_install_properties (object_class, LAST_PROP, props);
  483. }
  484.  
  485. static void
  486. adw_style_manager_init (AdwStyleManager *self)
  487. {
  488.   self->color_scheme = ADW_COLOR_SCHEME_DEFAULT;
  489. }
  490.  
  491. void
  492. adw_style_manager_ensure (void)
  493. {
  494.   GdkDisplayManager *display_manager = gdk_display_manager_get ();
  495.   GSList *displays;
  496.   GSList *l;
  497.  
  498.   if (display_style_managers)
  499.     return;
  500.  
  501.   default_instance = g_object_new (ADW_TYPE_STYLE_MANAGER, NULL);
  502.   display_style_managers = g_hash_table_new_full (g_direct_hash,
  503.                                                   g_direct_equal,
  504.                                                   NULL,
  505.                                                   g_object_unref);
  506.  
  507.   displays = gdk_display_manager_list_displays (display_manager);
  508.  
  509.   for (l = displays; l; l = l->next)
  510.     register_display (display_manager, l->data);
  511.  
  512.   g_signal_connect (display_manager,
  513.                     "display-opened",
  514.                     G_CALLBACK (register_display),
  515.                     NULL);
  516.  
  517.   g_slist_free (displays);
  518. }
  519.  
  520. /**
  521.  * adw_style_manager_get_default:
  522.  *
  523.  * Gets the default `AdwStyleManager` instance.
  524.  *
  525.  * It manages all [class@Gdk.Display] instances unless the style manager for
  526.  * that display has an override.
  527.  *
  528.  * See [func@StyleManager.get_for_display].
  529.  *
  530.  * Returns: (transfer none): the default style manager
  531.  */
  532. AdwStyleManager *
  533. adw_style_manager_get_default (void)
  534. {
  535.   if (!default_instance)
  536.     adw_style_manager_ensure ();
  537.  
  538.   return default_instance;
  539. }
  540.  
  541. /**
  542.  * adw_style_manager_get_for_display:
  543.  * @display: a `GdkDisplay`
  544.  *
  545.  * Gets the `AdwStyleManager` instance managing @display.
  546.  *
  547.  * It can be used to override styles for that specific display instead of the
  548.  * whole application.
  549.  *
  550.  * Most applications should use [func@StyleManager.get_default] instead.
  551.  *
  552.  * Returns: (transfer none): the style manager for @display
  553.  */
  554. AdwStyleManager *
  555. adw_style_manager_get_for_display (GdkDisplay *display)
  556. {
  557.   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
  558.  
  559.   if (!display_style_managers)
  560.     adw_style_manager_ensure ();
  561.  
  562.   g_return_val_if_fail (g_hash_table_contains (display_style_managers, display), NULL);
  563.  
  564.   return g_hash_table_lookup (display_style_managers, display);
  565. }
  566.  
  567. /**
  568.  * adw_style_manager_get_display: (attributes org.gtk.Method.get_property=display)
  569.  * @self: a style manager
  570.  *
  571.  * Gets the display the style manager is associated with.
  572.  *
  573.  * The display will be `NULL` for the style manager returned by
  574.  * [func@StyleManager.get_default].
  575.  *
  576.  * Returns: (transfer none) (nullable): the display
  577.  */
  578. GdkDisplay *
  579. adw_style_manager_get_display (AdwStyleManager *self)
  580. {
  581.   g_return_val_if_fail (ADW_IS_STYLE_MANAGER (self), NULL);
  582.  
  583.   return self->display;
  584. }
  585.  
  586. /**
  587.  * adw_style_manager_get_color_scheme: (attributes org.gtk.Method.get_property=color-scheme)
  588.  * @self: a style manager
  589.  *
  590.  * Gets the requested application color scheme.
  591.  *
  592.  * Returns: the color scheme
  593.  */
  594. AdwColorScheme
  595. adw_style_manager_get_color_scheme (AdwStyleManager *self)
  596. {
  597.   g_return_val_if_fail (ADW_IS_STYLE_MANAGER (self), ADW_COLOR_SCHEME_DEFAULT);
  598.  
  599.   return self->color_scheme;
  600. }
  601.  
  602. /**
  603.  * adw_style_manager_set_color_scheme: (attributes org.gtk.Method.set_property=color-scheme)
  604.  * @self: a style manager
  605.  * @color_scheme: the color scheme
  606.  *
  607.  * Sets the requested application color scheme.
  608.  *
  609.  * The effective appearance will be decided based on the application color
  610.  * scheme and the system preferred color scheme. The
  611.  * [property@StyleManager:dark] property can be used to query the current
  612.  * effective appearance.
  613.  *
  614.  * The `ADW_COLOR_SCHEME_PREFER_LIGHT` color scheme results in the application
  615.  * using light appearance unless the system prefers dark colors. This is the
  616.  * default value.
  617.  *
  618.  * The `ADW_COLOR_SCHEME_PREFER_DARK` color scheme results in the application
  619.  * using dark appearance, but can still switch to the light appearance if the
  620.  * system can prefers it, for example, when the high contrast preference is
  621.  * enabled.
  622.  *
  623.  * The `ADW_COLOR_SCHEME_FORCE_LIGHT` and `ADW_COLOR_SCHEME_FORCE_DARK` values
  624.  * ignore the system preference entirely. They are useful if the application
  625.  * wants to match its UI to its content or to provide a separate color scheme
  626.  * switcher.
  627.  *
  628.  * If a per-[class@Gdk.Display] style manager has its color scheme set to
  629.  * `ADW_COLOR_SCHEME_DEFAULT`, it will inherit the color scheme from the
  630.  * default style manager.
  631.  *
  632.  * For the default style manager, `ADW_COLOR_SCHEME_DEFAULT` is equivalent to
  633.  * `ADW_COLOR_SCHEME_PREFER_LIGHT`.
  634.  *
  635.  * The [property@StyleManager:system-supports-color-schemes] property can be
  636.  * used to check if the current environment provides a color scheme
  637.  * preference.
  638.  */
  639. void
  640. adw_style_manager_set_color_scheme (AdwStyleManager *self,
  641.                                     AdwColorScheme   color_scheme)
  642. {
  643.   g_return_if_fail (ADW_IS_STYLE_MANAGER (self));
  644.  
  645.   if (color_scheme == self->color_scheme)
  646.     return;
  647.  
  648.   self->color_scheme = color_scheme;
  649.  
  650.   g_object_freeze_notify (G_OBJECT (self));
  651.  
  652.   update_dark (self);
  653.  
  654.   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_COLOR_SCHEME]);
  655.  
  656.   g_object_thaw_notify (G_OBJECT (self));
  657.  
  658.   if (!self->display) {
  659.     GHashTableIter iter;
  660.     AdwStyleManager *manager;
  661.  
  662.     g_hash_table_iter_init (&iter, display_style_managers);
  663.  
  664.     while (g_hash_table_iter_next (&iter, NULL, (gpointer) &manager))
  665.       if (manager->color_scheme == ADW_COLOR_SCHEME_DEFAULT)
  666.         update_dark (manager);
  667.   }
  668. }
  669.  
  670. /**
  671.  * adw_style_manager_get_system_supports_color_schemes: (attributes org.gtk.Method.get_property=system-supports-color-schemes)
  672.  * @self: a style manager
  673.  *
  674.  * Gets whether the system supports color schemes.
  675.  *
  676.  * This can be used to check if the current environment provides a color scheme
  677.  * preference. For example, applications might want to show a separate
  678.  * appearance switcher if it's set to `FALSE`.
  679.  *
  680.  * Returns: whether the system supports color schemes
  681.  */
  682. gboolean
  683. adw_style_manager_get_system_supports_color_schemes (AdwStyleManager *self)
  684. {
  685.   g_return_val_if_fail (ADW_IS_STYLE_MANAGER (self), FALSE);
  686.  
  687.   return adw_settings_get_system_supports_color_schemes (self->settings);
  688. }
  689.  
  690. /**
  691.  * adw_style_manager_get_dark: (attributes org.gtk.Method.get_property=dark)
  692.  * @self: a style manager
  693.  *
  694.  * Gets whether the application is using dark appearance.
  695.  *
  696.  * This can be used to query the current appearance, as requested via
  697.  * [property@StyleManager:color-scheme].
  698.  *
  699.  * Returns: whether the application is using dark appearance
  700.  */
  701. gboolean
  702. adw_style_manager_get_dark (AdwStyleManager *self)
  703. {
  704.   g_return_val_if_fail (ADW_IS_STYLE_MANAGER (self), FALSE);
  705.  
  706.   return self->dark;
  707. }
  708.  
  709. /**
  710.  * adw_style_manager_get_high_contrast: (attributes org.gtk.Method.get_property=high-contrast)
  711.  * @self: a style manager
  712.  *
  713.  * Gets whether the application is using high contrast appearance.
  714.  *
  715.  * This cannot be overridden by applications.
  716.  *
  717.  * Returns: whether the application is using high contrast appearance
  718.  */
  719. gboolean
  720. adw_style_manager_get_high_contrast (AdwStyleManager *self)
  721. {
  722.   g_return_val_if_fail (ADW_IS_STYLE_MANAGER (self), FALSE);
  723.  
  724.   return adw_settings_get_high_contrast (self->settings);
  725. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement