[mutter] monitor-config-manager: Use scale from past configs when generating



commit 3dca01a06c1b082823a8938f6397979e44cdd644
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Thu Jun 23 12:49:35 2022 +0200

    monitor-config-manager: Use scale from past configs when generating
    
    When we e.g. generate switch configs (i.e. the ones from pressing the
    Super+P or the switch-config key on laptops), try a bit harder to find a
    "good" monitor scale.
    
    With "good", it means pick a scale that was used in a previous
    configuration. In practice, this means that if you for example have
    configured your external monitor to use a specific scale, then pressed
    e.g. "built in only", and then switched back to e.g. "external only" or
    "linear", the generated configuration will use the scale that was
    previously configured.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2479>

 src/backends/meta-monitor-config-manager.c | 83 ++++++++++++++++++++++++++++--
 1 file changed, 78 insertions(+), 5 deletions(-)
---
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index d8e3a9cda0..575810b3f9 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -784,14 +784,82 @@ create_preferred_logical_monitor_config (MetaMonitorManager          *monitor_ma
   return logical_monitor_config;
 }
 
+static MetaLogicalMonitorConfig *
+find_monitor_config (MetaMonitorsConfig *config,
+                     MetaMonitor        *monitor,
+                     MetaMonitorMode    *monitor_mode)
+{
+  int mode_width, mode_height;
+  GList *l;
+
+  meta_monitor_mode_get_resolution (monitor_mode, &mode_width, &mode_height);
+
+  for (l = config->logical_monitor_configs; l; l = l->next)
+    {
+      MetaLogicalMonitorConfig *logical_monitor_config = l->data;
+      GList *l_monitor;
+
+      for (l_monitor = logical_monitor_config->monitor_configs;
+           l_monitor;
+           l_monitor = l_monitor->next)
+        {
+          MetaMonitorConfig *monitor_config = l_monitor->data;
+          MetaMonitorModeSpec *mode_spec =
+            meta_monitor_mode_get_spec (monitor_mode);
+
+          if (meta_monitor_spec_equals (meta_monitor_get_spec (monitor),
+                                         monitor_config->monitor_spec) &&
+              meta_monitor_mode_spec_has_similar_size (mode_spec,
+                                                       monitor_config->mode_spec))
+            return logical_monitor_config;
+        }
+    }
+
+  return NULL;
+}
+
+static gboolean
+get_last_scale_for_monitor (MetaMonitorConfigManager *config_manager,
+                            MetaMonitor              *monitor,
+                            MetaMonitorMode          *monitor_mode,
+                            float                    *out_scale)
+{
+  g_autoptr (GList) configs = NULL;
+  GList *l;
+
+  if (config_manager->current_config)
+    configs = g_list_append (configs, config_manager->current_config);
+
+  configs = g_list_concat (configs,
+                           g_list_copy (config_manager->config_history.head));
+
+  for (l = configs; l; l = l->next)
+    {
+      MetaMonitorsConfig *config = l->data;
+      MetaLogicalMonitorConfig *logical_monitor_config;
+
+      logical_monitor_config = find_monitor_config (config,
+                                                    monitor, monitor_mode);
+      if (logical_monitor_config)
+        {
+          *out_scale = logical_monitor_config->scale;
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
 static float
-compute_scale_for_monitor (MetaMonitorManager *monitor_manager,
-                           MetaMonitor        *monitor,
-                           MetaMonitor        *primary_monitor)
+compute_scale_for_monitor (MetaMonitorConfigManager *config_manager,
+                           MetaMonitor              *monitor,
+                           MetaMonitor              *primary_monitor)
 {
+  MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
   MetaMonitor *target_monitor = monitor;
   MetaLogicalMonitorLayoutMode layout_mode;
   MetaMonitorMode *monitor_mode;
+  float scale;
 
   if ((meta_monitor_manager_get_capabilities (monitor_manager) &
        META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED) &&
@@ -801,6 +869,11 @@ compute_scale_for_monitor (MetaMonitorManager *monitor_manager,
   layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
   monitor_mode = meta_monitor_get_preferred_mode (target_monitor);
 
+  if (get_last_scale_for_monitor (config_manager,
+                                  target_monitor, monitor_mode,
+                                  &scale))
+    return scale;
+
   return meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager,
                                                             layout_mode,
                                                             target_monitor,
@@ -897,7 +970,7 @@ create_monitors_config (MetaMonitorConfigManager *config_manager,
           break;
         }
 
-      scale = compute_scale_for_monitor (monitor_manager, monitor,
+      scale = compute_scale_for_monitor (config_manager, monitor,
                                          primary_monitor);
       logical_monitor_config =
         create_preferred_logical_monitor_config (monitor_manager,
@@ -1261,7 +1334,7 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager)
       if (!mode)
         continue;
 
-      scale = compute_scale_for_monitor (monitor_manager, monitor,
+      scale = compute_scale_for_monitor (config_manager, monitor,
                                          primary_monitor);
       best_scale = MAX (best_scale, scale);
       monitor_configs = g_list_prepend (monitor_configs, create_monitor_config (monitor, mode));


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