From 702f204a281c6525da6bfcd2286d70b1ab6eab13 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Nov 2017 15:58:02 +0800
Subject: [PATCH 1/4] monitor-config-manager: Don't include closed laptop panel
 in config key

When deriving the list of disabled monitors when creating new monitors
configs, don't include the laptop panel if the lid is currently closed,
as we consider the laptop panel nonexistent when the laptop lid is
closed when it comes to configuration.

The laptop panel connector(s) will either way be appropriately disabled
anyway, as the field listing disabled monitors in the configuration do
not affect actual CRTC/connector assignments.

https://bugzilla.gnome.org/show_bug.cgi?id=788915
---
 src/backends/meta-monitor-config-manager.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index 2fe620767..2a7287778 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -1308,6 +1308,10 @@ meta_monitors_config_new (MetaMonitorManager           *monitor_manager,
       MetaMonitor *monitor = l->data;
       MetaMonitorSpec *monitor_spec;
 
+      if (meta_monitor_manager_is_lid_closed (monitor_manager) &&
+          meta_monitor_is_laptop_panel (monitor))
+        continue;
+
       monitor_spec = meta_monitor_get_spec (monitor);
       if (meta_logical_monitor_configs_have_monitor (logical_monitor_configs,
                                                      monitor_spec))
-- 
2.14.2

From 584e2b93d9f28557cfe8a6ff720b4c3e45c458ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Nov 2017 16:03:23 +0800
Subject: [PATCH 2/4] monitor-manager: Compare keys when checking whether a
 config is complete

We only counted configured monitors and whether the config was
applicable (could be assigned), howeverwe didn't include disabled
monitors when comparing. This could caused incorrect configurations to
be applied when trying to use the previous configuration.

One scenario where this happened was one a system with one laptop
screen and one external monitor that was hot plugged some point after
start up. When the laptop lid was closed, the 'previous configuration'
being the configuration where only the laptop panel was enabled, passed
'is-complete' check as the number of configured monitors were correct,
and the configuration was applicable.

Avoid this issue by simply comparing the configuration key of the
previous configuration and the configuration key of the current state.
This correctly identifies a laptop panel with the lid closed as
inaccessible, thus doesn't incorrectly revert to the previous
configuration.

https://bugzilla.gnome.org/show_bug.cgi?id=788915
---
 src/backends/meta-monitor-config-manager.c |  7 +++---
 src/backends/meta-monitor-config-manager.h |  2 ++
 src/backends/meta-monitor-manager.c        | 36 +++++++++---------------------
 3 files changed, 16 insertions(+), 29 deletions(-)

diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index 2a7287778..bdf863055 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -326,8 +326,8 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager,
   return TRUE;
 }
 
-static MetaMonitorsConfigKey *
-create_key_for_current_state (MetaMonitorManager *monitor_manager)
+MetaMonitorsConfigKey *
+meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager)
 {
   MetaMonitorsConfigKey *config_key;
   GList *l;
@@ -369,7 +369,8 @@ meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager
   MetaMonitorsConfig *config;
   GError *error = NULL;
 
-  config_key = create_key_for_current_state (monitor_manager);
+  config_key =
+    meta_create_monitors_config_key_for_current_state (monitor_manager);
   if (!config_key)
     return NULL;
 
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 516909dd7..c36df38e6 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -136,6 +136,8 @@ void meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor
 
 void meta_monitor_config_free (MetaMonitorConfig *monitor_config);
 
+MetaMonitorsConfigKey * meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager);
+
 gboolean meta_logical_monitor_configs_have_monitor (GList           *logical_monitor_configs,
                                                     MetaMonitorSpec *monitor_spec);
 
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 8b548fd68..eb3612cf0 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -1551,35 +1551,19 @@ static gboolean
 meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
                                          MetaMonitorsConfig *config)
 {
-  GList *l;
-  unsigned int configured_monitor_count = 0;
-  unsigned int expected_monitor_count = 0;
-
-  for (l = config->logical_monitor_configs; l; l = l->next)
-    {
-      MetaLogicalMonitorConfig *logical_monitor_config = l->data;
-      GList *k;
+  MetaMonitorsConfigKey *current_state_key;
+  gboolean is_config_complete;
 
-      for (k = logical_monitor_config->monitor_configs; k; k = k->next)
-        configured_monitor_count++;
-    }
-
-  for (l = manager->monitors; l; l = l->next)
-    {
-      MetaMonitor *monitor = l->data;
+  current_state_key =
+    meta_create_monitors_config_key_for_current_state (manager);
+  if (!current_state_key)
+    return FALSE;
 
-      if (meta_monitor_is_laptop_panel (monitor))
-        {
-          if (!meta_monitor_manager_is_lid_closed (manager))
-            expected_monitor_count++;
-        }
-      else
-        {
-          expected_monitor_count++;
-        }
-    }
+  is_config_complete = meta_monitors_config_key_equal (current_state_key,
+                                                       config->key);
+  meta_monitors_config_key_free (current_state_key);
 
-  if (configured_monitor_count != expected_monitor_count)
+  if (!is_config_complete)
     return FALSE;
 
   return meta_monitor_manager_is_config_applicable (manager, config, NULL);
-- 
2.14.2

