[mutter] monitor-manager: Try to restore previous config before regenerating



commit 35c9280fb6cc22170b952a1924237365dbcca89a
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Aug 11 15:21:36 2017 +0800

    monitor-manager: Try to restore previous config before regenerating
    
    When opening a laptop lid, one will likely want to restore the
    configuration one had prior to closing it, so when ensuring monitor
    configuration, first try to see if the previously set configuration is
    both complete (all connected monitors are configured) and applicable
    (it is a valid configuration) and only try to generate a new from
    scratch if that failed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777732

 src/backends/meta-monitor-manager.c |   67 +++++++++++++++++++++++++++++++++++
 src/tests/monitor-unit-tests.c      |   25 +++----------
 2 files changed, 73 insertions(+), 19 deletions(-)
---
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index b139262..aa945a4 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -71,6 +71,10 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaMonitorManager, meta_monitor_manager, META
 
 static void initialize_dbus_interface (MetaMonitorManager *manager);
 
+static gboolean
+meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
+                                         MetaMonitorsConfig *config);
+
 static void
 meta_monitor_manager_init (MetaMonitorManager *manager)
 {
@@ -529,6 +533,31 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
         }
     }
 
+  config = meta_monitor_config_manager_get_previous (manager->config_manager);
+  if (config)
+    {
+      config = g_object_ref (config);
+
+      if (meta_monitor_manager_is_config_complete (manager, config))
+        {
+          if (!meta_monitor_manager_apply_monitors_config (manager,
+                                                           config,
+                                                           method,
+                                                           &error))
+            {
+              g_warning ("Failed to use suggested monitor configuration: %s",
+                         error->message);
+              g_clear_error (&error);
+            }
+          else
+            {
+              goto done;
+            }
+        }
+
+      g_clear_object (&config);
+    }
+
   config = meta_monitor_config_manager_create_linear (manager->config_manager);
   if (config)
     {
@@ -1494,6 +1523,44 @@ meta_monitor_manager_is_config_applicable (MetaMonitorManager *manager,
   return TRUE;
 }
 
+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;
+
+      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;
+
+      if (meta_monitor_is_laptop_panel (monitor))
+        {
+          if (!meta_monitor_manager_is_lid_closed (manager))
+            expected_monitor_count++;
+        }
+      else
+        {
+          expected_monitor_count++;
+        }
+    }
+
+  if (configured_monitor_count != expected_monitor_count)
+    return FALSE;
+
+  return meta_monitor_manager_is_config_applicable (manager, config, NULL);
+}
+
 static MetaMonitor *
 find_monitor_from_connector (MetaMonitorManager *manager,
                              char               *connector)
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index 6a8626b..53455c1 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -2281,33 +2281,20 @@ meta_test_monitor_lid_switch_config (void)
   meta_monitor_manager_test_set_is_lid_closed (monitor_manager_test, FALSE);
   meta_monitor_manager_lid_is_closed_changed (monitor_manager);
 
-  test_case.expect.n_logical_monitors = 2;
-  test_case.expect.screen_width = 1024 * 2;
-  test_case.expect.monitors[0].current_mode = 0;
-
-  test_case.expect.crtcs[0].current_mode = 0;
-  test_case.expect.crtcs[1].current_mode = 0;
-
-  /*
-   * FIXME: The above expectation is correct, but MetaMonitorConfigManager
-   * doesn't support restoring previous configurations yet, so it'll
-   * pick keep the external monitor as primary and put it first.
-   */
   test_case.expect.logical_monitors[0] = (MonitorTestCaseLogicalMonitor) {
-    .monitors = { 1 },
-    .n_monitors = 1,
-    .layout = {.x = 0, .y = 0, .width = 1024, .height = 768 },
-    .scale = 1
-  };
-  test_case.expect.logical_monitors[1] = (MonitorTestCaseLogicalMonitor) {
     .monitors = { 0 },
     .n_monitors = 1,
-    .layout = {.x = 1024, .y = 0, .width = 1024, .height = 768 },
+    .layout = {.x = 0, .y = 0, .width = 1024, .height = 768 },
     .scale = 1
   };
   test_case.expect.n_logical_monitors = 2;
+  test_case.expect.screen_width = 1024 * 2;
+  test_case.expect.monitors[0].current_mode = 0;
   test_case.expect.primary_logical_monitor = 0;
 
+  test_case.expect.crtcs[0].current_mode = 0;
+  test_case.expect.crtcs[1].current_mode = 0;
+
   check_monitor_configuration (&test_case);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]