From bdf1ff0360fb93588337294b2617d5bea09175e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 13 Feb 2025 15:27:26 +0800 Subject: [PATCH] settings: Add output luminance settings to org.gnome.mutter This aims to allow configuring the output luminance currently used via the color state shaders. It will replace the output luminance property of the debug control API. Part-of: --- data/org.gnome.mutter.gschema.xml.in | 13 +++ src/backends/meta-settings-private.h | 9 ++ src/backends/meta-settings.c | 164 +++++++++++++++++++++++++-- 3 files changed, 178 insertions(+), 8 deletions(-) diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in index 9457fac25..3a8fd2bc3 100644 --- a/data/org.gnome.mutter.gschema.xml.in +++ b/data/org.gnome.mutter.gschema.xml.in @@ -164,6 +164,19 @@ + + [] + + Per output luminance settings + + Per output and color mode luminance setting. Each entry consists of a + tuple with connector, vendor, product, serial, and a color mode, as well + as an associated floating point value representing the output luminance + in percent (%). The default when not specified is 100%. + + + diff --git a/src/backends/meta-settings-private.h b/src/backends/meta-settings-private.h index d213441fd..82da6ca77 100644 --- a/src/backends/meta-settings-private.h +++ b/src/backends/meta-settings-private.h @@ -21,6 +21,7 @@ #include +#include "backends/meta-backend-types.h" #include "core/util-private.h" #include "meta/meta-settings.h" #include "meta/types.h" @@ -79,3 +80,11 @@ gboolean meta_settings_is_privacy_screen_enabled (MetaSettings *settings); void meta_settings_set_privacy_screen_enabled (MetaSettings *settings, gboolean enabled); + +double meta_settings_get_output_luminance (MetaSettings *settings, + const MetaMonitorSpec *monitor_spec, + MetaColorMode color_mode); + +double meta_settings_get_default_output_luminance (MetaSettings *settings, + const MetaMonitorSpec *monitor_spec, + MetaColorMode color_mode); diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c index 5f646984e..1609f2682 100644 --- a/src/backends/meta-settings.c +++ b/src/backends/meta-settings.c @@ -39,6 +39,7 @@ enum FONT_DPI_CHANGED, EXPERIMENTAL_FEATURES_CHANGED, PRIVACY_SCREEN_CHANGED, + OUTPUT_LUMINANCE_CHANGED, N_SIGNALS }; @@ -83,6 +84,8 @@ struct _MetaSettings /* Whether Xwayland should allow X11 clients from different endianness */ gboolean xwayland_allow_byte_swapped_clients; + + GPtrArray *output_luminance; }; G_DEFINE_TYPE (MetaSettings, meta_settings, G_TYPE_OBJECT) @@ -341,20 +344,150 @@ update_experimental_features (MetaSettings *settings) settings)); } +typedef struct _LuminanceEntry +{ + MetaMonitorSpec *monitor_spec; + MetaColorMode color_mode; + double luminance; +} LuminanceEntry; + +static void +luminance_entry_free (LuminanceEntry *entry) +{ + g_clear_pointer (&entry->monitor_spec, meta_monitor_spec_free); + g_free (entry); +} + +static LuminanceEntry * +luminance_entry_new (const MetaMonitorSpec *monitor_spec, + MetaColorMode color_mode, + double luminance) +{ + LuminanceEntry *entry; + + entry = g_new0 (LuminanceEntry, 1); + entry->monitor_spec = meta_monitor_spec_clone (monitor_spec); + entry->color_mode = color_mode; + entry->luminance = luminance; + + return entry; +} + +static gboolean +luminance_entry_matches (LuminanceEntry *entry, + const MetaMonitorSpec *monitor_spec, + MetaColorMode color_mode) +{ + return (meta_monitor_spec_equals (entry->monitor_spec, monitor_spec) && + entry->color_mode == color_mode); +} + +static LuminanceEntry * +find_luminance_entry (MetaSettings *settings, + const MetaMonitorSpec *monitor_spec, + MetaColorMode color_mode) +{ + size_t i; + + for (i = 0; i < settings->output_luminance->len; i++) + { + LuminanceEntry *entry = + g_ptr_array_index (settings->output_luminance, i); + + if (luminance_entry_matches (entry, monitor_spec, color_mode)) + return entry; + } + + return NULL; +} + +double +meta_settings_get_output_luminance (MetaSettings *settings, + const MetaMonitorSpec *monitor_spec, + MetaColorMode color_mode) +{ + LuminanceEntry *entry; + + entry = find_luminance_entry (settings, monitor_spec, color_mode); + if (entry) + return entry->luminance; + + return meta_settings_get_default_output_luminance (settings, + monitor_spec, + color_mode); +} + +double +meta_settings_get_default_output_luminance (MetaSettings *settings, + const MetaMonitorSpec *monitor_spec, + MetaColorMode color_mode) +{ + return 100.0; +} + +static void +update_output_luminance_settings (MetaSettings *settings) +{ + g_autoptr (GVariant) output_luminance_variant = NULL; + GVariantIter iter; + char *connector; + char *vendor; + char *product; + char *serial; + uint32_t color_mode_value; + double luminance; + + output_luminance_variant = g_settings_get_value (settings->mutter_settings, + "output-luminance"); + g_variant_iter_init (&iter, output_luminance_variant); + + g_ptr_array_remove_range (settings->output_luminance, + 0, + settings->output_luminance->len); + + while (g_variant_iter_next (&iter, + "(ssssud)", + &connector, &vendor, &product, &serial, + &color_mode_value, + &luminance)) + { + g_autoptr (MetaMonitorSpec) monitor_spec = NULL; + MetaColorMode color_mode = color_mode_value; + LuminanceEntry *entry; + + monitor_spec = g_new0 (MetaMonitorSpec, 1); + *monitor_spec = (MetaMonitorSpec) { + .connector = connector, + .vendor = vendor, + .product = product, + .serial = serial + }; + + entry = luminance_entry_new (monitor_spec, color_mode, luminance); + g_ptr_array_add (settings->output_luminance, entry); + } + + g_signal_emit (settings, signals[OUTPUT_LUMINANCE_CHANGED], 0); +} + static void mutter_settings_changed (GSettings *mutter_settings, gchar *key, MetaSettings *settings) { - MetaExperimentalFeature old_experimental_features; + if (g_str_equal (key, "experimental-features")) + { + MetaExperimentalFeature old_experimental_features; - if (!g_str_equal (key, "experimental-features")) - return; - - old_experimental_features = settings->experimental_features; - if (update_experimental_features (settings)) - g_signal_emit (settings, signals[EXPERIMENTAL_FEATURES_CHANGED], 0, - (unsigned int) old_experimental_features); + old_experimental_features = settings->experimental_features; + if (update_experimental_features (settings)) + g_signal_emit (settings, signals[EXPERIMENTAL_FEATURES_CHANGED], 0, + (unsigned int) old_experimental_features); + } + else if (g_str_equal (key, "output-luminance")) + { + update_output_luminance_settings (settings); + } } static void @@ -545,6 +678,8 @@ meta_settings_dispose (GObject *object) g_clear_pointer (&settings->xwayland_grab_deny_list_patterns, g_ptr_array_unref); + g_clear_pointer (&settings->output_luminance, g_ptr_array_unref); + G_OBJECT_CLASS (meta_settings_parent_class)->dispose (object); } @@ -553,6 +688,9 @@ meta_settings_init (MetaSettings *settings) { const char *experimental_features_env; + settings->output_luminance = + g_ptr_array_new_with_free_func ((GDestroyNotify) luminance_entry_free); + settings->interface_settings = g_settings_new ("org.gnome.desktop.interface"); g_signal_connect (settings->interface_settings, "changed", G_CALLBACK (interface_settings_changed), @@ -598,6 +736,7 @@ meta_settings_init (MetaSettings *settings) update_xwayland_disable_extensions (settings); update_privacy_settings (settings); update_xwayland_allow_byte_swapped_clients (settings); + update_output_luminance_settings (settings); } static void @@ -667,4 +806,13 @@ meta_settings_class_init (MetaSettingsClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + + signals[OUTPUT_LUMINANCE_CHANGED] = + g_signal_new ("output-luminance-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + }