monitor-manager: Don't apply configurations with unsupported color modes
The set of supported color modes of a monitor might change for the same monitor, for example by the monitor providing different EDID blobs depending on configuration done on the monitor itself. When we have a color mode configured that is not actually supported by the monitor at the moment, amend the configuration and fall back on the default color mode. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3911 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4364>
This commit is contained in:
parent
cb5d43b39a
commit
e5ff0dbc81
@ -923,7 +923,12 @@ get_last_color_mode_for_monitor (MetaMonitorConfigManager *config_manager,
|
|||||||
monitor_config = find_monitor_config (config, monitor);
|
monitor_config = find_monitor_config (config, monitor);
|
||||||
if (monitor_config)
|
if (monitor_config)
|
||||||
{
|
{
|
||||||
*out_color_mode = monitor_config->color_mode;
|
MetaColorMode color_mode = monitor_config->color_mode;
|
||||||
|
|
||||||
|
if (!meta_monitor_is_color_mode_supported (monitor, color_mode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*out_color_mode = color_mode;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include "backends/meta-monitor.h"
|
#include "backends/meta-monitor.h"
|
||||||
#include "backends/meta-monitor-config-manager.h"
|
#include "backends/meta-monitor-config-manager.h"
|
||||||
#include "backends/meta-monitor-config-store.h"
|
#include "backends/meta-monitor-config-store.h"
|
||||||
|
#include "backends/meta-monitor-config-utils.h"
|
||||||
#include "backends/meta-output.h"
|
#include "backends/meta-output.h"
|
||||||
#include "backends/meta-virtual-monitor.h"
|
#include "backends/meta-virtual-monitor.h"
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
@ -130,6 +131,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitorManager, meta_monitor_manager,
|
|||||||
static void initialize_dbus_interface (MetaMonitorManager *manager);
|
static void initialize_dbus_interface (MetaMonitorManager *manager);
|
||||||
static void monitor_manager_setup_dbus_config_handlers (MetaMonitorManager *manager);
|
static void monitor_manager_setup_dbus_config_handlers (MetaMonitorManager *manager);
|
||||||
|
|
||||||
|
static gboolean meta_monitors_config_has_monitors_connected (MetaMonitorsConfig *config,
|
||||||
|
MetaMonitorManager *manager);
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
|
meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
|
||||||
MetaMonitorsConfig *config);
|
MetaMonitorsConfig *config);
|
||||||
@ -692,6 +695,82 @@ should_use_stored_config (MetaMonitorManager *manager)
|
|||||||
!meta_monitor_manager_has_hotplug_mode_update (manager));
|
!meta_monitor_manager_has_hotplug_mode_update (manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_logical_monitor_config_amend_needed (MetaMonitorManager *manager,
|
||||||
|
MetaLogicalMonitorConfig *logical_monitor_config)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = logical_monitor_config->monitor_configs; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaMonitorConfig *monitor_config = l->data;
|
||||||
|
MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec;
|
||||||
|
MetaMonitor *monitor;
|
||||||
|
|
||||||
|
monitor = meta_monitor_manager_get_monitor_from_spec (manager,
|
||||||
|
monitor_spec);
|
||||||
|
if (!meta_monitor_is_color_mode_supported (monitor,
|
||||||
|
monitor_config->color_mode))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_monitors_config_amend_needed (MetaMonitorManager *manager,
|
||||||
|
MetaMonitorsConfig *config)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
g_assert (meta_monitors_config_has_monitors_connected (config, manager));
|
||||||
|
|
||||||
|
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||||
|
|
||||||
|
if (is_logical_monitor_config_amend_needed (manager,
|
||||||
|
logical_monitor_config))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
amend_monitor_config (MetaMonitorConfig *monitor_config,
|
||||||
|
MetaMonitorManager *manager)
|
||||||
|
{
|
||||||
|
MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec;
|
||||||
|
MetaMonitor *monitor;
|
||||||
|
|
||||||
|
monitor = meta_monitor_manager_get_monitor_from_spec (manager,
|
||||||
|
monitor_spec);
|
||||||
|
if (!meta_monitor_is_color_mode_supported (monitor,
|
||||||
|
monitor_config->color_mode))
|
||||||
|
monitor_config->color_mode = META_COLOR_MODE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
amend_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
|
||||||
|
MetaMonitorManager *manager)
|
||||||
|
{
|
||||||
|
g_list_foreach (logical_monitor_config->monitor_configs,
|
||||||
|
(GFunc) amend_monitor_config,
|
||||||
|
manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
amend_monitors_config (MetaMonitorManager *manager,
|
||||||
|
MetaMonitorsConfig *config,
|
||||||
|
MetaMonitorsConfig *base_config)
|
||||||
|
{
|
||||||
|
g_list_foreach (config->logical_monitor_configs,
|
||||||
|
(GFunc) amend_logical_monitor_config,
|
||||||
|
manager);
|
||||||
|
meta_monitors_config_set_parent_config (config, base_config);
|
||||||
|
}
|
||||||
|
|
||||||
MetaMonitorsConfig *
|
MetaMonitorsConfig *
|
||||||
meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
||||||
{
|
{
|
||||||
@ -714,6 +793,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
|||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
g_autoptr (MetaMonitorsConfig) oriented_config = NULL;
|
g_autoptr (MetaMonitorsConfig) oriented_config = NULL;
|
||||||
|
g_autoptr (MetaMonitorsConfig) amended_config = NULL;
|
||||||
|
|
||||||
if (manager->panel_orientation_managed)
|
if (manager->panel_orientation_managed)
|
||||||
{
|
{
|
||||||
@ -724,6 +804,13 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
|||||||
config = oriented_config;
|
config = oriented_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_monitors_config_amend_needed (manager, config))
|
||||||
|
{
|
||||||
|
amended_config = meta_monitors_config_copy (config);
|
||||||
|
amend_monitors_config (manager, amended_config, config);
|
||||||
|
config = amended_config;
|
||||||
|
}
|
||||||
|
|
||||||
if (!meta_monitor_manager_apply_monitors_config (manager,
|
if (!meta_monitor_manager_apply_monitors_config (manager,
|
||||||
config,
|
config,
|
||||||
method,
|
method,
|
||||||
@ -798,6 +885,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
|||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
g_autoptr (MetaMonitorsConfig) oriented_config = NULL;
|
g_autoptr (MetaMonitorsConfig) oriented_config = NULL;
|
||||||
|
g_autoptr (MetaMonitorsConfig) amended_config = NULL;
|
||||||
|
|
||||||
if (manager->panel_orientation_managed)
|
if (manager->panel_orientation_managed)
|
||||||
{
|
{
|
||||||
@ -809,26 +897,35 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
|||||||
config = oriented_config;
|
config = oriented_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
config = g_object_ref (config);
|
|
||||||
|
|
||||||
if (meta_monitor_manager_is_config_complete (manager, config))
|
if (meta_monitor_manager_is_config_complete (manager, config))
|
||||||
{
|
{
|
||||||
|
if (is_monitors_config_amend_needed (manager, config))
|
||||||
|
{
|
||||||
|
amended_config = meta_monitors_config_copy (config);
|
||||||
|
amend_monitors_config (manager, amended_config, config);
|
||||||
|
config = amended_config;
|
||||||
|
}
|
||||||
|
|
||||||
if (!meta_monitor_manager_apply_monitors_config (manager,
|
if (!meta_monitor_manager_apply_monitors_config (manager,
|
||||||
config,
|
config,
|
||||||
method,
|
method,
|
||||||
&error))
|
&error))
|
||||||
{
|
{
|
||||||
|
config = NULL;
|
||||||
g_warning ("Failed to use suggested monitor configuration: %s",
|
g_warning ("Failed to use suggested monitor configuration: %s",
|
||||||
error->message);
|
error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
config = g_object_ref (config);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
g_clear_object (&config);
|
{
|
||||||
|
config = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config = meta_monitor_config_manager_create_linear (manager->config_manager);
|
config = meta_monitor_config_manager_create_linear (manager->config_manager);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user