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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4271>
This commit is contained in:
Jonas Ådahl 2025-02-13 15:27:26 +08:00 committed by Marge Bot
parent 5b6519b4d4
commit bdf1ff0360
3 changed files with 178 additions and 8 deletions

View File

@ -164,6 +164,19 @@
</description>
</key>
<key name="output-luminance" type="a(ssssud)">
<default>[]</default>
<!-- TRANSLATORS: Luminance is different from brightness.
See https://en.wikipedia.org/wiki/Luminance -->
<summary>Per output luminance settings</summary>
<description>
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%.
</description>
</key>
<child name="keybindings" schema="org.gnome.mutter.keybindings"/>
</schema>

View File

@ -21,6 +21,7 @@
#include <glib-object.h>
#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);

View File

@ -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);
}