From d79fe1960b4909455555f80de21eeaf3ec19d2d8 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 20 Dec 2019 14:17:46 +0100 Subject: [PATCH] monitor: Add flag whether EDID is sufficient to disambiguate monitors If the EDID of the attached or stored monitor configurations contain proper serial numbers, then we do not need to rely on the connector to disambiguate them. Add a boolean to both MetaMonitorManager and MetaMonitorsConfigKey to store this information. https://gitlab.gnome.org/GNOME/mutter/issues/932 --- src/backends/meta-monitor-config-manager.c | 25 +++++++++++++++++++-- src/backends/meta-monitor-config-manager.h | 5 +++++ src/backends/meta-monitor-manager-private.h | 1 + src/backends/meta-monitor-manager.c | 10 +++++++++ src/tests/monitor-store-unit-tests.c | 3 ++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c index c99d31e54..8938f4e2c 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -410,6 +410,25 @@ is_lid_closed (MetaMonitorManager *monitor_manager) return meta_backend_is_lid_closed (backend); } +gboolean +meta_config_key_edid_sufficient_for_specs (GList *monitor_specs) +{ + GList *l; + + for (l = monitor_specs; l && l->next; l = l->next) + { + MetaMonitorSpec *spec = l->data; + MetaMonitorSpec *spec_next = l->next->data; + + if (meta_monitor_spec_equals (spec, spec_next, TRUE)) + return FALSE; + + /* XXX: Should we reject e.g. only 0 serial numbers? */ + } + + return TRUE; +} + MetaMonitorsConfigKey * meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager) { @@ -439,7 +458,8 @@ meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_m config_key = g_new0 (MetaMonitorsConfigKey, 1); *config_key = (MetaMonitorsConfigKey) { - .monitor_specs = monitor_specs + .monitor_specs = monitor_specs, + .edid_sufficient = meta_config_key_edid_sufficient_for_specs (monitor_specs) }; return config_key; @@ -1356,7 +1376,8 @@ meta_monitors_config_key_new (GList *logical_monitor_configs, config_key = g_new0 (MetaMonitorsConfigKey, 1); *config_key = (MetaMonitorsConfigKey) { - .monitor_specs = monitor_specs + .monitor_specs = monitor_specs, + .edid_sufficient = meta_config_key_edid_sufficient_for_specs (monitor_specs) }; return config_key; diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h index 3875e04e9..207cec473 100644 --- a/src/backends/meta-monitor-config-manager.h +++ b/src/backends/meta-monitor-config-manager.h @@ -48,7 +48,9 @@ typedef struct _MetaLogicalMonitorConfig typedef struct _MetaMonitorsConfigKey { + /* monitor_specs needs to be sorted using meta_monitor_spec_compare. */ GList *monitor_specs; + gboolean edid_sufficient; } MetaMonitorsConfigKey; typedef enum _MetaMonitorsConfigFlag @@ -159,6 +161,9 @@ META_EXPORT_TEST gboolean meta_monitors_config_key_equal (gconstpointer config_key_a, gconstpointer config_key_b); +META_EXPORT_TEST +gboolean meta_config_key_edid_sufficient_for_specs (GList *monitor_specs); + META_EXPORT_TEST void meta_monitors_config_key_free (MetaMonitorsConfigKey *config_key); diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index 20bb6b679..897454697 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -122,6 +122,7 @@ struct _MetaMonitorManager int screen_height; GList *monitors; + gboolean edid_sufficient; GList *logical_monitors; MetaLogicalMonitor *primary_logical_monitor; diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index b773d436f..b0e1c449c 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -2621,6 +2621,7 @@ rebuild_monitors (MetaMonitorManager *manager) { GList *gpus; GList *l; + GList *specs; if (manager->monitors) { @@ -2659,6 +2660,15 @@ rebuild_monitors (MetaMonitorManager *manager) } } } + + specs = NULL; + for (l = manager->monitors; l; l = l->next) + specs = g_list_prepend (specs, meta_monitor_get_spec (l->data)); + + specs = g_list_sort (specs, + (GCompareFunc) meta_monitor_spec_compare); + manager->edid_sufficient = meta_config_key_edid_sufficient_for_specs (specs); + g_list_free (specs); } void diff --git a/src/tests/monitor-store-unit-tests.c b/src/tests/monitor-store-unit-tests.c index 4a73d89db..77810e2e7 100644 --- a/src/tests/monitor-store-unit-tests.c +++ b/src/tests/monitor-store-unit-tests.c @@ -108,7 +108,8 @@ create_config_key_from_expect (MonitorStoreTestConfiguration *expect_config) config_key = g_new0 (MetaMonitorsConfigKey, 1); *config_key = (MetaMonitorsConfigKey) { - .monitor_specs = monitor_specs + .monitor_specs = monitor_specs, + .edid_sufficient = meta_config_key_edid_sufficient_for_specs (monitor_specs) }; return config_key;