diff --git a/doc/css-variables.md b/doc/css-variables.md
index c0d811cb224c2fb9cb1f9aa9ef7bfd0286689a34..6049c150b820cf4e1dec180852f5432e11a4319a 100644
--- a/doc/css-variables.md
+++ b/doc/css-variables.md
@@ -94,37 +94,180 @@ large surfaces, or on too many items on the same view.
The [`.accent`](style-classes.html#colors) style class allows to use it for
widgets such as [class@Gtk.Label].
+The background color is available as `--accent-bg-color`, the foreground as
+`--accent-fg-color` and the standalone color as `--accent-color`.
+
The `--accent-color` color is derived from `--accent-bg-color` as detailed
above.
+The default values of these colors depend on the system preferences, and will
+always be one of the following:
+
- Name
+ Color
- Light
+ Background
- Dark
+ Foreground
+
+ Standalone (Light)
+
+ Standalone (Dark)
- --accent-bg-color
-
- #3584e4
+ Blue
#3584e4
+
+ #ffffff
+
+ #0461be
+
+ #81d0ff
- --accent-fg-color
+ Teal
+
+ #2190a4
#ffffff
+
+ #007184
+
+ #7bdff4
+
+
+ Green
+
+ #3a944a
#ffffff
+
+ #15772e
+
+ #8de698
- --accent-color
-
- #0461be
-
- #81d0ff
+ Yellow
+
+ #c88800
+
+ #ffffff
+
+ #905300
+
+ #ffc057
+
+
+ Orange
+
+ #ed5b00
+
+ #ffffff
+
+ #b62200
+
+ #ff9c5b
+
+
+ Red
+
+ #e62d42
+
+ #ffffff
+
+ #c00023
+
+ #ff888c
+
+
+ Pink
+
+ #d56199
+
+ #ffffff
+
+ #a2326c
+
+ #ffa0d8
+
+
+ Purple
+
+ #9141ac
+
+ #ffffff
+
+ #8939a4
+
+ #fba7ff
+
+
+ Slate
+
+ #6f8396
+
+ #ffffff
+
+ #526678
+
+ #bbd1e5
+
+
+
+Each background color is also available as a variable, as follows:
+
+
+
+ Name
+
+ Value
+
+
+ --accent-blue
+
+ #3584e4
+
+
+ --accent-teal
+
+ #2190a4
+
+
+ --accent-green
+
+ #3a944a
+
+
+ --accent-yellow
+
+ #c88800
+
+
+ --accent-orange
+
+ #ed5b00
+
+
+ --accent-red
+
+ #e62d42
+
+
+ --accent-pink
+
+ #d56199
+
+
+ --accent-purple
+
+ #9141ac
+
+
+ --accent-slate
+
+ #6f8396
diff --git a/doc/styles-and-appearance.md b/doc/styles-and-appearance.md
index e3881e7b398be71991e081f8357467e314a88ee1..257d152a08e22b3b9590f52ba6b852267458ac16 100644
--- a/doc/styles-and-appearance.md
+++ b/doc/styles-and-appearance.md
@@ -84,6 +84,54 @@ remains legible in both appearances:
* [class@Application] allows loading additional styles for dark appearance via
the `style-dark.css` resource.
+## Accent Color
+
+Libadwaita applications follow the system accent color by default. Applications
+with custom drawing or styles may need to ensure that they use the actual accent
+color instead of harcoding blue:
+
+* Use [accent color variables](css-variables.html#accent-colors) and the
+ [`.accent`](style-classes.html#colors) style class in CSS.
+
+* Use [property@StyleManager:accent-color-rgba] to get the background accent
+ color programmatically.
+
+* Use [property@StyleManager:accent-color] and
+ [func@AccentColor.to_standalone_rgba] to get the standalone accent color
+ programmatically.
+
+Applications can override the accent color using CSS, as follows:
+
+```css
+:root {
+ --accent-bg-color: var(--accent-green); /* Always use the green color */
+}
+```
+
+Accent can also be overridden for an individual widget. In this case
+`--accent-color` must be manually overridden as well:
+
+```css
+my-widget {
+ --accent-bg-color: var(--accent-purple); /* Always use the purple color */
+ --accent-color: oklab(from var(--accent-bg-color) var(--standalone-color-oklab));
+}
+```
+
+All of the default accent colors use white text as the foreground color. If the
+custom accent color is too bright, use a dark foreground color instead:
+
+```css
+:root {
+ --accent-bg-color: var(--yellow-3);
+ --accent-fg-color: rgb(0 0 0 / 80%);
+}
+```
+
+::: note
+ When accent color is overridden, [class@StyleManager] API will still return
+ the system color.
+
## High Contrast
The system can provide a high contrast preference. Libadwaita applications
diff --git a/src/adw-accent-color-private.h b/src/adw-accent-color-private.h
new file mode 100644
index 0000000000000000000000000000000000000000..19a0bb2c5582f0bed07537281827d3355e91357b
--- /dev/null
+++ b/src/adw-accent-color-private.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023 Christopher Davis
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#if !defined(_ADWAITA_INSIDE) && !defined(ADWAITA_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include "adw-accent-color.h"
+
+G_BEGIN_DECLS
+
+AdwAccentColor adw_accent_color_nearest_from_rgba (GdkRGBA *original_color);
+
+G_END_DECLS
diff --git a/src/adw-accent-color.c b/src/adw-accent-color.c
new file mode 100644
index 0000000000000000000000000000000000000000..207e22bffbb30dbc593ba844416b7162bffa216b
--- /dev/null
+++ b/src/adw-accent-color.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2023 Christopher Davis
+ * Copyright (C) 2024 Alice Mikhaylenko
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "adw-accent-color-private.h"
+
+#include "adw-color-utils-private.h"
+
+/**
+ * AdwAccentColor:
+ * @ADW_ACCENT_COLOR_BLUE: Use a blue color (`#3584e4`). This is the default value.
+ * @ADW_ACCENT_COLOR_TEAL: Use a teal color (`#2190a4`).
+ * @ADW_ACCENT_COLOR_GREEN: Use a green color (`#3a944a`).
+ * @ADW_ACCENT_COLOR_YELLOW: Use a yellow color (`#c88800`).
+ * @ADW_ACCENT_COLOR_ORANGE: Use a orange color (`#ed5b00`).
+ * @ADW_ACCENT_COLOR_RED: Use a red color (`#e62d42`).
+ * @ADW_ACCENT_COLOR_PINK: Use a pink color (`#d56199`).
+ * @ADW_ACCENT_COLOR_PURPLE: Use a purple color (`#9141ac`).
+ * @ADW_ACCENT_COLOR_SLATE: Use a slate color (`#6f8396`).
+ *
+ * Describes the available system accent colors.
+ *
+ * Since: 1.6
+ */
+
+/**
+ * adw_accent_color_to_rgba:
+ * @self: an accent color
+ * @rgba: return location for the color
+ *
+ * Converts @self to a `GdkRGBA` representing its background color.
+ *
+ * The matching foreground color is white.
+ *
+ * Since: 1.6
+ */
+void
+adw_accent_color_to_rgba (AdwAccentColor self,
+ GdkRGBA *rgba)
+{
+ const char *hex = NULL;
+
+ g_return_if_fail (self >= ADW_ACCENT_COLOR_BLUE);
+ g_return_if_fail (self <= ADW_ACCENT_COLOR_SLATE);
+ g_return_if_fail (rgba != NULL);
+
+ switch (self) {
+ case ADW_ACCENT_COLOR_BLUE:
+ hex = "#3584e4";
+ break;
+ case ADW_ACCENT_COLOR_TEAL:
+ hex = "#2190a4";
+ break;
+ case ADW_ACCENT_COLOR_GREEN:
+ hex = "#3a944a";
+ break;
+ case ADW_ACCENT_COLOR_YELLOW:
+ hex = "#c88800";
+ break;
+ case ADW_ACCENT_COLOR_ORANGE:
+ hex = "#ed5b00";
+ break;
+ case ADW_ACCENT_COLOR_RED:
+ hex = "#e62d42";
+ break;
+ case ADW_ACCENT_COLOR_PINK:
+ hex = "#d56199";
+ break;
+ case ADW_ACCENT_COLOR_PURPLE:
+ hex = "#9141ac";
+ break;
+ case ADW_ACCENT_COLOR_SLATE:
+ hex = "#6f8396";
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (rgba)
+ gdk_rgba_parse (rgba, hex);
+}
+
+/**
+ * adw_accent_color_to_standalone_rgba:
+ * @self: an accent color
+ * @dark: Whether to calculate standalone color for light or dark background
+ * @rgba: return location for the color
+ *
+ * Converts @self to a `GdkRGBA` representing its standalone color.
+ *
+ * It will typically be darker for light background, and lighter for dark
+ * background, ensuring contrast.
+ *
+ * Since: 1.6
+ */
+void
+adw_accent_color_to_standalone_rgba (AdwAccentColor self,
+ gboolean dark,
+ GdkRGBA *rgba)
+{
+ g_return_if_fail (self >= ADW_ACCENT_COLOR_BLUE);
+ g_return_if_fail (self <= ADW_ACCENT_COLOR_SLATE);
+ g_return_if_fail (rgba != NULL);
+
+ dark = !!dark;
+
+ adw_accent_color_to_rgba (self, rgba);
+ adw_rgba_to_standalone (rgba, dark, rgba);
+}
+
+/**
+ * adw_rgba_to_standalone:
+ * @rgba: a background color
+ * @dark: Whether to calculate standalone color for light or dark background
+ * @standalone_rgba: return location for the standalone color
+ *
+ * Adjusts @rgba to be suitable as a standalone color.
+ *
+ * It will typically be darker for light background, and lighter for dark
+ * background, ensuring contrast.
+ *
+ * Since: 1.6
+ */
+void
+adw_rgba_to_standalone (GdkRGBA *rgba,
+ gboolean dark,
+ GdkRGBA *standalone_rgba)
+{
+ float L, a, b;
+
+ g_return_if_fail (rgba != NULL);
+ g_return_if_fail (standalone_rgba != NULL);
+
+ dark = !!dark;
+
+ adw_rgb_to_oklab (rgba->red, rgba->green, rgba->blue, &L, &a, &b);
+
+ if (dark)
+ L = MAX (L, 0.85);
+ else
+ L = MIN (L, 0.5);
+
+ adw_oklab_to_rgb (L, a, b,
+ &standalone_rgba->red,
+ &standalone_rgba->green,
+ &standalone_rgba->blue);
+
+ standalone_rgba->red = CLAMP (standalone_rgba->red, 0, 1);
+ standalone_rgba->green = CLAMP (standalone_rgba->green, 0, 1);
+ standalone_rgba->blue = CLAMP (standalone_rgba->blue, 0, 1);
+ standalone_rgba->alpha = rgba->alpha;
+}
+
+AdwAccentColor
+adw_accent_color_nearest_from_rgba (GdkRGBA *original_color)
+{
+ float L, c, h;
+
+ g_return_val_if_fail (original_color != NULL, ADW_ACCENT_COLOR_BLUE);
+
+ adw_rgb_to_oklch (original_color->red,
+ original_color->green,
+ original_color->blue,
+ &L, &c, &h);
+
+ if (c < 0.04)
+ return ADW_ACCENT_COLOR_SLATE;
+
+ if (h > 345)
+ return ADW_ACCENT_COLOR_PINK;
+
+ if (h > 280)
+ return ADW_ACCENT_COLOR_PURPLE;
+
+ if (h > 230)
+ return ADW_ACCENT_COLOR_BLUE;
+
+ if (h > 175)
+ return ADW_ACCENT_COLOR_TEAL;
+
+ if (h > 130)
+ return ADW_ACCENT_COLOR_GREEN;
+
+ if (h > 75)
+ return ADW_ACCENT_COLOR_YELLOW;
+
+ if (h > 35)
+ return ADW_ACCENT_COLOR_ORANGE;
+
+ if (h > 10)
+ return ADW_ACCENT_COLOR_RED;
+
+ return ADW_ACCENT_COLOR_PINK;
+}
diff --git a/src/adw-accent-color.h b/src/adw-accent-color.h
new file mode 100644
index 0000000000000000000000000000000000000000..5db09121145d1086afd89d558725b67805713d47
--- /dev/null
+++ b/src/adw-accent-color.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 Christopher Davis
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#if !defined(_ADWAITA_INSIDE) && !defined(ADWAITA_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include "adw-version.h"
+
+#include
+
+G_BEGIN_DECLS
+
+typedef enum {
+ ADW_ACCENT_COLOR_BLUE,
+ ADW_ACCENT_COLOR_TEAL,
+ ADW_ACCENT_COLOR_GREEN,
+ ADW_ACCENT_COLOR_YELLOW,
+ ADW_ACCENT_COLOR_ORANGE,
+ ADW_ACCENT_COLOR_RED,
+ ADW_ACCENT_COLOR_PINK,
+ ADW_ACCENT_COLOR_PURPLE,
+ ADW_ACCENT_COLOR_SLATE,
+} AdwAccentColor;
+
+ADW_AVAILABLE_IN_1_6
+void adw_accent_color_to_rgba (AdwAccentColor self,
+ GdkRGBA *rgba);
+
+ADW_AVAILABLE_IN_1_6
+void adw_accent_color_to_standalone_rgba (AdwAccentColor self,
+ gboolean dark,
+ GdkRGBA *rgba);
+
+ADW_AVAILABLE_IN_1_6
+void adw_rgba_to_standalone (GdkRGBA *rgba,
+ gboolean dark,
+ GdkRGBA *standalone_rgba);
+
+G_END_DECLS
diff --git a/src/adw-color-utils-private.h b/src/adw-color-utils-private.h
new file mode 100644
index 0000000000000000000000000000000000000000..cfe3e211f4c4fbb5b87f1cca2698bf37c36e4b14
--- /dev/null
+++ b/src/adw-color-utils-private.h
@@ -0,0 +1,52 @@
+/* Color utilities
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Simon Budig (original code)
+ * Federico Mena-Quintero (cleanup for GTK+)
+ * Jonathan Blandford (cleanup for GTK+)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#pragma once
+
+#if !defined(_ADWAITA_INSIDE) && !defined(ADWAITA_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include "adw-version.h"
+
+#include
+
+G_BEGIN_DECLS
+
+void adw_oklab_to_rgb (float L, float a, float b,
+ float *red, float *green, float *blue);
+void adw_rgb_to_oklab (float red, float green, float blue,
+ float *L, float *a, float *b);
+
+void adw_oklch_to_rgb (float L, float c, float h,
+ float *red, float *green, float *blue);
+void adw_rgb_to_oklch (float red, float green, float blue,
+ float *L, float *c, float *h);
+
+G_END_DECLS
diff --git a/src/adw-color-utils.c b/src/adw-color-utils.c
new file mode 100644
index 0000000000000000000000000000000000000000..0d7f3ccba6a6c020f7f5fd9fbad7e12552d1b2c6
--- /dev/null
+++ b/src/adw-color-utils.c
@@ -0,0 +1,177 @@
+/* Color utilities
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Simon Budig (original code)
+ * Federico Mena-Quintero (cleanup for GTK+)
+ * Jonathan Blandford (cleanup for GTK+)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+#include "adw-color-utils-private.h"
+
+#include
+
+#define DEG_TO_RAD(x) ((x) * G_PI / 180)
+#define RAD_TO_DEG(x) ((x) * 180 / G_PI)
+
+static inline void
+_sincosf (float angle,
+ float *out_s,
+ float *out_c)
+{
+#ifdef HAVE_SINCOSF
+ sincosf (angle, out_s, out_c);
+#else
+ *out_s = sinf (angle);
+ *out_c = cosf (angle);
+#endif
+}
+
+static void
+oklab_to_oklch (float L, float a, float b,
+ float *L2, float *C, float *H)
+{
+ *L2 = L;
+ *C = hypotf (a, b);
+ *H = RAD_TO_DEG (atan2 (b, a));
+ *H = fmod (*H, 360);
+ if (*H < 0)
+ *H += 360;
+}
+
+static void
+oklch_to_oklab (float L, float C, float H,
+ float *L2, float *a, float *b)
+{
+ *L2 = L;
+ _sincosf (DEG_TO_RAD (H), b, a);
+ *a *= C;
+ *b *= C;
+}
+
+static float
+apply_gamma (float v)
+{
+ if (v > 0.0031308)
+ return 1.055 * pow (v, 1/2.4) - 0.055;
+ else
+ return 12.92 * v;
+}
+
+static float
+unapply_gamma (float v)
+{
+ if (v >= 0.04045)
+ return pow (((v + 0.055)/(1 + 0.055)), 2.4);
+ else
+ return v / 12.92;
+}
+
+static void
+oklab_to_linear_srgb (float L, float a, float b,
+ float *red, float *green, float *blue)
+{
+ float l = L + 0.3963377774f * a + 0.2158037573f * b;
+ float m = L - 0.1055613458f * a - 0.0638541728f * b;
+ float s = L - 0.0894841775f * a - 1.2914855480f * b;
+
+ l = powf (l, 3);
+ m = powf (m, 3);
+ s = powf (s, 3);
+
+ *red = +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s;
+ *green = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s;
+ *blue = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s;
+}
+
+static void
+linear_srgb_to_oklab (float red, float green, float blue,
+ float *L, float *a, float *b)
+{
+ float l = 0.4122214708f * red + 0.5363325363f * green + 0.0514459929f * blue;
+ float m = 0.2119034982f * red + 0.6806995451f * green + 0.1073969566f * blue;
+ float s = 0.0883024619f * red + 0.2817188376f * green + 0.6299787005f * blue;
+
+ l = cbrtf (l);
+ m = cbrtf (m);
+ s = cbrtf (s);
+
+ *L = 0.2104542553f*l + 0.7936177850f*m - 0.0040720468f*s;
+ *a = 1.9779984951f*l - 2.4285922050f*m + 0.4505937099f*s;
+ *b = 0.0259040371f*l + 0.7827717662f*m - 0.8086757660f*s;
+}
+
+static void
+rgb_to_linear_srgb (float red, float green, float blue,
+ float *linear_red, float *linear_green, float *linear_blue)
+{
+ *linear_red = unapply_gamma (red);
+ *linear_green = unapply_gamma (green);
+ *linear_blue = unapply_gamma (blue);
+}
+
+static void
+linear_srgb_to_rgb (float linear_red, float linear_green, float linear_blue,
+ float *red, float *green, float *blue)
+{
+ *red = apply_gamma (linear_red);
+ *green = apply_gamma (linear_green);
+ *blue = apply_gamma (linear_blue);
+}
+
+void
+adw_oklab_to_rgb (float L, float a, float b,
+ float *red, float *green, float *blue)
+{
+ float linear_red, linear_green, linear_blue;
+ oklab_to_linear_srgb (L, a, b, &linear_red, &linear_green, &linear_blue);
+ linear_srgb_to_rgb (linear_red, linear_green, linear_blue, red, green, blue);
+}
+
+void
+adw_rgb_to_oklab (float red, float green, float blue,
+ float *L, float *a, float *b)
+{
+ float linear_red, linear_green, linear_blue;
+ rgb_to_linear_srgb (red, green, blue, &linear_red, &linear_green, &linear_blue);
+ linear_srgb_to_oklab (linear_red, linear_green, linear_blue, L, a, b);
+}
+
+void
+adw_oklch_to_rgb (float L, float c, float h,
+ float *red, float *green, float *blue)
+{
+ float l, a, b;
+ oklch_to_oklab (L, c, h, &l, &a, &b);
+ adw_oklab_to_rgb (l, a, b, red, green, blue);
+}
+
+void
+adw_rgb_to_oklch (float red, float green, float blue,
+ float *L, float *c, float *h)
+{
+ float l, a, b;
+ adw_rgb_to_oklab (red, green, blue, &l, &a, &b);
+ oklab_to_oklch (l, a, b, L, c, h);
+}
diff --git a/src/adw-inspector-page.c b/src/adw-inspector-page.c
index fa28678d219ac96b0012255b675186ffb5f87bef..43b450f1b240a81326907b776511b1a802b11d7f 100644
--- a/src/adw-inspector-page.c
+++ b/src/adw-inspector-page.c
@@ -12,6 +12,7 @@
#include "adw-inspector-page-private.h"
#include
+#include "adw-gizmo-private.h"
#include "adw-settings-private.h"
struct _AdwInspectorPage
@@ -23,6 +24,8 @@ struct _AdwInspectorPage
AdwSwitchRow *support_color_schemes_row;
AdwComboRow *color_scheme_row;
AdwSwitchRow *high_contrast_row;
+ AdwSwitchRow *support_accent_colors_row;
+ AdwComboRow *accent_color_row;
GObject *object;
};
@@ -66,6 +69,26 @@ high_contrast_changed_cb (AdwInspectorPage *self)
adw_settings_override_high_contrast (self->settings, hc);
}
+static void
+accent_color_changed_cb (AdwInspectorPage *self)
+{
+ AdwEnumListItem *item = adw_combo_row_get_selected_item (self->accent_color_row);
+ AdwAccentColor accent_color = adw_enum_list_item_get_value (item);
+
+ adw_settings_override_accent_color (self->settings, accent_color);
+}
+
+static void
+support_accent_colors_changed_cb (AdwInspectorPage *self)
+{
+ gboolean supports = adw_switch_row_get_active (self->support_accent_colors_row);
+
+ adw_settings_override_system_supports_accent_colors (self->settings, supports);
+
+ if (supports)
+ accent_color_changed_cb (self);
+}
+
static char *
get_system_color_scheme_name (AdwEnumListItem *item,
gpointer user_data)
@@ -83,6 +106,156 @@ get_system_color_scheme_name (AdwEnumListItem *item,
return "";
}
+static char *
+get_accent_color_name (AdwEnumListItem *item,
+ gpointer user_data)
+{
+ switch (adw_enum_list_item_get_value (item)) {
+ case ADW_ACCENT_COLOR_BLUE:
+ return g_strdup (_("Blue"));
+ case ADW_ACCENT_COLOR_TEAL:
+ return g_strdup (_("Teal"));
+ case ADW_ACCENT_COLOR_GREEN:
+ return g_strdup (_("Green"));
+ case ADW_ACCENT_COLOR_YELLOW:
+ return g_strdup (_("Yellow"));
+ case ADW_ACCENT_COLOR_ORANGE:
+ return g_strdup (_("Orange"));
+ case ADW_ACCENT_COLOR_RED:
+ return g_strdup (_("Red"));
+ case ADW_ACCENT_COLOR_PINK:
+ return g_strdup (_("Pink"));
+ case ADW_ACCENT_COLOR_PURPLE:
+ return g_strdup (_("Purple"));
+ case ADW_ACCENT_COLOR_SLATE:
+ return g_strdup (_("Slate"));
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+selected_item_changed (AdwComboRow *row,
+ GParamSpec *pspec,
+ GtkListItem *item)
+{
+ GtkWidget *checkmark = g_object_get_data (G_OBJECT (item), "checkmark");
+
+ if (adw_combo_row_get_selected_item (row) == gtk_list_item_get_item (item))
+ gtk_widget_set_opacity (checkmark, 1);
+ else
+ gtk_widget_set_opacity (checkmark, 0);
+}
+
+static void
+color_snapshot_cb (AdwGizmo *color,
+ GtkSnapshot *snapshot)
+{
+ GtkListItem *item = g_object_get_data (G_OBJECT (color), "item");
+ AdwEnumListItem *enum_list_item;
+ AdwAccentColor accent;
+ GdkRGBA rgba;
+ int w, h;
+
+ w = gtk_widget_get_width (GTK_WIDGET (color));
+ h = gtk_widget_get_height (GTK_WIDGET (color));
+
+ enum_list_item = ADW_ENUM_LIST_ITEM (gtk_list_item_get_item (item));
+ accent = adw_enum_list_item_get_value (enum_list_item);
+
+ adw_accent_color_to_rgba (accent, &rgba);
+
+ gtk_snapshot_append_color (snapshot, &rgba, &GRAPHENE_RECT_INIT (0, 0, w, h));
+}
+
+static void
+accent_color_item_setup_cb (GtkSignalListItemFactory *factory,
+ GtkListItem *item)
+{
+ GtkWidget *box, *color, *title, *checkmark;
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+ color = adw_gizmo_new_with_role ("color",
+ GTK_ACCESSIBLE_ROLE_PRESENTATION,
+ NULL, NULL,
+ color_snapshot_cb,
+ NULL, NULL, NULL);
+ gtk_widget_set_valign (color, GTK_ALIGN_CENTER);
+ gtk_widget_set_overflow (color, GTK_OVERFLOW_HIDDEN);
+ gtk_box_append (GTK_BOX (box), color);
+
+ title = gtk_label_new (NULL);
+ gtk_label_set_xalign (GTK_LABEL (title), 0.0);
+ gtk_label_set_ellipsize (GTK_LABEL (title), PANGO_ELLIPSIZE_END);
+ gtk_label_set_max_width_chars (GTK_LABEL (title), 20);
+ gtk_widget_set_valign (title, GTK_ALIGN_CENTER);
+ gtk_box_append (GTK_BOX (box), title);
+
+ checkmark = g_object_new (GTK_TYPE_IMAGE,
+ "accessible-role", GTK_ACCESSIBLE_ROLE_PRESENTATION,
+ "icon-name", "object-select-symbolic",
+ NULL);
+ gtk_box_append (GTK_BOX (box), checkmark);
+
+ g_object_set_data (G_OBJECT (item), "box", box);
+ g_object_set_data (G_OBJECT (item), "color", color);
+ g_object_set_data (G_OBJECT (item), "title", title);
+ g_object_set_data (G_OBJECT (item), "checkmark", checkmark);
+
+ g_object_set_data (G_OBJECT (color), "item", item);
+
+ gtk_list_item_set_child (item, box);
+}
+
+static void
+accent_color_item_bind_cb (GtkSignalListItemFactory *factory,
+ GtkListItem *item,
+ AdwInspectorPage *self)
+{
+ AdwComboRow *row = self->accent_color_row;
+ GtkWidget *box, *color, *title, *checkmark;
+ AdwEnumListItem *enum_list_item;
+ char *accent_name;
+ GtkWidget *popup;
+
+ enum_list_item = ADW_ENUM_LIST_ITEM (gtk_list_item_get_item (item));
+ accent_name = get_accent_color_name (enum_list_item, NULL);
+
+ box = g_object_get_data (G_OBJECT (item), "box");
+ color = g_object_get_data (G_OBJECT (item), "color");
+ title = g_object_get_data (G_OBJECT (item), "title");
+ checkmark = g_object_get_data (G_OBJECT (item), "checkmark");
+
+ gtk_label_set_label (GTK_LABEL (title), accent_name);
+
+ gtk_widget_queue_draw (color);
+
+ popup = gtk_widget_get_ancestor (title, GTK_TYPE_POPOVER);
+ if (popup && gtk_widget_is_ancestor (popup, GTK_WIDGET (row))) {
+ gtk_box_set_spacing (GTK_BOX (box), 0);
+ gtk_widget_set_visible (checkmark, TRUE);
+ g_signal_connect (row, "notify::selected-item",
+ G_CALLBACK (selected_item_changed), item);
+ selected_item_changed (row, NULL, item);
+ } else {
+ gtk_box_set_spacing (GTK_BOX (box), 6);
+ gtk_widget_set_visible (checkmark, FALSE);
+ }
+
+ g_free (accent_name);
+}
+
+static void
+accent_color_item_unbind_cb (GtkSignalListItemFactory *factory,
+ GtkListItem *item,
+ AdwInspectorPage *self)
+{
+ AdwComboRow *row = self->accent_color_row;
+
+ g_signal_handlers_disconnect_by_func (row, selected_item_changed, item);
+}
+
static void
adw_inspector_page_get_property (GObject *object,
guint prop_id,
@@ -164,17 +337,26 @@ adw_inspector_page_class_init (AdwInspectorPageClass *klass)
gtk_widget_class_bind_template_child (widget_class, AdwInspectorPage, support_color_schemes_row);
gtk_widget_class_bind_template_child (widget_class, AdwInspectorPage, color_scheme_row);
gtk_widget_class_bind_template_child (widget_class, AdwInspectorPage, high_contrast_row);
+ gtk_widget_class_bind_template_child (widget_class, AdwInspectorPage, support_accent_colors_row);
+ gtk_widget_class_bind_template_child (widget_class, AdwInspectorPage, accent_color_row);
gtk_widget_class_bind_template_callback (widget_class, get_system_color_scheme_name);
+ gtk_widget_class_bind_template_callback (widget_class, get_accent_color_name);
+ gtk_widget_class_bind_template_callback (widget_class, accent_color_item_setup_cb);
+ gtk_widget_class_bind_template_callback (widget_class, accent_color_item_bind_cb);
+ gtk_widget_class_bind_template_callback (widget_class, accent_color_item_unbind_cb);
gtk_widget_class_bind_template_callback (widget_class, support_color_schemes_changed_cb);
+ gtk_widget_class_bind_template_callback (widget_class, support_accent_colors_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, color_scheme_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, high_contrast_changed_cb);
+ gtk_widget_class_bind_template_callback (widget_class, accent_color_changed_cb);
}
static void
adw_inspector_page_init (AdwInspectorPage *self)
{
AdwSystemColorScheme color_scheme;
+ AdwAccentColor accent_color;
gboolean supports, hc;
self->settings = adw_settings_get_default ();
@@ -191,4 +373,10 @@ adw_inspector_page_init (AdwInspectorPage *self)
hc = adw_settings_get_high_contrast (self->settings);
adw_switch_row_set_active (self->high_contrast_row, hc);
+
+ accent_color = adw_settings_get_accent_color (self->settings);
+ adw_combo_row_set_selected (self->accent_color_row, accent_color);
+
+ supports = adw_settings_get_system_supports_accent_colors (self->settings);
+ adw_switch_row_set_active (self->support_accent_colors_row, supports);
}
diff --git a/src/adw-inspector-page.ui b/src/adw-inspector-page.ui
index 5bb93b0238004fc5a0eb201f551c65f754db4f77..19cf2e509b3da757e679c5f68cae3e264bbaefd8 100644
--- a/src/adw-inspector-page.ui
+++ b/src/adw-inspector-page.ui
@@ -32,6 +32,49 @@
+
+
+
+
+ Accent Color
+
+
+ System Supports Accent Colors
+
+
+
+
+
+ Preferred Accent Color
+
+
+
+ AdwAccentColor
+
+
+
+
+
+
+
+
+
+
+
+
+
+ support_accent_colors_row
+
+
+
+
+
+
+
+
+ Accessibility
High Contrast
diff --git a/src/adw-settings-impl-gsettings.c b/src/adw-settings-impl-gsettings.c
index 1a2cee3676c73ac64cd92ed127b84411b210f285..5a3cfe99da4e37fe44b74c8b447e005d79c1f0e7 100644
--- a/src/adw-settings-impl-gsettings.c
+++ b/src/adw-settings-impl-gsettings.c
@@ -50,6 +50,15 @@ high_contrast_changed_cb (AdwSettingsImplGSettings *self)
adw_settings_impl_set_high_contrast (ADW_SETTINGS_IMPL (self), high_contrast);
}
+static void
+accent_color_changed_cb (AdwSettingsImplGSettings *self)
+{
+ AdwAccentColor accent_color =
+ g_settings_get_enum (self->interface_settings, "accent-color");
+
+ adw_settings_impl_set_accent_color (ADW_SETTINGS_IMPL (self), accent_color);
+}
+
static void
adw_settings_impl_gsettings_dispose (GObject *object)
{
@@ -76,12 +85,14 @@ adw_settings_impl_gsettings_init (AdwSettingsImplGSettings *self)
AdwSettingsImpl *
adw_settings_impl_gsettings_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast)
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors)
{
AdwSettingsImplGSettings *self = g_object_new (ADW_TYPE_SETTINGS_IMPL_GSETTINGS, NULL);
GSettingsSchemaSource *source;
gboolean found_color_scheme = FALSE;
gboolean found_high_contrast = FALSE;
+ gboolean found_accent_colors = FALSE;
/* While we can access gsettings in flatpak, we can't do anything useful with
* them as they aren't propagated from the system. */
@@ -90,20 +101,34 @@ adw_settings_impl_gsettings_new (gboolean enable_color_scheme,
source = g_settings_schema_source_get_default ();
- if (enable_color_scheme && adw_get_disable_portal ()) {
+ if ((enable_color_scheme || enable_accent_colors) && adw_get_disable_portal ()) {
GSettingsSchema *schema =
g_settings_schema_source_lookup (source, "org.gnome.desktop.interface", TRUE);
- if (schema && g_settings_schema_has_key (schema, "color-scheme")) {
- found_color_scheme = TRUE;
+ if (schema) {
self->interface_settings = g_settings_new ("org.gnome.desktop.interface");
- color_scheme_changed_cb (self);
+ if (g_settings_schema_has_key (schema, "color-scheme")) {
+ found_color_scheme = TRUE;
- g_signal_connect_swapped (self->interface_settings,
- "changed::color-scheme",
- G_CALLBACK (color_scheme_changed_cb),
- self);
+ color_scheme_changed_cb (self);
+
+ g_signal_connect_swapped (self->interface_settings,
+ "changed::color-scheme",
+ G_CALLBACK (color_scheme_changed_cb),
+ self);
+ }
+
+ if (g_settings_schema_has_key (schema, "accent-color")) {
+ found_accent_colors = TRUE;
+
+ accent_color_changed_cb (self);
+
+ g_signal_connect_swapped (self->interface_settings,
+ "changed::accent-color",
+ G_CALLBACK (accent_color_changed_cb),
+ self);
+ }
}
g_clear_pointer (&schema, g_settings_schema_unref);
@@ -130,7 +155,8 @@ adw_settings_impl_gsettings_new (gboolean enable_color_scheme,
adw_settings_impl_set_features (ADW_SETTINGS_IMPL (self),
found_color_scheme,
- found_high_contrast);
+ found_high_contrast,
+ found_accent_colors);
return ADW_SETTINGS_IMPL (self);
}
diff --git a/src/adw-settings-impl-legacy.c b/src/adw-settings-impl-legacy.c
index 87519a975690319dfcfab7e0b82aa192c204376d..b7da8dbb85e285448f773189490fe673abd079d7 100644
--- a/src/adw-settings-impl-legacy.c
+++ b/src/adw-settings-impl-legacy.c
@@ -62,7 +62,8 @@ adw_settings_impl_legacy_init (AdwSettingsImplLegacy *self)
AdwSettingsImpl *
adw_settings_impl_legacy_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast)
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors)
{
AdwSettingsImplLegacy *self = g_object_new (ADW_TYPE_SETTINGS_IMPL_LEGACY, NULL);
GdkDisplay *display;
@@ -79,7 +80,8 @@ adw_settings_impl_legacy_new (gboolean enable_color_scheme,
is_theme_high_contrast (display));
adw_settings_impl_set_features (ADW_SETTINGS_IMPL (self),
/* has_color_scheme */ FALSE,
- /* has_high_contrast */ TRUE);
+ /* has_high_contrast */ TRUE,
+ /* has_accent_colors */ FALSE);
g_signal_connect_swapped (display,
"setting-changed",
diff --git a/src/adw-settings-impl-macos.c b/src/adw-settings-impl-macos.c
index 2d20b486ef3958aaec41c6717d09497d308af73c..50bec95ac3872343ee881186de0e1f89f6dbf47d 100644
--- a/src/adw-settings-impl-macos.c
+++ b/src/adw-settings-impl-macos.c
@@ -84,7 +84,8 @@ adw_settings_impl_macos_init (AdwSettingsImplMacOS *self)
AdwSettingsImpl *
adw_settings_impl_macos_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast)
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors)
{
AdwSettingsImplMacOS *self = g_object_new (ADW_TYPE_SETTINGS_IMPL_MACOS, NULL);
@@ -106,7 +107,8 @@ adw_settings_impl_macos_new (gboolean enable_color_scheme,
adw_settings_impl_set_features (ADW_SETTINGS_IMPL (self),
/* has_color_scheme */ TRUE,
- /* has_high_contrast */ FALSE);
+ /* has_high_contrast */ FALSE,
+ /* has_accent_colors */ FALSE);
}
return ADW_SETTINGS_IMPL (self);
diff --git a/src/adw-settings-impl-portal.c b/src/adw-settings-impl-portal.c
index 7f50a79c5dd09fd538292a436d17eedf581a7cbd..6984aa181757f23929604127c10becbd2e63d819 100644
--- a/src/adw-settings-impl-portal.c
+++ b/src/adw-settings-impl-portal.c
@@ -32,6 +32,8 @@ struct _AdwSettingsImplPortal
HIGH_CONTRAST_STATE_FDO,
HIGH_CONTRAST_STATE_GNOME,
} high_contrast_portal_state;
+
+ gboolean found_accent_colors;
};
G_DEFINE_FINAL_TYPE (AdwSettingsImplPortal, adw_settings_impl_portal, ADW_TYPE_SETTINGS_IMPL)
@@ -116,6 +118,25 @@ get_fdo_color_scheme (GVariant *variant)
return color_scheme;
}
+static AdwAccentColor
+get_fdo_accent_color (GVariant *variant)
+{
+ double r = -1, g = -1, b = -1;
+ GdkRGBA rgba;
+
+ g_variant_get (variant, "(ddd)", &r, &g, &b);
+
+ if (r < 0 || g < 0 || b < 0 || r > 1 || g > 1 || b > 1)
+ return ADW_ACCENT_COLOR_BLUE;
+
+ rgba.red = r;
+ rgba.green = g;
+ rgba.blue = b;
+ rgba.alpha = 1.0;
+
+ return adw_accent_color_nearest_from_rgba (&rgba);
+}
+
static void
changed_cb (GDBusProxy *proxy,
const char *sender_name,
@@ -151,6 +172,15 @@ changed_cb (GDBusProxy *proxy,
return;
}
+
+ if (!g_strcmp0 (name, "accent-color") && self->found_accent_colors) {
+ adw_settings_impl_set_accent_color (ADW_SETTINGS_IMPL (self),
+ get_fdo_accent_color (value));
+
+ g_variant_unref (value);
+
+ return;
+ }
}
if (!g_strcmp0 (namespace, "org.gnome.desktop.a11y.interface") &&
@@ -188,7 +218,8 @@ adw_settings_impl_portal_init (AdwSettingsImplPortal *self)
AdwSettingsImpl *
adw_settings_impl_portal_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast)
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors)
{
AdwSettingsImplPortal *self = g_object_new (ADW_TYPE_SETTINGS_IMPL_PORTAL, NULL);
GError *error = NULL;
@@ -226,7 +257,7 @@ adw_settings_impl_portal_new (gboolean enable_color_scheme,
if (enable_high_contrast) {
if (read_setting (self, "org.freedesktop.appearance",
- "contrast", "u", &variant)) {
+ "contrast", "u", &variant)) {
self->high_contrast_portal_state = HIGH_CONTRAST_STATE_FDO;
adw_settings_impl_set_high_contrast (ADW_SETTINGS_IMPL (self),
@@ -243,13 +274,28 @@ adw_settings_impl_portal_new (gboolean enable_color_scheme,
}
}
+ if (enable_accent_colors &&
+ read_setting (self, "org.freedesktop.appearance",
+ "accent-color", "(ddd)", &variant)) {
+ self->found_accent_colors = TRUE;
+
+ adw_settings_impl_set_accent_color (ADW_SETTINGS_IMPL (self),
+ get_fdo_accent_color (variant));
+
+ g_variant_unref (variant);
+ }
+
adw_settings_impl_set_features (ADW_SETTINGS_IMPL (self),
self->found_color_scheme,
- self->high_contrast_portal_state != HIGH_CONTRAST_STATE_NONE);
+ self->high_contrast_portal_state != HIGH_CONTRAST_STATE_NONE,
+ self->found_accent_colors);
- if (self->found_color_scheme || self->high_contrast_portal_state != HIGH_CONTRAST_STATE_NONE)
+ if (self->found_color_scheme ||
+ self->high_contrast_portal_state != HIGH_CONTRAST_STATE_NONE ||
+ self->found_accent_colors) {
g_signal_connect (self->settings_portal, "g-signal",
G_CALLBACK (changed_cb), self);
+ }
return ADW_SETTINGS_IMPL (self);
}
diff --git a/src/adw-settings-impl-private.h b/src/adw-settings-impl-private.h
index 54c3f6fb6314bd7c54e6c6961b6bc3acb448c27d..347523d12dd1ed0a1c67a5438e8228d5ce440591 100644
--- a/src/adw-settings-impl-private.h
+++ b/src/adw-settings-impl-private.h
@@ -28,9 +28,11 @@ struct _AdwSettingsImplClass
gboolean adw_settings_impl_get_has_color_scheme (AdwSettingsImpl *self);
gboolean adw_settings_impl_get_has_high_contrast (AdwSettingsImpl *self);
+gboolean adw_settings_impl_get_has_accent_colors (AdwSettingsImpl *self);
void adw_settings_impl_set_features (AdwSettingsImpl *self,
gboolean has_color_scheme,
- gboolean has_high_contrast);
+ gboolean has_high_contrast,
+ gboolean has_accent_colors);
AdwSystemColorScheme adw_settings_impl_get_color_scheme (AdwSettingsImpl *self);
void adw_settings_impl_set_color_scheme (AdwSettingsImpl *self,
@@ -40,6 +42,10 @@ gboolean adw_settings_impl_get_high_contrast (AdwSettingsImpl *self);
void adw_settings_impl_set_high_contrast (AdwSettingsImpl *self,
gboolean high_contrast);
+AdwAccentColor adw_settings_impl_get_accent_color (AdwSettingsImpl *self);
+void adw_settings_impl_set_accent_color (AdwSettingsImpl *self,
+ AdwAccentColor accent_color);
+
gboolean adw_get_disable_portal (void);
#ifdef __APPLE__
@@ -48,21 +54,24 @@ gboolean adw_get_disable_portal (void);
G_DECLARE_FINAL_TYPE (AdwSettingsImplMacOS, adw_settings_impl_macos, ADW, SETTINGS_IMPL_MACOS, AdwSettingsImpl)
AdwSettingsImpl *adw_settings_impl_macos_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast) G_GNUC_WARN_UNUSED_RESULT;
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors) G_GNUC_WARN_UNUSED_RESULT;
#elif defined(G_OS_WIN32)
#define ADW_TYPE_SETTINGS_IMPL_WIN32 (adw_settings_impl_win32_get_type())
G_DECLARE_FINAL_TYPE (AdwSettingsImplWin32, adw_settings_impl_win32, ADW, SETTINGS_IMPL_WIN32, AdwSettingsImpl)
AdwSettingsImpl *adw_settings_impl_win32_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast) G_GNUC_WARN_UNUSED_RESULT;
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors) G_GNUC_WARN_UNUSED_RESULT;
#else
#define ADW_TYPE_SETTINGS_IMPL_PORTAL (adw_settings_impl_portal_get_type())
G_DECLARE_FINAL_TYPE (AdwSettingsImplPortal, adw_settings_impl_portal, ADW, SETTINGS_IMPL_PORTAL, AdwSettingsImpl)
AdwSettingsImpl *adw_settings_impl_portal_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast) G_GNUC_WARN_UNUSED_RESULT;
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors) G_GNUC_WARN_UNUSED_RESULT;
#endif
#define ADW_TYPE_SETTINGS_IMPL_GSETTINGS (adw_settings_impl_gsettings_get_type())
@@ -70,13 +79,15 @@ AdwSettingsImpl *adw_settings_impl_portal_new (gboolean enable_color_scheme,
G_DECLARE_FINAL_TYPE (AdwSettingsImplGSettings, adw_settings_impl_gsettings, ADW, SETTINGS_IMPL_GSETTINGS, AdwSettingsImpl)
AdwSettingsImpl *adw_settings_impl_gsettings_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast) G_GNUC_WARN_UNUSED_RESULT;
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors) G_GNUC_WARN_UNUSED_RESULT;
#define ADW_TYPE_SETTINGS_IMPL_LEGACY (adw_settings_impl_legacy_get_type())
G_DECLARE_FINAL_TYPE (AdwSettingsImplLegacy, adw_settings_impl_legacy, ADW, SETTINGS_IMPL_LEGACY, AdwSettingsImpl)
AdwSettingsImpl *adw_settings_impl_legacy_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast) G_GNUC_WARN_UNUSED_RESULT;
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors) G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
diff --git a/src/adw-settings-impl-win32.c b/src/adw-settings-impl-win32.c
index 484e3f807055718e8a520d991057b0c5f9808912..f17f496ddd2f6629e386e958d9228ef8f163f6c0 100644
--- a/src/adw-settings-impl-win32.c
+++ b/src/adw-settings-impl-win32.c
@@ -375,7 +375,8 @@ adw_settings_impl_win32_init (AdwSettingsImplWin32 *self)
AdwSettingsImpl *
adw_settings_impl_win32_new (gboolean enable_color_scheme,
- gboolean enable_high_contrast)
+ gboolean enable_high_contrast,
+ gboolean enable_accent_colors)
{
AdwSettingsImplWin32 *self = g_object_new (ADW_TYPE_SETTINGS_IMPL_WIN32, NULL);
GdkDisplay *display = gdk_display_get_default ();
@@ -401,7 +402,8 @@ adw_settings_impl_win32_new (gboolean enable_color_scheme,
adw_settings_impl_set_features (ADW_SETTINGS_IMPL (self),
found_color_scheme,
- enable_high_contrast);
+ enable_high_contrast,
+ /* has_accent_colors */ FALSE);
return ADW_SETTINGS_IMPL (self);
}
diff --git a/src/adw-settings-impl.c b/src/adw-settings-impl.c
index 9bbcffdebeb513f73378da0dc3316ce5915ca5f0..536eca6ac743d8bda7dad12e2b813521d6be93b9 100644
--- a/src/adw-settings-impl.c
+++ b/src/adw-settings-impl.c
@@ -16,9 +16,11 @@ typedef struct
{
gboolean has_color_scheme;
gboolean has_high_contrast;
+ gboolean has_accent_colors;
AdwSystemColorScheme color_scheme;
gboolean high_contrast;
+ AdwAccentColor accent_color;
} AdwSettingsImplPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (AdwSettingsImpl, adw_settings_impl, G_TYPE_OBJECT)
@@ -27,6 +29,7 @@ enum {
SIGNAL_PREPARE,
SIGNAL_COLOR_SCHEME_CHANGED,
SIGNAL_HIGH_CONTRAST_CHANGED,
+ SIGNAL_ACCENT_COLOR_CHANGED,
SIGNAL_LAST_SIGNAL,
};
@@ -62,6 +65,20 @@ adw_settings_impl_class_init (AdwSettingsImplClass *klass)
g_signal_set_va_marshaller (signals[SIGNAL_HIGH_CONTRAST_CHANGED],
G_TYPE_FROM_CLASS (klass),
adw_marshal_VOID__BOOLEANv);
+
+ signals[SIGNAL_ACCENT_COLOR_CHANGED] =
+ g_signal_new ("accent-color-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ adw_marshal_VOID__ENUM,
+ G_TYPE_NONE,
+ 1,
+ ADW_TYPE_ACCENT_COLOR);
+ g_signal_set_va_marshaller (signals[SIGNAL_ACCENT_COLOR_CHANGED],
+ G_TYPE_FROM_CLASS (klass),
+ adw_marshal_VOID__ENUMv);
}
static void
@@ -89,10 +106,21 @@ adw_settings_impl_get_has_high_contrast (AdwSettingsImpl *self)
return priv->has_high_contrast;
}
+gboolean
+adw_settings_impl_get_has_accent_colors (AdwSettingsImpl *self)
+{
+ AdwSettingsImplPrivate *priv = adw_settings_impl_get_instance_private (self);
+
+ g_return_val_if_fail (ADW_IS_SETTINGS_IMPL (self), FALSE);
+
+ return priv->has_accent_colors;
+}
+
void
adw_settings_impl_set_features (AdwSettingsImpl *self,
gboolean has_color_scheme,
- gboolean has_high_contrast)
+ gboolean has_high_contrast,
+ gboolean has_accent_colors)
{
AdwSettingsImplPrivate *priv = adw_settings_impl_get_instance_private (self);
@@ -100,6 +128,7 @@ adw_settings_impl_set_features (AdwSettingsImpl *self,
priv->has_color_scheme = !!has_color_scheme;
priv->has_high_contrast = !!has_high_contrast;
+ priv->has_accent_colors = !!has_accent_colors;
}
AdwSystemColorScheme
@@ -158,6 +187,33 @@ adw_settings_impl_set_high_contrast (AdwSettingsImpl *self,
g_signal_emit (G_OBJECT (self), signals[SIGNAL_HIGH_CONTRAST_CHANGED], 0, high_contrast);
}
+AdwAccentColor
+adw_settings_impl_get_accent_color (AdwSettingsImpl *self)
+{
+ AdwSettingsImplPrivate *priv = adw_settings_impl_get_instance_private (self);
+
+ g_return_val_if_fail (ADW_IS_SETTINGS_IMPL (self), ADW_ACCENT_COLOR_BLUE);
+
+ return priv->accent_color;
+}
+
+void
+adw_settings_impl_set_accent_color (AdwSettingsImpl *self,
+ AdwAccentColor accent_color)
+{
+ AdwSettingsImplPrivate *priv = adw_settings_impl_get_instance_private (self);
+
+ g_return_if_fail (ADW_IS_SETTINGS_IMPL (self));
+
+ if (priv->accent_color == accent_color)
+ return;
+
+ priv->accent_color = accent_color;
+
+ if (priv->has_accent_colors)
+ g_signal_emit (G_OBJECT (self), signals[SIGNAL_ACCENT_COLOR_CHANGED], 0, accent_color);
+}
+
gboolean
adw_get_disable_portal (void)
{
diff --git a/src/adw-settings-private.h b/src/adw-settings-private.h
index dc11df58fa181ff0f777682b2ca5cd9f3a929a2f..f4921f4d27a9ae34a32b11798039de8cc2c1c88c 100644
--- a/src/adw-settings-private.h
+++ b/src/adw-settings-private.h
@@ -13,6 +13,7 @@
#endif
#include
+#include "adw-accent-color-private.h"
#include "adw-enums-private.h"
G_BEGIN_DECLS
@@ -39,6 +40,12 @@ AdwSystemColorScheme adw_settings_get_color_scheme (AdwSettings *self);
ADW_AVAILABLE_IN_ALL
gboolean adw_settings_get_high_contrast (AdwSettings *self);
+ADW_AVAILABLE_IN_1_6
+gboolean adw_settings_get_system_supports_accent_colors (AdwSettings *self);
+
+ADW_AVAILABLE_IN_1_6
+AdwAccentColor adw_settings_get_accent_color (AdwSettings *self);
+
ADW_AVAILABLE_IN_ALL
void adw_settings_start_override (AdwSettings *self);
ADW_AVAILABLE_IN_ALL
@@ -56,4 +63,10 @@ ADW_AVAILABLE_IN_ALL
void adw_settings_override_high_contrast (AdwSettings *self,
gboolean high_contrast);
+void adw_settings_override_system_supports_accent_colors (AdwSettings *self,
+ gboolean system_supports_accent_colors);
+
+void adw_settings_override_accent_color (AdwSettings *self,
+ AdwAccentColor accent_color);
+
G_END_DECLS
diff --git a/src/adw-settings.c b/src/adw-settings.c
index cf0e81c0e3ff026d9f17ea0f82c858aab71f5c88..4187f798a34902a125f90883dc120ce61597e16c 100644
--- a/src/adw-settings.c
+++ b/src/adw-settings.c
@@ -25,11 +25,15 @@ struct _AdwSettings
AdwSystemColorScheme color_scheme;
gboolean high_contrast;
gboolean system_supports_color_schemes;
+ AdwAccentColor accent_color;
+ gboolean system_supports_accent_colors;
gboolean override;
gboolean system_supports_color_schemes_override;
AdwSystemColorScheme color_scheme_override;
gboolean high_contrast_override;
+ gboolean system_supports_accent_colors_override;
+ AdwAccentColor accent_color_override;
};
G_DEFINE_FINAL_TYPE (AdwSettings, adw_settings, G_TYPE_OBJECT);
@@ -39,6 +43,8 @@ enum {
PROP_SYSTEM_SUPPORTS_COLOR_SCHEMES,
PROP_COLOR_SCHEME,
PROP_HIGH_CONTRAST,
+ PROP_SYSTEM_SUPPORTS_ACCENT_COLORS,
+ PROP_ACCENT_COLOR,
LAST_PROP,
};
@@ -72,10 +78,24 @@ set_high_contrast (AdwSettings *self,
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HIGH_CONTRAST]);
}
+static void
+set_accent_color (AdwSettings *self,
+ AdwAccentColor accent_color)
+{
+ if (accent_color == self->accent_color)
+ return;
+
+ self->accent_color = accent_color;
+
+ if (!self->override)
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACCENT_COLOR]);
+}
+
static void
init_debug (AdwSettings *self,
gboolean *found_color_scheme,
- gboolean *found_high_contrast)
+ gboolean *found_high_contrast,
+ gboolean *found_accent_colors)
{
const char *env = g_getenv ("ADW_DEBUG_HIGH_CONTRAST");
if (env && *env) {
@@ -105,13 +125,41 @@ init_debug (AdwSettings *self,
g_warning ("Invalid color scheme %s (Expected one of: default, prefer-dark, prefer-light)", env);
}
}
+
+ env = g_getenv ("ADW_DEBUG_ACCENT_COLOR");
+ if (env) {
+ *found_accent_colors = TRUE;
+ if (!g_strcmp0 (env, "blue")) {
+ self->accent_color = ADW_ACCENT_COLOR_BLUE;
+ } else if (!g_strcmp0 (env, "teal")) {
+ self->accent_color = ADW_ACCENT_COLOR_TEAL;
+ } else if (!g_strcmp0 (env, "green")) {
+ self->accent_color = ADW_ACCENT_COLOR_GREEN;
+ } else if (!g_strcmp0 (env, "yellow")) {
+ self->accent_color = ADW_ACCENT_COLOR_YELLOW;
+ } else if (!g_strcmp0 (env, "orange")) {
+ self->accent_color = ADW_ACCENT_COLOR_ORANGE;
+ } else if (!g_strcmp0 (env, "red")) {
+ self->accent_color = ADW_ACCENT_COLOR_RED;
+ } else if (!g_strcmp0 (env, "pink")) {
+ self->accent_color = ADW_ACCENT_COLOR_PINK;
+ } else if (!g_strcmp0 (env, "purple")) {
+ self->accent_color = ADW_ACCENT_COLOR_PURPLE;
+ } else if (!g_strcmp0 (env, "slate")) {
+ self->accent_color = ADW_ACCENT_COLOR_SLATE;
+ } else {
+ g_warning ("Invalid accent color %s (Expected one of: blue, teal, green,"
+ "yellow, orange, red, pink, purple, slate)", env);
+ }
+ }
}
static void
register_impl (AdwSettings *self,
AdwSettingsImpl *impl,
gboolean *found_color_scheme,
- gboolean *found_high_contrast)
+ gboolean *found_high_contrast,
+ gboolean *found_accent_colors)
{
if (adw_settings_impl_get_has_color_scheme (impl)) {
*found_color_scheme = TRUE;
@@ -130,6 +178,15 @@ register_impl (AdwSettings *self,
g_signal_connect_swapped (impl, "high-contrast-changed",
G_CALLBACK (set_high_contrast), self);
}
+
+ if (adw_settings_impl_get_has_accent_colors (impl)) {
+ *found_accent_colors = TRUE;
+
+ set_accent_color (self, adw_settings_impl_get_accent_color (impl));
+
+ g_signal_connect_swapped (impl, "accent-color-changed",
+ G_CALLBACK (set_accent_color), self);
+ }
}
static void
@@ -138,34 +195,49 @@ adw_settings_constructed (GObject *object)
AdwSettings *self = ADW_SETTINGS (object);
gboolean found_color_scheme = FALSE;
gboolean found_high_contrast = FALSE;
+ gboolean found_accent_colors = FALSE;
G_OBJECT_CLASS (adw_settings_parent_class)->constructed (object);
- init_debug (self, &found_color_scheme, &found_high_contrast);
+ init_debug (self, &found_color_scheme, &found_high_contrast, &found_accent_colors);
- if (!found_color_scheme || !found_high_contrast) {
+ if (!found_color_scheme || !found_high_contrast || !found_accent_colors) {
#ifdef __APPLE__
- self->platform_impl = adw_settings_impl_macos_new (!found_color_scheme, !found_high_contrast);
+ self->platform_impl = adw_settings_impl_macos_new (!found_color_scheme,
+ !found_high_contrast,
+ !found_accent_colors);
#elif defined(G_OS_WIN32)
- self->platform_impl = adw_settings_impl_win32_new (!found_color_scheme, !found_high_contrast);
+ self->platform_impl = adw_settings_impl_win32_new (!found_color_scheme,
+ !found_high_contrast,
+ !found_accent_colors);
#else
- self->platform_impl = adw_settings_impl_portal_new (!found_color_scheme, !found_high_contrast);
+ self->platform_impl = adw_settings_impl_portal_new (!found_color_scheme,
+ !found_high_contrast,
+ !found_accent_colors);
#endif
- register_impl (self, self->platform_impl, &found_color_scheme, &found_high_contrast);
+ register_impl (self, self->platform_impl, &found_color_scheme,
+ &found_high_contrast, &found_accent_colors);
}
- if (!found_color_scheme || !found_high_contrast) {
- self->gsettings_impl = adw_settings_impl_gsettings_new (!found_color_scheme, !found_high_contrast);
- register_impl (self, self->gsettings_impl, &found_color_scheme, &found_high_contrast);
+ if (!found_color_scheme || !found_high_contrast || !found_accent_colors) {
+ self->gsettings_impl = adw_settings_impl_gsettings_new (!found_color_scheme,
+ !found_high_contrast,
+ !found_accent_colors);
+ register_impl (self, self->gsettings_impl, &found_color_scheme,
+ &found_high_contrast, &found_accent_colors);
}
- if (!found_color_scheme || !found_high_contrast) {
- self->legacy_impl = adw_settings_impl_legacy_new (!found_color_scheme, !found_high_contrast);
- register_impl (self, self->legacy_impl, &found_color_scheme, &found_high_contrast);
+ if (!found_color_scheme || !found_high_contrast || !found_accent_colors) {
+ self->legacy_impl = adw_settings_impl_legacy_new (!found_color_scheme,
+ !found_high_contrast,
+ !found_accent_colors);
+ register_impl (self, self->legacy_impl, &found_color_scheme,
+ &found_high_contrast, &found_accent_colors);
}
self->system_supports_color_schemes = found_color_scheme;
+ self->system_supports_accent_colors = found_accent_colors;
}
static void
@@ -201,6 +273,14 @@ adw_settings_get_property (GObject *object,
g_value_set_boolean (value, adw_settings_get_high_contrast (self));
break;
+ case PROP_SYSTEM_SUPPORTS_ACCENT_COLORS:
+ g_value_set_boolean (value, adw_settings_get_system_supports_accent_colors (self));
+ break;
+
+ case PROP_ACCENT_COLOR:
+ g_value_set_enum (value, adw_settings_get_accent_color (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -231,6 +311,17 @@ adw_settings_class_init (AdwSettingsClass *klass)
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ props[PROP_SYSTEM_SUPPORTS_ACCENT_COLORS] =
+ g_param_spec_boolean ("system-supports-accent-colors", NULL, NULL,
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ props[PROP_ACCENT_COLOR] =
+ g_param_spec_enum ("accent-color", NULL, NULL,
+ ADW_TYPE_ACCENT_COLOR,
+ ADW_ACCENT_COLOR_BLUE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, LAST_PROP, props);
}
@@ -281,6 +372,28 @@ adw_settings_get_high_contrast (AdwSettings *self)
return self->high_contrast;
}
+gboolean
+adw_settings_get_system_supports_accent_colors (AdwSettings *self)
+{
+ g_return_val_if_fail (ADW_IS_SETTINGS (self), FALSE);
+
+ if (self->override)
+ return self->system_supports_accent_colors_override;
+
+ return self->system_supports_accent_colors;
+}
+
+AdwAccentColor
+adw_settings_get_accent_color (AdwSettings *self)
+{
+ g_return_val_if_fail (ADW_IS_SETTINGS (self), ADW_ACCENT_COLOR_BLUE);
+
+ if (self->override)
+ return self->accent_color_override;
+
+ return self->accent_color;
+}
+
void
adw_settings_start_override (AdwSettings *self)
{
@@ -294,12 +407,15 @@ adw_settings_start_override (AdwSettings *self)
self->system_supports_color_schemes_override = self->system_supports_color_schemes;
self->color_scheme_override = self->color_scheme;
self->high_contrast_override = self->high_contrast;
+ self->system_supports_accent_colors_override = self->system_supports_accent_colors;
+ self->accent_color_override = self->accent_color;
}
void
adw_settings_end_override (AdwSettings *self)
{
- gboolean notify_system_supports_color_scheme, notify_color_scheme, notify_hc;
+ gboolean notify_system_supports_color_scheme, notify_color_scheme, notify_hc,
+ notify_system_supports_accent_colors, notify_accent_color;
g_return_if_fail (ADW_IS_SETTINGS (self));
@@ -309,11 +425,15 @@ adw_settings_end_override (AdwSettings *self)
notify_system_supports_color_scheme = self->system_supports_color_schemes_override != self->system_supports_color_schemes;
notify_color_scheme = self->color_scheme_override != self->color_scheme;
notify_hc = self->high_contrast_override != self->high_contrast;
+ notify_system_supports_accent_colors = self->system_supports_accent_colors_override != self->system_supports_accent_colors;
+ notify_accent_color= self->accent_color_override != self->accent_color;
self->override = FALSE;
self->system_supports_color_schemes_override = FALSE;
self->color_scheme_override = ADW_SYSTEM_COLOR_SCHEME_DEFAULT;
self->high_contrast_override = FALSE;
+ self->system_supports_accent_colors_override = FALSE;
+ self->accent_color_override = ADW_ACCENT_COLOR_BLUE;
if (notify_system_supports_color_scheme)
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SYSTEM_SUPPORTS_COLOR_SCHEMES]);
@@ -321,6 +441,10 @@ adw_settings_end_override (AdwSettings *self)
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_COLOR_SCHEME]);
if (notify_hc)
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HIGH_CONTRAST]);
+ if (notify_system_supports_accent_colors)
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SYSTEM_SUPPORTS_ACCENT_COLORS]);
+ if (notify_accent_color)
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACCENT_COLOR]);
}
void
@@ -375,3 +499,39 @@ adw_settings_override_high_contrast (AdwSettings *self,
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HIGH_CONTRAST]);
}
+
+void
+adw_settings_override_system_supports_accent_colors (AdwSettings *self,
+ gboolean system_supports_accent_colors)
+{
+ g_return_if_fail (ADW_IS_SETTINGS (self));
+ g_return_if_fail (self->override);
+
+ system_supports_accent_colors = !!system_supports_accent_colors;
+
+ if (system_supports_accent_colors == self->system_supports_accent_colors_override)
+ return;
+
+ if (!system_supports_accent_colors)
+ adw_settings_override_accent_color (self, ADW_ACCENT_COLOR_BLUE);
+
+ self->system_supports_accent_colors_override = system_supports_accent_colors;
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SYSTEM_SUPPORTS_ACCENT_COLORS]);
+}
+
+void
+adw_settings_override_accent_color (AdwSettings *self,
+ AdwAccentColor accent_color)
+{
+ g_return_if_fail (ADW_IS_SETTINGS (self));
+ g_return_if_fail (self->override);
+
+ if (accent_color == self->accent_color_override ||
+ !self->system_supports_accent_colors_override)
+ return;
+
+ self->accent_color_override = accent_color;
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACCENT_COLOR]);
+}
diff --git a/src/adw-style-manager.c b/src/adw-style-manager.c
index cf2c14237c3e333283bad3143ed596fb7959bb92..39b800edae20d0f4c268f4abf65b0f275b95ea7f 100644
--- a/src/adw-style-manager.c
+++ b/src/adw-style-manager.c
@@ -10,6 +10,7 @@
#include "adw-style-manager-private.h"
+#include "adw-accent-color-private.h"
#include "adw-main-private.h"
#include "adw-settings-private.h"
#include
@@ -37,11 +38,13 @@
* A class for managing application-wide styling.
*
* `AdwStyleManager` provides a way to query and influence the application
- * styles, such as whether to use dark or high contrast appearance.
+ * styles, such as whether to use dark style, the system accent color or high
+ * contrast appearance.
*
* It allows to set the color scheme via the
* [property@StyleManager:color-scheme] property, and to query the current
- * appearance, as well as whether a system-wide color scheme preference exists.
+ * appearance, as well as whether a system-wide color scheme and accent color
+ * preferences exists.
*/
struct _AdwStyleManager
@@ -52,6 +55,7 @@ struct _AdwStyleManager
AdwSettings *settings;
GtkCssProvider *provider;
GtkCssProvider *colors_provider;
+ GtkCssProvider *accent_provider;
AdwColorScheme color_scheme;
gboolean dark;
@@ -70,6 +74,9 @@ enum {
PROP_SYSTEM_SUPPORTS_COLOR_SCHEMES,
PROP_DARK,
PROP_HIGH_CONTRAST,
+ PROP_SYSTEM_SUPPORTS_ACCENT_COLORS,
+ PROP_ACCENT_COLOR,
+ PROP_ACCENT_COLOR_RGBA,
LAST_PROP,
};
@@ -126,6 +133,25 @@ enable_animations_cb (AdwStyleManager *self)
self->animation_timeout_id = 0;
}
+static char*
+generate_accent_css (AdwStyleManager *self)
+{
+ AdwAccentColor accent = adw_style_manager_get_accent_color (self);
+ GString *str = g_string_new ("");
+ GdkRGBA rgba;
+ char *rgba_str;
+
+ adw_accent_color_to_rgba (accent, &rgba);
+ rgba_str = gdk_rgba_to_string (&rgba);
+
+ g_string_append_printf (str, "@define-color accent_bg_color %s;\n", rgba_str);
+ g_string_append (str, "@define-color accent_fg_color white;\n");
+
+ g_free (rgba_str);
+
+ return g_string_free (str, FALSE);
+}
+
static void
update_stylesheet (AdwStyleManager *self)
{
@@ -169,6 +195,12 @@ update_stylesheet (AdwStyleManager *self)
"/org/gnome/Adwaita/styles/defaults-light.css");
}
+ if (self->accent_provider) {
+ char *accent_css = generate_accent_css (self);
+ gtk_css_provider_load_from_string (self->accent_provider, accent_css);
+ g_free (accent_css);
+ }
+
self->animation_timeout_id =
g_timeout_add_once (SWITCH_DURATION,
(GSourceOnceFunc) enable_animations_cb,
@@ -219,6 +251,21 @@ notify_system_supports_color_schemes_cb (AdwStyleManager *self)
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SYSTEM_SUPPORTS_COLOR_SCHEMES]);
}
+static void
+notify_accent_color_cb (AdwStyleManager *self)
+{
+ update_stylesheet (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACCENT_COLOR]);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACCENT_COLOR_RGBA]);
+}
+
+static void
+notify_system_supports_accent_colors_cb (AdwStyleManager *self)
+{
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SYSTEM_SUPPORTS_ACCENT_COLORS]);
+}
+
static void
notify_high_contrast_cb (AdwStyleManager *self)
{
@@ -265,6 +312,11 @@ adw_style_manager_constructed (GObject *object)
gtk_style_context_add_provider_for_display (self->display,
GTK_STYLE_PROVIDER (self->colors_provider),
GTK_STYLE_PROVIDER_PRIORITY_THEME);
+
+ self->accent_provider = gtk_css_provider_new ();
+ gtk_style_context_add_provider_for_display (self->display,
+ GTK_STYLE_PROVIDER (self->accent_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_THEME);
}
self->animations_provider = gtk_css_provider_new ();
@@ -284,6 +336,16 @@ adw_style_manager_constructed (GObject *object)
G_CALLBACK (update_dark),
self,
G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->settings,
+ "notify::system-supports-accent-colors",
+ G_CALLBACK (notify_system_supports_accent_colors_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->settings,
+ "notify::accent-color",
+ G_CALLBACK (notify_accent_color_cb),
+ self,
+ G_CONNECT_SWAPPED);
g_signal_connect_object (self->settings,
"notify::high-contrast",
G_CALLBACK (notify_high_contrast_cb),
@@ -303,6 +365,7 @@ adw_style_manager_dispose (GObject *object)
g_clear_object (&self->provider);
g_clear_object (&self->colors_provider);
g_clear_object (&self->animations_provider);
+ g_clear_object (&self->accent_provider);
G_OBJECT_CLASS (adw_style_manager_parent_class)->dispose (object);
}
@@ -336,6 +399,18 @@ adw_style_manager_get_property (GObject *object,
g_value_set_boolean (value, adw_style_manager_get_high_contrast (self));
break;
+ case PROP_SYSTEM_SUPPORTS_ACCENT_COLORS:
+ g_value_set_boolean (value, adw_style_manager_get_system_supports_accent_colors (self));
+ break;
+
+ case PROP_ACCENT_COLOR:
+ g_value_set_enum (value, adw_style_manager_get_accent_color (self));
+ break;
+
+ case PROP_ACCENT_COLOR_RGBA:
+ g_value_take_boxed (value, adw_style_manager_get_accent_color_rgba (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -468,6 +543,56 @@ adw_style_manager_class_init (AdwStyleManagerClass *klass)
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ /**
+ * AdwStyleManager:system-supports-accent-colors:
+ *
+ * Whether the system supports accent colors.
+ *
+ * This property can be used to check if the current environment provides an
+ * accent color preference. For example, applications might want to show a
+ * preference for choosing accent color if it's set to `FALSE`.
+ *
+ * See [property@StyleManager:accent-color].
+ *
+ * Since: 1.6
+ */
+ props[PROP_SYSTEM_SUPPORTS_ACCENT_COLORS] =
+ g_param_spec_boolean ("system-supports-accent-colors", NULL, NULL,
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * AdwStyleManager:accent-color:
+ *
+ * The current system accent color.
+ *
+ * See also [property@StyleManager:accent-color-rgba].
+ *
+ * Since: 1.6
+ */
+ props[PROP_ACCENT_COLOR] =
+ g_param_spec_enum ("accent-color", NULL, NULL,
+ ADW_TYPE_ACCENT_COLOR,
+ ADW_ACCENT_COLOR_BLUE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * AdwStyleManager:accent-color-rgba:
+ *
+ * The current system accent color as a `GdkRGBA`.
+ *
+ * Equivalent to calling [func@AccentColor.to_rgba] on the value of
+ * [property@StyleManager:accent-color].
+ *
+ * This is a background color. The matching foreground color is white.
+ *
+ * Since: 1.6
+ */
+ props[PROP_ACCENT_COLOR_RGBA] =
+ g_param_spec_boxed ("accent-color-rgba", NULL, NULL,
+ GDK_TYPE_RGBA,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, LAST_PROP, props);
}
@@ -712,3 +837,75 @@ adw_style_manager_get_high_contrast (AdwStyleManager *self)
return adw_settings_get_high_contrast (self->settings);
}
+
+/**
+ * adw_style_manager_get_system_supports_accent_colors:
+ * @self: a style manager
+ *
+ * Gets whether the system supports accent colors.
+ *
+ * This can be used to check if the current environment provides an accent color
+ * preference. For example, applications might want to show a preference for
+ * choosing accent color if it's set to `FALSE`.
+ *
+ * See [property@StyleManager:accent-color].
+ *
+ * Since: 1.6
+ */
+gboolean
+adw_style_manager_get_system_supports_accent_colors (AdwStyleManager *self)
+{
+ g_return_val_if_fail (ADW_IS_STYLE_MANAGER (self), FALSE);
+
+ return adw_settings_get_system_supports_accent_colors (self->settings);
+}
+
+/**
+ * adw_style_manager_get_accent_color:
+ * @self: a style manager
+ *
+ * Gets the current system accent color.
+ *
+ * See also [property@StyleManager:accent-color-rgba].
+ *
+ * Returns: the current system accent color
+ *
+ * Since: 1.6
+ */
+AdwAccentColor
+adw_style_manager_get_accent_color (AdwStyleManager *self)
+{
+ g_return_val_if_fail (ADW_IS_STYLE_MANAGER (self), ADW_ACCENT_COLOR_BLUE);
+
+ return adw_settings_get_accent_color (self->settings);
+}
+
+/**
+ * adw_style_manager_get_accent_color_rgba:
+ * @self: a style manager
+ *
+ * Gets the current system accent color as a `GdkRGBA`.
+ *
+ * Equivalent to calling [func@AccentColor.to_rgba] on the value of
+ * [property@StyleManager:accent-color].
+ *
+ * This is a background color. The matching foreground color is white.
+ *
+ * Returns: the current system accent color
+ *
+ * Since: 1.6
+ */
+GdkRGBA *
+adw_style_manager_get_accent_color_rgba (AdwStyleManager *self)
+{
+ AdwAccentColor color;
+ GdkRGBA rgba;
+
+ g_return_val_if_fail (ADW_IS_STYLE_MANAGER (self), NULL);
+
+ color = adw_style_manager_get_accent_color (self);
+
+ adw_accent_color_to_rgba (color, &rgba);
+
+ return gdk_rgba_copy (&rgba);
+}
diff --git a/src/adw-style-manager.h b/src/adw-style-manager.h
index dce27c2e0df5824ad9a3a2fe6aaa9ddedc8a14a5..b00b6c99a13771db56c764c7c73af69744902456 100644
--- a/src/adw-style-manager.h
+++ b/src/adw-style-manager.h
@@ -15,6 +15,8 @@
#include "adw-version.h"
#include
+
+#include "adw-accent-color.h"
#include "adw-enums.h"
G_BEGIN_DECLS
@@ -54,4 +56,13 @@ gboolean adw_style_manager_get_dark (AdwStyleManager *self);
ADW_AVAILABLE_IN_ALL
gboolean adw_style_manager_get_high_contrast (AdwStyleManager *self);
+ADW_AVAILABLE_IN_1_6
+gboolean adw_style_manager_get_system_supports_accent_colors (AdwStyleManager *self);
+
+ADW_AVAILABLE_IN_1_6
+AdwAccentColor adw_style_manager_get_accent_color (AdwStyleManager *self);
+
+ADW_AVAILABLE_IN_1_6
+GdkRGBA *adw_style_manager_get_accent_color_rgba (AdwStyleManager *self);
+
G_END_DECLS
diff --git a/src/adwaita.h b/src/adwaita.h
index 6593b55e87d5883fca8c5d607a9049905eb8134a..bca7880798ad73d5a409273e0c73cea51bf332c5 100644
--- a/src/adwaita.h
+++ b/src/adwaita.h
@@ -23,6 +23,7 @@ G_BEGIN_DECLS
#include "adw-version.h"
#include "adw-about-dialog.h"
#include "adw-about-window.h"
+#include "adw-accent-color.h"
#include "adw-action-row.h"
#include "adw-alert-dialog.h"
#include "adw-animation.h"
diff --git a/src/meson.build b/src/meson.build
index b1b43f90049567c2e2d054e19f33f1cd8508b2e3..19be77d217d331c752ca1e0715e2eee8220c3c45 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -11,6 +11,7 @@ libadwaita_resources = gnome.compile_resources(
)
adw_public_enum_headers = [
+ 'adw-accent-color.h',
'adw-alert-dialog.h',
'adw-animation.h',
'adw-banner.h',
@@ -98,6 +99,7 @@ libadwaita_private_sources += adw_marshalers
src_headers = [
'adw-about-dialog.h',
'adw-about-window.h',
+ 'adw-accent-color.h',
'adw-action-row.h',
'adw-alert-dialog.h',
'adw-animation.h',
@@ -183,6 +185,7 @@ libadwaita_init_public_types = custom_target('adw-public-types.c',
src_sources = [
'adw-about-dialog.c',
'adw-about-window.c',
+ 'adw-accent-color.c',
'adw-action-row.c',
'adw-alert-dialog.c',
'adw-animation.c',
@@ -261,6 +264,8 @@ src_sources = [
libadwaita_private_sources += files([
'adw-back-button.c',
'adw-bidi.c',
+ 'adw-bottom-sheet.c',
+ 'adw-color-utils.c',
'adw-dialog-host.c',
'adw-fading-label.c',
'adw-floating-sheet.c',
@@ -390,7 +395,6 @@ endif
libadwaita = library(
'adwaita-' + apiversion,
libadwaita_sources,
-
soversion: soversion,
c_args: libadwaita_c_args,
dependencies: libadwaita_deps,
@@ -408,6 +412,28 @@ libadwaita_dep = declare_dependency(
include_directories: include_directories('.'),
)
+if get_option('tests')
+ libadwaita_internal = library(
+ 'adwaita-' + apiversion + '-internal',
+ libadwaita_sources,
+
+ soversion: soversion,
+ c_args: libadwaita_c_args,
+ dependencies: libadwaita_deps,
+ include_directories: [ root_inc, src_inc ],
+ install: true,
+ link_args: libadwaita_link_args,
+ install_dir: adwaita_libdir,
+ )
+
+ libadwaita_internal_dep = declare_dependency(
+ sources: libadwaita_generated_headers,
+ dependencies: libadwaita_public_deps,
+ link_with: libadwaita_internal,
+ include_directories: include_directories('.'),
+ )
+endif
+
meson.override_dependency(package_api_name, libadwaita_dep)
if introspection
@@ -458,4 +484,3 @@ pkgg.generate(
requires: 'gtk4',
install_dir: libdir / 'pkgconfig',
)
-
diff --git a/src/stylesheet/_colors.scss b/src/stylesheet/_colors.scss
index 3eea3fef268a07e3e1920557f8d257e974b40d26..b1524a0475bd2900d81668996257a3d0223f8cdf 100644
--- a/src/stylesheet/_colors.scss
+++ b/src/stylesheet/_colors.scss
@@ -4,6 +4,16 @@ $focus_border_opacity: if($contrast == 'high', 80%, 50%);
// Colors from _defaults.scss
:root {
+ --accent-blue: #3584e4;
+ --accent-teal: #2190a4;
+ --accent-green: #3a944a;
+ --accent-yellow: #c88800;
+ --accent-orange: #ed5b00;
+ --accent-red: #e62d42;
+ --accent-pink: #d56199;
+ --accent-purple: #9141ac;
+ --accent-slate: #6f8396;
+
--accent-bg-color: @accent_bg_color;
--accent-fg-color: @accent_fg_color;
diff --git a/src/stylesheet/_defaults.scss b/src/stylesheet/_defaults.scss
index c505894592f49cc175b562ff711161f2cc44768a..b24acf2186590aa6013ed9b01e74c650725db661 100644
--- a/src/stylesheet/_defaults.scss
+++ b/src/stylesheet/_defaults.scss
@@ -8,10 +8,6 @@
// These are the colors apps are can override. We define the defaults here and
// define variables for them in _colors.scss
-// The main accent color and the matching text value
-@define-color accent_bg_color @blue_3;
-@define-color accent_fg_color white;
-
// destructive-action buttons
@define-color destructive_bg_color #{if($variant == 'light', "@red_3", "@red_4")};
@define-color destructive_fg_color white;
diff --git a/src/stylesheet/_widgets.scss b/src/stylesheet/_widgets.scss
index 471d0a9045fd8744a0dc6fd390a469f9ee8da1cc..9dacdd555e55ae6020938bcca47d2299927934fe 100644
--- a/src/stylesheet/_widgets.scss
+++ b/src/stylesheet/_widgets.scss
@@ -13,6 +13,7 @@
@import 'widgets/expanders';
@import 'widgets/file-chooser';
@import 'widgets/header-bar';
+@import 'widgets/inspector';
@import 'widgets/labels';
@import 'widgets/level-bar';
@import 'widgets/linked';
diff --git a/src/stylesheet/meson.build b/src/stylesheet/meson.build
index f1f09dc4bab0ba7c975304d03e9e4aef2a11dab1..733585108bbb3f76bf3fc24a809d49a22d89da92 100644
--- a/src/stylesheet/meson.build
+++ b/src/stylesheet/meson.build
@@ -37,6 +37,7 @@ if not fs.exists('base.css')
'widgets/_expanders.scss',
'widgets/_file-chooser.scss',
'widgets/_header-bar.scss',
+ 'widgets/_inspector.scss',
'widgets/_labels.scss',
'widgets/_level-bar.scss',
'widgets/_linked.scss',
diff --git a/src/stylesheet/widgets/_inspector.scss b/src/stylesheet/widgets/_inspector.scss
new file mode 100644
index 0000000000000000000000000000000000000000..b9f00cbcbd1005a5f0de3e33066c60df3a37a94e
--- /dev/null
+++ b/src/stylesheet/widgets/_inspector.scss
@@ -0,0 +1,9 @@
+.accent-color-row color {
+ min-width: 16px;
+ min-height: 16px;
+ border-radius: 16px;
+}
+
+.accent-color-row color:disabled {
+ opacity: var(--disabled-opacity);
+}
diff --git a/tests/meson.build b/tests/meson.build
index 933a33b34b953df1a56724dd52cb809e86debed1..6e8d5581ffcbb9e5d214dd2e70db98bc982d17de 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -34,6 +34,7 @@ endif
test_names = [
'test-about-dialog',
'test-about-window',
+ 'test-accent-color',
'test-action-row',
'test-alert-dialog',
'test-animation',
@@ -99,7 +100,7 @@ foreach test_name : test_names
t = executable(test_name, test_sources,
c_args: test_cflags,
link_args: test_link_args,
- dependencies: libadwaita_deps + [libadwaita_dep],
+ dependencies: libadwaita_deps + [libadwaita_internal_dep],
pie: use_pie,
)
test(test_name, t, env: test_env)
diff --git a/tests/test-accent-color.c b/tests/test-accent-color.c
new file mode 100644
index 0000000000000000000000000000000000000000..9625735ff757a5d07e196bf2a8ebce4eb171adef
--- /dev/null
+++ b/tests/test-accent-color.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2024 Alice Mikhaylenko
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include
+
+#include "adw-accent-color-private.h"
+
+#include
+
+static inline int
+rgba_to_hex (GdkRGBA *rgba)
+{
+ return (int) (round (rgba->red * 0xff)) << 16 |
+ (int) (round (rgba->green * 0xff)) << 8 |
+ (int) (round (rgba->blue * 0xff));
+}
+
+static inline void
+hex_to_rgba (int hex,
+ GdkRGBA *rgba)
+{
+ rgba->red = (float) ((hex >> 16) & 0xff) / 0xff;
+ rgba->green = (float) ((hex >> 8) & 0xff) / 0xff;
+ rgba->blue = (float) ((hex) & 0xff) / 0xff;
+ rgba->alpha = 1;
+}
+
+#define TEST_NEAREST_ACCENT(rgba_str, expected) \
+ gdk_rgba_parse (&rgba, rgba_str); \
+ g_assert_cmpint (expected, ==, adw_accent_color_nearest_from_rgba (&rgba));
+
+#define TEST_ACCENT_TO_RGBA(accent, expected) \
+ adw_accent_color_to_rgba (accent, &rgba); \
+ hex = rgba_to_hex (&rgba); \
+ g_assert_cmphex (expected, ==, hex);
+
+#define TEST_ACCENT_TO_STANDALONE_RGBA(accent, dark, expected) \
+ adw_accent_color_to_standalone_rgba (accent, dark, &rgba); \
+ hex = rgba_to_hex (&rgba); \
+ g_assert_cmphex (expected, ==, hex);
+
+#define TEST_RGBA_TO_STANDALONE(rgba_str, dark, expected) \
+ hex_to_rgba (rgba_str, &rgba); \
+ adw_rgba_to_standalone (&rgba, dark, &rgba); \
+ hex = rgba_to_hex (&rgba); \
+ g_assert_cmphex (expected, ==, hex);
+
+static void
+test_adw_accent_color_nearest_from_rgba (void)
+{
+ GdkRGBA rgba;
+
+ /* Roundtrip */
+ for (int i = 0; i <= ADW_ACCENT_COLOR_SLATE; i++) {
+ adw_accent_color_to_rgba (i, &rgba);
+ g_assert_cmpint (i, ==, adw_accent_color_nearest_from_rgba (&rgba));
+ }
+
+ /* Icon palette */
+ TEST_NEAREST_ACCENT ("#99c1f1", ADW_ACCENT_COLOR_BLUE); /* blue 1 */
+ TEST_NEAREST_ACCENT ("#62a0ea", ADW_ACCENT_COLOR_BLUE); /* blue 2 */
+ TEST_NEAREST_ACCENT ("#3584e4", ADW_ACCENT_COLOR_BLUE); /* blue 3 */
+ TEST_NEAREST_ACCENT ("#1c71d8", ADW_ACCENT_COLOR_BLUE); /* blue 4 */
+ TEST_NEAREST_ACCENT ("#1a5fb4", ADW_ACCENT_COLOR_BLUE); /* blue 5 */
+ TEST_NEAREST_ACCENT ("#8ff0a4", ADW_ACCENT_COLOR_GREEN); /* green 1 */
+ TEST_NEAREST_ACCENT ("#57e389", ADW_ACCENT_COLOR_GREEN); /* green 2 */
+ TEST_NEAREST_ACCENT ("#33d17a", ADW_ACCENT_COLOR_GREEN); /* green 3 */
+ TEST_NEAREST_ACCENT ("#2ec27e", ADW_ACCENT_COLOR_GREEN); /* green 4 */
+ TEST_NEAREST_ACCENT ("#26a269", ADW_ACCENT_COLOR_GREEN); /* green 5 */
+ TEST_NEAREST_ACCENT ("#f9f06b", ADW_ACCENT_COLOR_YELLOW); /* yellow 1 */
+ TEST_NEAREST_ACCENT ("#f8e45c", ADW_ACCENT_COLOR_YELLOW); /* yellow 2 */
+ TEST_NEAREST_ACCENT ("#f6d32d", ADW_ACCENT_COLOR_YELLOW); /* yellow 3 */
+ TEST_NEAREST_ACCENT ("#f5c211", ADW_ACCENT_COLOR_YELLOW); /* yellow 4 */
+ TEST_NEAREST_ACCENT ("#e5a50a", ADW_ACCENT_COLOR_YELLOW); /* yellow 5 */
+ TEST_NEAREST_ACCENT ("#ffbe6f", ADW_ACCENT_COLOR_ORANGE); /* orange 1 */
+ TEST_NEAREST_ACCENT ("#ffa348", ADW_ACCENT_COLOR_ORANGE); /* orange 2 */
+ TEST_NEAREST_ACCENT ("#ff7800", ADW_ACCENT_COLOR_ORANGE); /* orange 3 */
+ TEST_NEAREST_ACCENT ("#e66100", ADW_ACCENT_COLOR_ORANGE); /* orange 4 */
+ TEST_NEAREST_ACCENT ("#c64600", ADW_ACCENT_COLOR_ORANGE); /* orange 5 */
+ TEST_NEAREST_ACCENT ("#f66151", ADW_ACCENT_COLOR_RED); /* red 1 */
+ TEST_NEAREST_ACCENT ("#ed333b", ADW_ACCENT_COLOR_RED); /* red 2 */
+ TEST_NEAREST_ACCENT ("#e01b24", ADW_ACCENT_COLOR_RED); /* red 3 */
+ TEST_NEAREST_ACCENT ("#c01c28", ADW_ACCENT_COLOR_RED); /* red 4 */
+ TEST_NEAREST_ACCENT ("#a51d2d", ADW_ACCENT_COLOR_RED); /* red 5 */
+ TEST_NEAREST_ACCENT ("#dc8add", ADW_ACCENT_COLOR_PURPLE); /* purple 1 */
+ TEST_NEAREST_ACCENT ("#c061cb", ADW_ACCENT_COLOR_PURPLE); /* purple 2 */
+ TEST_NEAREST_ACCENT ("#9141ac", ADW_ACCENT_COLOR_PURPLE); /* purple 3 */
+ TEST_NEAREST_ACCENT ("#813d9c", ADW_ACCENT_COLOR_PURPLE); /* purple 4 */
+ TEST_NEAREST_ACCENT ("#613583", ADW_ACCENT_COLOR_PURPLE); /* purple 5 */
+ TEST_NEAREST_ACCENT ("#cdab8f", ADW_ACCENT_COLOR_ORANGE); /* brown 1 */
+ TEST_NEAREST_ACCENT ("#b5835a", ADW_ACCENT_COLOR_ORANGE); /* brown 2 */
+ TEST_NEAREST_ACCENT ("#986a44", ADW_ACCENT_COLOR_ORANGE); /* brown 3 */
+ TEST_NEAREST_ACCENT ("#865e3c", ADW_ACCENT_COLOR_ORANGE); /* brown 4 */
+ TEST_NEAREST_ACCENT ("#63452c", ADW_ACCENT_COLOR_ORANGE); /* brown 5 */
+ TEST_NEAREST_ACCENT ("#ffffff", ADW_ACCENT_COLOR_SLATE); /* light 1 */
+ TEST_NEAREST_ACCENT ("#f6f5f4", ADW_ACCENT_COLOR_SLATE); /* light 2 */
+ TEST_NEAREST_ACCENT ("#deddda", ADW_ACCENT_COLOR_SLATE); /* light 3 */
+ TEST_NEAREST_ACCENT ("#c0bfbc", ADW_ACCENT_COLOR_SLATE); /* light 4 */
+ TEST_NEAREST_ACCENT ("#9a9996", ADW_ACCENT_COLOR_SLATE); /* light 5 */
+ TEST_NEAREST_ACCENT ("#77767b", ADW_ACCENT_COLOR_SLATE); /* dark 1 */
+ TEST_NEAREST_ACCENT ("#5e5c64", ADW_ACCENT_COLOR_SLATE); /* dark 2 */
+ TEST_NEAREST_ACCENT ("#3d3846", ADW_ACCENT_COLOR_SLATE); /* dark 3 */
+ TEST_NEAREST_ACCENT ("#241f31", ADW_ACCENT_COLOR_SLATE); /* dark 4 */
+ TEST_NEAREST_ACCENT ("#000000", ADW_ACCENT_COLOR_SLATE); /* dark 5 */
+
+ /* elementary */
+ TEST_NEAREST_ACCENT ("#3689e6", ADW_ACCENT_COLOR_BLUE); /* blueberry */
+ TEST_NEAREST_ACCENT ("#28bca3", ADW_ACCENT_COLOR_TEAL); /* mint */
+ TEST_NEAREST_ACCENT ("#68b723", ADW_ACCENT_COLOR_GREEN); /* lime */
+ TEST_NEAREST_ACCENT ("#f9c440", ADW_ACCENT_COLOR_YELLOW); /* banana */
+ TEST_NEAREST_ACCENT ("#ffa154", ADW_ACCENT_COLOR_ORANGE); /* orange */
+ TEST_NEAREST_ACCENT ("#ed5353", ADW_ACCENT_COLOR_RED); /* strawberry */
+ TEST_NEAREST_ACCENT ("#de3e80", ADW_ACCENT_COLOR_PINK); /* bubblegum */
+ TEST_NEAREST_ACCENT ("#a56de2", ADW_ACCENT_COLOR_PURPLE); /* grape */
+ TEST_NEAREST_ACCENT ("#8a715e", ADW_ACCENT_COLOR_ORANGE); /* cocoa */
+ TEST_NEAREST_ACCENT ("#667885", ADW_ACCENT_COLOR_SLATE); /* slate */
+
+ /* KDE (light) */
+ TEST_NEAREST_ACCENT ("#ef75b8", ADW_ACCENT_COLOR_PINK);
+ TEST_NEAREST_ACCENT ("#ef778a", ADW_ACCENT_COLOR_RED);
+ TEST_NEAREST_ACCENT ("#ef9275", ADW_ACCENT_COLOR_ORANGE);
+ TEST_NEAREST_ACCENT ("#eeda6b", ADW_ACCENT_COLOR_YELLOW);
+ TEST_NEAREST_ACCENT ("#77e066", ADW_ACCENT_COLOR_GREEN);
+ TEST_NEAREST_ACCENT ("#4ce0cd", ADW_ACCENT_COLOR_TEAL);
+ TEST_NEAREST_ACCENT ("#77c6ef", ADW_ACCENT_COLOR_BLUE);
+ TEST_NEAREST_ACCENT ("#cd9ee6", ADW_ACCENT_COLOR_PURPLE);
+ TEST_NEAREST_ACCENT ("#b299ec", ADW_ACCENT_COLOR_PURPLE);
+ TEST_NEAREST_ACCENT ("#95979a", ADW_ACCENT_COLOR_SLATE);
+
+ /* KDE (dark) */
+ TEST_NEAREST_ACCENT ("#ab3175", ADW_ACCENT_COLOR_PINK);
+ TEST_NEAREST_ACCENT ("#ab3347", ADW_ACCENT_COLOR_RED);
+ TEST_NEAREST_ACCENT ("#ab4f32", ADW_ACCENT_COLOR_ORANGE);
+ TEST_NEAREST_ACCENT ("#aa9729", ADW_ACCENT_COLOR_YELLOW);
+ TEST_NEAREST_ACCENT ("#329d23", ADW_ACCENT_COLOR_GREEN);
+ TEST_NEAREST_ACCENT ("#089c8a", ADW_ACCENT_COLOR_TEAL);
+ TEST_NEAREST_ACCENT ("#3282ac", ADW_ACCENT_COLOR_BLUE);
+ TEST_NEAREST_ACCENT ("#885aa3", ADW_ACCENT_COLOR_PURPLE);
+ TEST_NEAREST_ACCENT ("#6e56a9", ADW_ACCENT_COLOR_PURPLE);
+ TEST_NEAREST_ACCENT ("#505357", ADW_ACCENT_COLOR_SLATE);
+
+ /* Ubuntu */
+ TEST_NEAREST_ACCENT ("#e95420", ADW_ACCENT_COLOR_ORANGE);
+ TEST_NEAREST_ACCENT ("#787859", ADW_ACCENT_COLOR_YELLOW); /* bark */
+ TEST_NEAREST_ACCENT ("#657b69", ADW_ACCENT_COLOR_SLATE); /* sage */
+ TEST_NEAREST_ACCENT ("#4b8501", ADW_ACCENT_COLOR_GREEN); /* olive */
+ TEST_NEAREST_ACCENT ("#03875b", ADW_ACCENT_COLOR_GREEN); /* viridian */
+ TEST_NEAREST_ACCENT ("#308280", ADW_ACCENT_COLOR_TEAL); /* prussian green */
+ TEST_NEAREST_ACCENT ("#0073e5", ADW_ACCENT_COLOR_BLUE);
+ TEST_NEAREST_ACCENT ("#7764d8", ADW_ACCENT_COLOR_PURPLE);
+ TEST_NEAREST_ACCENT ("#b34cb3", ADW_ACCENT_COLOR_PURPLE); /* magenta */
+ TEST_NEAREST_ACCENT ("#da3450", ADW_ACCENT_COLOR_RED);
+
+ /* Cinnamon */
+ TEST_NEAREST_ACCENT ("#0c75de", ADW_ACCENT_COLOR_BLUE);
+ TEST_NEAREST_ACCENT ("#1f9ede", ADW_ACCENT_COLOR_BLUE);
+ TEST_NEAREST_ACCENT ("#199ca8", ADW_ACCENT_COLOR_TEAL);
+ TEST_NEAREST_ACCENT ("#35a854", ADW_ACCENT_COLOR_GREEN);
+ TEST_NEAREST_ACCENT ("#c5a07c", ADW_ACCENT_COLOR_ORANGE);
+ TEST_NEAREST_ACCENT ("#70737a", ADW_ACCENT_COLOR_SLATE);
+ TEST_NEAREST_ACCENT ("#ff7139", ADW_ACCENT_COLOR_ORANGE);
+ TEST_NEAREST_ACCENT ("#e82127", ADW_ACCENT_COLOR_RED);
+ TEST_NEAREST_ACCENT ("#e54980", ADW_ACCENT_COLOR_PINK);
+ TEST_NEAREST_ACCENT ("#8c5dd9", ADW_ACCENT_COLOR_PURPLE);
+
+ /* COSMIC */
+ TEST_NEAREST_ACCENT ("#63d0df", ADW_ACCENT_COLOR_TEAL);
+ TEST_NEAREST_ACCENT ("#a1c0eb", ADW_ACCENT_COLOR_BLUE);
+ TEST_NEAREST_ACCENT ("#e79cfe", ADW_ACCENT_COLOR_PURPLE);
+ TEST_NEAREST_ACCENT ("#ff9cb1", ADW_ACCENT_COLOR_PINK);
+ TEST_NEAREST_ACCENT ("#fda1a0", ADW_ACCENT_COLOR_RED);
+ TEST_NEAREST_ACCENT ("#ffad00", ADW_ACCENT_COLOR_ORANGE);
+ TEST_NEAREST_ACCENT ("#f7e062", ADW_ACCENT_COLOR_YELLOW);
+ TEST_NEAREST_ACCENT ("#92cf9c", ADW_ACCENT_COLOR_GREEN);
+ TEST_NEAREST_ACCENT ("#cabab4", ADW_ACCENT_COLOR_SLATE);
+
+ /* macOS */
+ TEST_NEAREST_ACCENT ("#017bff", ADW_ACCENT_COLOR_BLUE);
+ TEST_NEAREST_ACCENT ("#a550a7", ADW_ACCENT_COLOR_PURPLE);
+ TEST_NEAREST_ACCENT ("#f8509e", ADW_ACCENT_COLOR_PINK);
+ TEST_NEAREST_ACCENT ("#ff5257", ADW_ACCENT_COLOR_RED);
+ TEST_NEAREST_ACCENT ("#f7821a", ADW_ACCENT_COLOR_ORANGE);
+ TEST_NEAREST_ACCENT ("#ffc602", ADW_ACCENT_COLOR_YELLOW);
+ TEST_NEAREST_ACCENT ("#62ba46", ADW_ACCENT_COLOR_GREEN);
+ TEST_NEAREST_ACCENT ("#8c8c8c", ADW_ACCENT_COLOR_SLATE);
+}
+
+static void
+test_adw_accent_color_to_rgba (void)
+{
+ GdkRGBA rgba;
+ int hex;
+
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_BLUE, 0x3584e4);
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_TEAL, 0x2190a4);
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_GREEN, 0x3a944a);
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_YELLOW, 0xc88800);
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_ORANGE, 0xed5b00);
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_RED, 0xe62d42);
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_PINK, 0xd56199);
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_PURPLE, 0x9141ac);
+ TEST_ACCENT_TO_RGBA (ADW_ACCENT_COLOR_SLATE, 0x6f8396);
+}
+
+static void
+test_adw_accent_color_to_standalone_rgba (void)
+{
+ GdkRGBA rgba;
+ int hex;
+
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_BLUE, FALSE, 0x0461be);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_TEAL, FALSE, 0x007184);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_GREEN, FALSE, 0x15772e);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_YELLOW, FALSE, 0x905300);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_ORANGE, FALSE, 0xb62200);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_RED, FALSE, 0xc00023);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_PINK, FALSE, 0xa2326c);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_PURPLE, FALSE, 0x8939a4);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_SLATE, FALSE, 0x526678);
+
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_BLUE, TRUE, 0x81d0ff);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_TEAL, TRUE, 0x7bdff4);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_GREEN, TRUE, 0x8de698);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_YELLOW, TRUE, 0xffc057);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_ORANGE, TRUE, 0xff9c5b);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_RED, TRUE, 0xff888c);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_PINK, TRUE, 0xffa0d8);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_PURPLE, TRUE, 0xfba7ff);
+ TEST_ACCENT_TO_STANDALONE_RGBA (ADW_ACCENT_COLOR_SLATE, TRUE, 0xbbd1e5);
+}
+
+static void
+test_adw_accent_color_rgba_to_standalone (void)
+{
+ GdkRGBA rgba;
+ int hex;
+
+ TEST_RGBA_TO_STANDALONE (0x3584e4, FALSE, 0x0461be);
+ TEST_RGBA_TO_STANDALONE (0x3584e4, TRUE, 0x81d0ff);
+
+ TEST_RGBA_TO_STANDALONE (0xffffff, FALSE, 0x636363);
+ TEST_RGBA_TO_STANDALONE (0xffffff, TRUE, 0xffffff);
+
+ TEST_RGBA_TO_STANDALONE (0x000000, FALSE, 0x000000);
+ TEST_RGBA_TO_STANDALONE (0x000000, TRUE, 0xcecece);
+
+ TEST_RGBA_TO_STANDALONE (0x959595, FALSE, 0x636363);
+ TEST_RGBA_TO_STANDALONE (0x959595, TRUE, 0xcecece);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ gtk_test_init (&argc, &argv, NULL);
+ adw_init ();
+
+ g_test_add_func ("/Adwaita/AccentColor/nearest_from_rgba", test_adw_accent_color_nearest_from_rgba);
+ g_test_add_func ("/Adwaita/AccentColor/to_rgba", test_adw_accent_color_to_rgba);
+ g_test_add_func ("/Adwaita/AccentColor/to_standalone_rgba", test_adw_accent_color_to_standalone_rgba);
+ g_test_add_func ("/Adwaita/AccentColor/rgba_to_standalone", test_adw_accent_color_rgba_to_standalone);
+
+ return g_test_run ();
+}