From 648f1ce9350fcab0ebaecccb115b5021c632e7b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 28 Jan 2016 15:26:33 +0100
Subject: [PATCH] monitor-manager: Consider external layout before default
 linear config

In case of no existing configuration, we use a default layout of
aligning attached displays horizontally. This sidesteps any layout
configuration that is done externally, for instance via xorg.conf,
which is not desirable. Instead, base the initial configuration on
the existing layout if it passes some sanity checks before falling
back to the default linear config.
---
 src/backends/meta-monitor-config-manager.c | 75 ++++++++++++++++++++++
 src/backends/meta-monitor-config-manager.h |  1 +
 src/backends/meta-monitor-manager.c        | 19 ++++++++
 3 files changed, 97 insertions(+)

diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index 197892bf2..ae988f64a 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -559,6 +559,83 @@ create_preferred_logical_monitor_config (MetaMonitorManager          *monitor_ma
   return logical_monitor_config;
 }
 
+static MetaLogicalMonitorConfig *
+create_logical_monitor_config_from_output (MetaMonitorManager           *monitor_manager,
+                                           MetaMonitor                  *monitor,
+                                           MetaLogicalMonitorConfig     *primary_logical_monitor_config,
+                                           MetaLogicalMonitorLayoutMode  layout_mode)
+{
+    MetaOutput *output;
+    MetaCrtc *crtc;
+
+    output = meta_monitor_get_main_output (monitor);
+    crtc = meta_output_get_assigned_crtc (output);
+    return create_preferred_logical_monitor_config (monitor_manager,
+                                                    monitor,
+                                                    crtc->rect.x,
+                                                    crtc->rect.y,
+                                                    primary_logical_monitor_config,
+                                                    layout_mode);
+}
+
+MetaMonitorsConfig *
+meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager)
+{
+  MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
+  GList *logical_monitor_configs;
+  MetaMonitor *primary_monitor;
+  MetaLogicalMonitorLayoutMode layout_mode;
+  MetaLogicalMonitorConfig *primary_logical_monitor_config;
+  GList *monitors;
+  GList *l;
+
+  if (meta_monitor_config_store_get_config_count (config_manager->config_store) > 0)
+    return NULL;
+
+  primary_monitor = find_primary_monitor (monitor_manager);
+  if (!primary_monitor || !meta_monitor_is_active (primary_monitor))
+    return NULL;
+
+  layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
+
+  primary_logical_monitor_config =
+    create_logical_monitor_config_from_output (monitor_manager,
+                                               primary_monitor,
+                                               NULL,
+                                               layout_mode);
+
+  primary_logical_monitor_config->is_primary = TRUE;
+  logical_monitor_configs = g_list_append (NULL,
+                                           primary_logical_monitor_config);
+
+  monitors = meta_monitor_manager_get_monitors (monitor_manager);
+  for (l = monitors; l; l = l->next)
+    {
+      MetaMonitor *monitor = l->data;
+      MetaLogicalMonitorConfig *logical_monitor_config;
+
+      if (monitor == primary_monitor)
+        continue;
+
+      if (!meta_monitor_is_active (monitor))
+        continue;
+
+      logical_monitor_config =
+        create_logical_monitor_config_from_output (monitor_manager,
+                                                   monitor,
+                                                   primary_logical_monitor_config,
+                                                   layout_mode);
+
+      logical_monitor_configs = g_list_append (logical_monitor_configs,
+                                               logical_monitor_config);
+    }
+
+  return meta_monitors_config_new (monitor_manager,
+                                   logical_monitor_configs,
+                                   layout_mode,
+                                   META_MONITORS_CONFIG_FLAG_NONE);
+}
+
 MetaMonitorsConfig *
 meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager)
 {
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 269d8e1b7..c36df38e6 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -87,6 +87,7 @@ gboolean meta_monitor_config_manager_assign (MetaMonitorManager *manager,
 
 MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager);
 
+MetaMonitorsConfig * meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager);
 MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager);
 
 MetaMonitorsConfig * meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_manager);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 0b5e54c48..263e93941 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -576,6 +576,25 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
       g_clear_object (&config);
     }
 
+  config = meta_monitor_config_manager_create_current (manager->config_manager);
+  if (config)
+    {
+      if (!meta_monitor_manager_apply_monitors_config (manager,
+                                                       config,
+                                                       method,
+                                                       &error))
+        {
+          g_clear_object (&config);
+          g_warning ("Failed to use current monitor configuration: %s",
+                     error->message);
+          g_clear_error (&error);
+        }
+      else
+        {
+          goto done;
+        }
+    }
+
   config = meta_monitor_config_manager_create_linear (manager->config_manager);
   if (config)
     {
-- 
2.17.1

