diff --git a/demo/GraniteDemo.vala b/demo/GraniteDemo.vala index 9e4d8d305..9d47d3087 100644 --- a/demo/GraniteDemo.vala +++ b/demo/GraniteDemo.vala @@ -11,6 +11,7 @@ public class Granite.Demo : Gtk.Application { public override void startup () { Granite.init (); + base.startup (); } @@ -95,6 +96,7 @@ public class Granite.Demo : Gtk.Application { }; var granite_settings = Granite.Settings.get_default (); + gtk_settings.gtk_theme_name = "io.elementary.stylesheet.blueberry"; gtk_settings.gtk_application_prefer_dark_theme = granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK; window.child = paned; diff --git a/lib/Init.vala b/lib/Init.vala index 98472c582..b4839adb9 100644 --- a/lib/Init.vala +++ b/lib/Init.vala @@ -7,6 +7,7 @@ namespace Granite { private static bool initialized = false; private static Gtk.CssProvider? base_provider = null; private static Gtk.CssProvider? dark_provider = null; + private static Gtk.CssProvider? accent_provider = null; private static Gtk.CssProvider? app_provider = null; /** @@ -41,12 +42,28 @@ namespace Granite { set_provider_for_display (display, gtk_settings.gtk_application_prefer_dark_theme); }); + var granite_settings = Granite.Settings.get_default (); + granite_settings.notify["accent-color"].connect (() => { + set_accent_for_display (display, granite_settings.accent_color.to_string ()); + }); + set_provider_for_display (display, gtk_settings.gtk_application_prefer_dark_theme); + set_accent_for_display (display, granite_settings.accent_color.to_string ()); var icon_theme = Gtk.IconTheme.get_for_display (display); icon_theme.add_resource_path ("/io/elementary/granite"); } + private static void set_accent_for_display (Gdk.Display display, string accent_color) { + if (accent_provider == null) { + accent_provider = new Gtk.CssProvider (); + } + + Gtk.StyleContext.remove_provider_for_display (display, accent_provider); + accent_provider.load_from_string ("@define-color accent_color %s;".printf (accent_color)); + Gtk.StyleContext.add_provider_for_display (display, accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION - 1); + } + private static void set_provider_for_display (Gdk.Display display, bool prefer_dark_style) { if (app_provider == null) { var base_path = Application.get_default ().resource_base_path; diff --git a/lib/Styles/Index-dark.scss b/lib/Styles/Index-dark.scss index 1a4f21c12..7bf8d82df 100644 --- a/lib/Styles/Index-dark.scss +++ b/lib/Styles/Index-dark.scss @@ -43,6 +43,7 @@ $warning-color: $BANANA_100; $warning-icon-color: $BANANA_500; // Common styles +@import '_exported.scss'; @import '_label.scss'; @import '_osd.scss'; diff --git a/lib/Styles/Index.scss b/lib/Styles/Index.scss index f302b64b0..eafae2d2b 100644 --- a/lib/Styles/Index.scss +++ b/lib/Styles/Index.scss @@ -43,6 +43,7 @@ $warning_color: $BANANA_900; $warning-icon-color: mix($BANANA_500, $BANANA_700, $weight: 50%); // Common styles +@import '_exported.scss'; @import '_label.scss'; @import '_osd.scss'; diff --git a/lib/Styles/_exported.scss b/lib/Styles/_exported.scss new file mode 100644 index 000000000..2749bfc61 --- /dev/null +++ b/lib/Styles/_exported.scss @@ -0,0 +1,8 @@ +// These are defined as GtkCSS variables, so are accessible and overridable +// inside of apps. While internal sass variables are considered private API, +// these exported GtkCSS variables should be considered public API. + +@define-color base_color #{"" + bg_color(1)}; +@define-color bg_color #{"" + bg_color(2)}; +@define-color fg_color #{"" + $fg-color}; +@define-color highlight_color #{"" + $highlight_color}; diff --git a/lib/Styles/_label.scss b/lib/Styles/_label.scss index 21649275a..da56f7f39 100644 --- a/lib/Styles/_label.scss +++ b/lib/Styles/_label.scss @@ -1,3 +1,11 @@ +.accent { + color: #{'mix(@accent_color, @fg_color, 0.27)'}; + + &:backdrop { + color: inherit; + } +} + .title-1 { font-size: 24pt; font-weight: 700; diff --git a/lib/Widgets/Settings.vala b/lib/Widgets/Settings.vala index 51e8c1fe5..78a271989 100644 --- a/lib/Widgets/Settings.vala +++ b/lib/Widgets/Settings.vala @@ -36,6 +36,25 @@ namespace Granite { LIGHT } + private Gdk.RGBA? _accent_color = null; + + /** + * The theme accent color chosen by the user + * @since 7.6.0 + */ + [Version (since = "7.6.0")] + public Gdk.RGBA accent_color { + get { + if (_accent_color == null) { + setup_accent_color (); + } + return (_accent_color); + } + private set { + _accent_color = value; + } + } + private ColorScheme? _prefers_color_scheme = null; /** @@ -96,6 +115,39 @@ namespace Granite { } } + private void setup_accent_color () { + try { + portal = Portal.Settings.get (); + + var variant = portal.read ( + "org.freedesktop.appearance", + "accent-color" + ).get_variant (); + + accent_color = parse_color (variant); + + portal.setting_changed.connect ((scheme, key, value) => { + if (scheme == "org.freedesktop.appearance" && key == "accent-color") { + accent_color = parse_color (value); + } + }); + } catch (Error e) { + warning (e.message); + + // Set a default in case we can't get from system + accent_color.parse ("#3689e6"); + } + } + + private Gdk.RGBA parse_color (GLib.Variant color) { + double red, green, blue; + color.get ("(ddd)", out red, out green, out blue); + + Gdk.RGBA rgba = {(float) red, (float) green, (float) blue, 1}; + + return rgba; + } + private void setup_prefers_color_scheme () { try { portal = Portal.Settings.get (); diff --git a/meson.build b/meson.build index eb773df6c..460d52599 100644 --- a/meson.build +++ b/meson.build @@ -49,7 +49,7 @@ libgranite_deps = [ gio_os_dep, dependency('glib-2.0', version: '>=' + glib_min_version), dependency('gobject-2.0', version: '>=' + glib_min_version), - dependency('gtk4', version: '>=4.4'), + dependency('gtk4', version: '>=4.12'), ] pkgconfig = import('pkgconfig')