Introduce a StyleManager (#1880)

This commit is contained in:
Leonhard 2024-03-26 18:05:32 +01:00 committed by GitHub
parent 8fce251a2c
commit 4c6f503b31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 155 additions and 42 deletions

View File

@ -10,7 +10,7 @@ gala_daemon_sources = files(
gala_daemon_bin = executable(
'gala-daemon',
gala_daemon_sources,
dependencies: [gala_dep, gala_base_dep, hdy_dep],
dependencies: [gala_dep, gala_base_dep, granite_dep, hdy_dep],
include_directories: config_inc_dir,
install: true,
)

View File

@ -6,13 +6,11 @@
using Gdk;
using Granite.Services;
namespace Gala.Drawing {
/**
* A class containing an RGBA color and methods for more powerful color manipulation.
*/
public class Color : GLib.Object, SettingsSerializable {
public class Color : GLib.Object {
public const Gdk.RGBA LIGHT_BACKGROUND = { (250f / 255f), (250f / 255f), (250f / 255f), 1};
public const Gdk.RGBA DARK_BACKGROUND = { (51 / 255f), (51 / 255f), (51 / 255f), 1};
public const Gdk.RGBA TOOLTIP_BACKGROUND = { 0, 0, 0, 1};

View File

@ -0,0 +1,128 @@
/*
* Copyright 2024 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
*/
public class Gala.Drawing.StyleManager : Object {
public enum ColorScheme {
NO_PREFERENCE,
DARK,
LIGHT
}
[DBus (name="org.freedesktop.Accounts")]
private interface Accounts : Object {
public abstract async string find_user_by_name (string name) throws IOError, DBusError;
}
[DBus (name="io.elementary.pantheon.AccountsService")]
private interface AccountsService : DBusProxy {
public abstract int prefers_color_scheme { get; set; }
public abstract int prefers_accent_color { get; set; }
}
private const string FDO_ACCOUNTS_NAME = "org.freedesktop.Accounts";
private const string FDO_ACCOUNTS_PATH = "/org/freedesktop/Accounts";
private const double ACCENT_COLOR_ALPHA = 0.25;
private const Gdk.RGBA DEFAULT_ACCENT_COLOR = { 0, 0, 0, ACCENT_COLOR_ALPHA };
private static GLib.Once<StyleManager> instance;
public static StyleManager get_instance () {
return instance.once (() => {return new StyleManager ();});
}
public ColorScheme prefers_color_scheme { get; private set; default = LIGHT; }
public Gdk.RGBA theme_accent_color { get; private set; default = DEFAULT_ACCENT_COLOR; }
private AccountsService? accounts_service_proxy;
construct {
Bus.watch_name (SYSTEM, FDO_ACCOUNTS_NAME, NONE, () => connect_to_accounts_service.begin (), () => accounts_service_proxy = null);
}
private async void connect_to_accounts_service () {
try {
var accounts = yield Bus.get_proxy<Accounts> (SYSTEM, FDO_ACCOUNTS_NAME, FDO_ACCOUNTS_PATH);
var path = yield accounts.find_user_by_name (Environment.get_user_name ());
accounts_service_proxy = yield Bus.get_proxy<AccountsService> (SYSTEM, FDO_ACCOUNTS_NAME, path, GET_INVALIDATED_PROPERTIES);
} catch {
warning ("Could not connect to AccountsService. Default accent color will be used");
return;
}
update_color_scheme (accounts_service_proxy.prefers_color_scheme);
update_color (accounts_service_proxy.prefers_accent_color);
accounts_service_proxy.g_properties_changed.connect ((changed, invalid) => {
var value = changed.lookup_value ("PrefersAccentColor", new VariantType ("i"));
if (value != null) {
update_color (value.get_int32 ());
}
value = changed.lookup_value ("PrefersColorScheme", new VariantType ("i"));
if (value != null) {
update_color_scheme (value.get_int32 ());
}
});
}
private void update_color_scheme (int color_scheme) {
prefers_color_scheme = (ColorScheme) color_scheme;
}
private void update_color (int color) {
var rgb = get_color (color);
double r = ((rgb >> 16) & 255) / 255.0;
double g = ((rgb >> 8) & 255) / 255.0;
double b = (rgb & 255) / 255.0;
theme_accent_color = {
r,
g,
b,
ACCENT_COLOR_ALPHA
};
}
private int get_color (int color) {
switch (color) {
case 1: // Strawberry
return 0xed5353;
case 2: // Orange
return 0xffa154;
case 3: // Banana
return 0xf9c440;
case 4: // Lime
return 0x68b723;
case 5: // Mint
return 0x28bca3;
case 6: // Blueberry
return 0x3689e6;
case 7: // Grape
return 0xa56de2;
case 8: // Bubblegum
return 0xde3e80;
case 9: // Cocoa
return 0x8a715e;
case 10: // Slate
return 0x667885;
}
return 0;
}
}

View File

@ -11,6 +11,7 @@ gala_lib_sources = files(
'Drawing/BufferSurface.vala',
'Drawing/Canvas.vala',
'Drawing/Color.vala',
'Drawing/StyleManager.vala',
'Drawing/Utilities.vala',
'Plugin.vala',
'ShadowEffect.vala',

View File

@ -175,7 +175,7 @@ endif
add_project_arguments(vala_flags, language: 'vala')
add_project_link_arguments(['-Wl,-rpath,@0@'.format(mutter_typelib_dir)], language: 'c')
gala_base_dep = [canberra_dep, glib_dep, gobject_dep, gio_dep, gio_unix_dep, gmodule_dep, gee_dep, gtk_dep, mutter_dep, granite_dep, gnome_desktop_dep, m_dep, posix_dep, sqlite3_dep, config_dep]
gala_base_dep = [canberra_dep, glib_dep, gobject_dep, gio_dep, gio_unix_dep, gmodule_dep, gee_dep, gtk_dep, mutter_dep, gnome_desktop_dep, m_dep, posix_dep, sqlite3_dep, config_dep]
if get_option('systemd')
gala_base_dep += systemd_dep

View File

@ -42,7 +42,7 @@ namespace Gala {
public bool should_dim {
get {
return (
Granite.Settings.get_default ().prefers_color_scheme == DARK &&
Drawing.StyleManager.get_instance ().prefers_color_scheme == DARK &&
gala_background_settings.get_boolean ("dim-wallpaper-in-dark-style")
);
}
@ -62,7 +62,7 @@ namespace Gala {
gala_background_settings = new GLib.Settings ("io.elementary.desktop.background");
gala_background_settings.changed["dim-wallpaper-in-dark-style"].connect (() => changed ());
Granite.Settings.get_default ().notify["prefers-color-scheme"].connect (() => changed ());
Drawing.StyleManager.get_instance ().notify["prefers-color-scheme"].connect (() => changed ());
gnome_background_settings = new GLib.Settings ("org.gnome.desktop.background");
@ -129,7 +129,7 @@ namespace Gala {
}
private string get_background_path () {
if (Granite.Settings.get_default ().prefers_color_scheme == DARK) {
if (Drawing.StyleManager.get_instance ().prefers_color_scheme == DARK) {
var uri = gnome_background_settings.get_string ("picture-uri-dark");
var path = File.new_for_uri (uri).get_path ();
if (FileUtils.test (path, EXISTS)) {

View File

@ -318,23 +318,6 @@ namespace Gala {
return (int) (Math.round ((float)value * scale_factor));
}
private static Gtk.StyleContext selection_style_context = null;
public static Gdk.RGBA get_theme_accent_color () {
if (selection_style_context == null) {
var label_widget_path = new Gtk.WidgetPath ();
label_widget_path.append_type (GLib.Type.from_name ("label"));
label_widget_path.iter_set_object_name (-1, "selection");
selection_style_context = new Gtk.StyleContext ();
selection_style_context.set_path (label_widget_path);
}
return (Gdk.RGBA) selection_style_context.get_property (
Gtk.STYLE_PROPERTY_BACKGROUND_COLOR,
Gtk.StateFlags.NORMAL
);
}
/**
* Returns the workspaces geometry following the only_on_primary settings.
*/

View File

@ -108,7 +108,7 @@ namespace Gala {
return;
}
var rgba = InternalUtils.get_theme_accent_color ();
var rgba = Drawing.StyleManager.get_instance ().theme_accent_color;
/* Don't use alpha from the stylesheet to ensure contrast */
stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue);

View File

@ -236,9 +236,9 @@ namespace Gala {
scale_factor = scale_factor
};
var granite_settings = Granite.Settings.get_default ();
var style_manager = Drawing.StyleManager.get_instance ();
if (granite_settings.prefers_color_scheme == DARK) {
if (style_manager.prefers_color_scheme == DARK) {
const double BG_COLOR = 35.0 / 255.0;
if (drag_action.dragging) {
cr.set_source_rgba (BG_COLOR, BG_COLOR, BG_COLOR, 0.8);
@ -298,7 +298,7 @@ namespace Gala {
InternalUtils.scale_to_int (PLUS_SIZE, scale_factor)
);
if (granite_settings.prefers_color_scheme == DARK) {
if (style_manager.prefers_color_scheme == DARK) {
buffer.context.move_to (0, 1 * scale_factor);
buffer.context.set_source_rgb (0, 0, 0);
buffer.context.fill_preserve ();

View File

@ -44,7 +44,7 @@ namespace Gala {
private Clutter.BrightnessContrastEffect brightness_effect;
private GLib.Settings gala_behavior_settings;
private Granite.Settings granite_settings;
private Drawing.StyleManager style_manager;
private bool switching_workspace_with_gesture = false;
private bool switching_workspace_in_progress {
@ -59,7 +59,7 @@ namespace Gala {
construct {
gala_behavior_settings = new GLib.Settings ("org.pantheon.desktop.gala.behavior");
granite_settings = Granite.Settings.get_default ();
style_manager = Drawing.StyleManager.get_instance ();
visible = false;
reactive = true;
@ -150,11 +150,11 @@ namespace Gala {
});
});
granite_settings.notify["prefers-color-scheme"].connect (update_brightness_effect);
style_manager.notify["prefers-color-scheme"].connect (update_brightness_effect);
}
private void update_brightness_effect () {
if (granite_settings.prefers_color_scheme == DARK) {
if (style_manager.prefers_color_scheme == DARK) {
brightness_effect.set_brightness (-0.4f);
} else {
brightness_effect.set_brightness (0.4f);

View File

@ -138,7 +138,7 @@ namespace Gala {
transition.started.connect (() => { visible = true; });
add_transition ("circle", transition);
var rgba = InternalUtils.get_theme_accent_color ();
var rgba = Drawing.StyleManager.get_instance ().theme_accent_color;
/* Don't use alpha from the stylesheet to ensure contrast */
stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue);

View File

@ -883,7 +883,7 @@ public class Gala.WindowClone : Clutter.Actor {
return;
}
var color = InternalUtils.get_theme_accent_color ();
var color = Drawing.StyleManager.get_instance ().theme_accent_color;
cr.save ();
cr.set_operator (Cairo.Operator.CLEAR);

View File

@ -24,7 +24,7 @@ public class Gala.WindowSwitcher : CanvasActor {
private bool handling_gesture = false;
private int modifier_mask;
private Gala.ModalProxy modal_proxy = null;
private Granite.Settings granite_settings;
private Drawing.StyleManager style_manager;
private Clutter.Actor container;
private Clutter.Text caption;
private ShadowEffect shadow_effect;
@ -58,7 +58,7 @@ public class Gala.WindowSwitcher : CanvasActor {
}
construct {
granite_settings = Granite.Settings.get_default ();
style_manager = Drawing.StyleManager.get_instance ();
container = new Clutter.Actor () {
reactive = true,
@ -93,7 +93,7 @@ public class Gala.WindowSwitcher : CanvasActor {
container.button_release_event.connect (container_mouse_release);
// Redraw the components if the colour scheme changes.
granite_settings.notify["prefers-color-scheme"].connect (content.invalidate);
style_manager.notify["prefers-color-scheme"].connect (content.invalidate);
unowned var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager ();
monitor_manager.monitors_changed.connect (scale);
@ -140,7 +140,7 @@ public class Gala.WindowSwitcher : CanvasActor {
protected override void draw (Cairo.Context ctx, int width, int height) {
var caption_color = "#2e2e31";
if (granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK) {
if (style_manager.prefers_color_scheme == Drawing.StyleManager.ColorScheme.DARK) {
caption_color = "#fafafa";
}
@ -153,7 +153,7 @@ public class Gala.WindowSwitcher : CanvasActor {
ctx.reset_clip ();
var background_color = Drawing.Color.LIGHT_BACKGROUND;
if (granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK) {
if (style_manager.prefers_color_scheme == Drawing.StyleManager.ColorScheme.DARK) {
background_color = Drawing.Color.DARK_BACKGROUND;
}

View File

@ -62,7 +62,7 @@ public class Gala.WindowSwitcherIcon : CanvasActor {
if (selected) {
// draw rect
var rgba = InternalUtils.get_theme_accent_color ();
var rgba = Drawing.StyleManager.get_instance ().theme_accent_color;
ctx.set_source_rgba (
rgba.red,
rgba.green,

View File

@ -137,6 +137,9 @@ namespace Gala {
behavior_settings = new GLib.Settings (Config.SCHEMA + ".behavior");
new_behavior_settings = new GLib.Settings ("io.elementary.desktop.wm.behavior");
enable_animations = animations_settings.get_boolean ("enable-animations");
//Make it start watching the settings daemon bus
Drawing.StyleManager.get_instance ();
}
public override void start () {
@ -1068,7 +1071,7 @@ namespace Gala {
#endif
if (tile_preview == null) {
tile_preview = new Clutter.Actor ();
var rgba = InternalUtils.get_theme_accent_color ();
var rgba = Drawing.StyleManager.get_instance ().theme_accent_color;
tile_preview.background_color = {
(uint8)(255.0 * rgba.red),
(uint8)(255.0 * rgba.green),