[mutter] monitor-manager/xrandr: Use a single supported scales list for all



commit 1a78557e0b7733375fe0a97efb42080af72be853
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Oct 13 14:34:19 2017 +0800

    monitor-manager/xrandr: Use a single supported scales list for all
    
    Under X11 we can only ever have the same scale configured on all
    monitors. In order to use e.g. scale 2 when there is a HiDPI monitor
    connected, we must not disallow it because there is a monitor that does
    not support scale 2. Thus we must show the same scale for every monitor
    and monitor mode, even though it might result in a bad experience.
    
    Do this by iterating through all the monitors adding all supported
    scales by the preferred mode, combining all the supported scales. This
    supported scales list is then used for all monitor and modes no matter
    what.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=788901

 src/backends/x11/meta-monitor-manager-xrandr.c |  104 +++++++++++++++++++++--
 1 files changed, 95 insertions(+), 9 deletions(-)
---
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 7efbd79..487e952 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -74,6 +74,9 @@ struct _MetaMonitorManagerXrandr
 #ifdef HAVE_XRANDR15
   GHashTable *tiled_monitor_atoms;
 #endif /* HAVE_XRANDR15 */
+
+  float *supported_scales;
+  int n_supported_scales;
 };
 
 struct _MetaMonitorManagerXrandrClass
@@ -546,6 +549,17 @@ meta_monitor_manager_xrandr_ensure_initial_config (MetaMonitorManager *manager)
   meta_monitor_manager_update_logical_state_derived (manager, config);
 }
 
+static void
+meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager,
+                                             MetaMonitorsConfig *config)
+{
+  MetaMonitorManagerXrandr *manager_xrandr =
+    META_MONITOR_MANAGER_XRANDR (manager);
+
+  g_clear_pointer (&manager_xrandr->supported_scales, g_free);
+  meta_monitor_manager_rebuild_derived (manager, config);
+}
+
 static gboolean
 meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager      *manager,
                                                    MetaMonitorsConfig      *config,
@@ -557,7 +571,7 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager      *mana
 
   if (!config)
     {
-      meta_monitor_manager_rebuild_derived (manager, NULL);
+      meta_monitor_manager_xrandr_rebuild_derived (manager, NULL);
       return TRUE;
     }
 
@@ -591,7 +605,7 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager      *mana
         }
       else
         {
-          meta_monitor_manager_rebuild_derived (manager, config);
+          meta_monitor_manager_xrandr_rebuild_derived (manager, config);
         }
     }
 
@@ -832,6 +846,76 @@ meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *ma
   return meta_monitor_calculate_mode_scale (monitor, monitor_mode);
 }
 
+static void
+add_supported_scale (GArray *supported_scales,
+                     float   scale)
+{
+  unsigned int i;
+
+  for (i = 0; i < supported_scales->len; i++)
+    {
+      float supported_scale = g_array_index (supported_scales, float, i);
+
+      if (scale == supported_scale)
+        return;
+    }
+
+  g_array_append_val (supported_scales, scale);
+}
+
+static int
+compare_scales (gconstpointer a,
+                gconstpointer b)
+{
+  float f = *(float *) a - *(float *) b;
+
+  if (f < 0)
+    return -1;
+  if (f > 0)
+    return 1;
+  return 0;
+}
+
+static void
+ensure_supported_monitor_scales (MetaMonitorManager *manager)
+{
+  MetaMonitorManagerXrandr *manager_xrandr =
+    META_MONITOR_MANAGER_XRANDR (manager);
+  MetaMonitorScalesConstraint constraints;
+  GList *l;
+  GArray *supported_scales;
+
+  if (manager_xrandr->supported_scales)
+    return;
+
+  constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
+  supported_scales = g_array_new (FALSE, FALSE, sizeof (float));
+
+  for (l = manager->monitors; l; l = l->next)
+    {
+      MetaMonitor *monitor = l->data;
+      MetaMonitorMode *monitor_mode;
+      float *monitor_scales;
+      int n_monitor_scales;
+      int i;
+
+      monitor_mode = meta_monitor_get_preferred_mode (monitor);
+      monitor_scales =
+        meta_monitor_calculate_supported_scales (monitor,
+                                                 monitor_mode,
+                                                 constraints,
+                                                 &n_monitor_scales);
+
+      for (i = 0; i < n_monitor_scales; i++)
+        add_supported_scale (supported_scales, monitor_scales[i]);
+      g_array_sort (supported_scales, compare_scales);
+    }
+
+  manager_xrandr->supported_scales = (float *) supported_scales->data;
+  manager_xrandr->n_supported_scales = supported_scales->len;
+  g_array_free (supported_scales, FALSE);
+}
+
 static float *
 meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager          *manager,
                                                         MetaLogicalMonitorLayoutMode layout_mode,
@@ -839,12 +923,14 @@ meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager
                                                         MetaMonitorMode             *monitor_mode,
                                                         int                         *n_supported_scales)
 {
-  MetaMonitorScalesConstraint constraints;
+  MetaMonitorManagerXrandr *manager_xrandr =
+    META_MONITOR_MANAGER_XRANDR (manager);
 
-  constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
-  return meta_monitor_calculate_supported_scales (monitor, monitor_mode,
-                                                  constraints,
-                                                  n_supported_scales);
+  ensure_supported_monitor_scales (manager);
+
+  *n_supported_scales = manager_xrandr->n_supported_scales;
+  return g_memdup (manager_xrandr->supported_scales,
+                   manager_xrandr->n_supported_scales * sizeof (float));
 }
 
 static MetaMonitorManagerCapability
@@ -929,8 +1015,8 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object);
 
   g_clear_object (&manager_xrandr->gpu);
-
   g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
+  g_free (manager_xrandr->supported_scales);
 
   G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
 }
@@ -1014,7 +1100,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
           config = NULL;
         }
 
-      meta_monitor_manager_rebuild_derived (manager, config);
+      meta_monitor_manager_xrandr_rebuild_derived (manager, config);
     }
 
   return TRUE;


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