[gnome-flashback] monitor-manager-xrandr: use a single supported scales list for all



commit c633d2f29c45e93835095a79855e92e7e31d6433
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

 backends/gf-monitor-manager-xrandr.c |  112 +++++++++++++++++++++++++++++++---
 1 files changed, 104 insertions(+), 8 deletions(-)
---
diff --git a/backends/gf-monitor-manager-xrandr.c b/backends/gf-monitor-manager-xrandr.c
index 2d04a44..ff79a25 100644
--- a/backends/gf-monitor-manager-xrandr.c
+++ b/backends/gf-monitor-manager-xrandr.c
@@ -72,6 +72,9 @@ struct _GfMonitorManagerXrandr
 
   gint                max_screen_width;
   gint                max_screen_height;
+
+  gfloat             *supported_scales;
+  gint                n_supported_scales;
 };
 
 typedef struct
@@ -81,6 +84,96 @@ typedef struct
 
 G_DEFINE_TYPE (GfMonitorManagerXrandr, gf_monitor_manager_xrandr, GF_TYPE_MONITOR_MANAGER)
 
+static void
+add_supported_scale (GArray *supported_scales,
+                     gfloat  scale)
+{
+  guint i;
+
+  for (i = 0; i < supported_scales->len; i++)
+    {
+      gfloat supported_scale;
+
+      supported_scale = g_array_index (supported_scales, gfloat, i);
+
+      if (scale == supported_scale)
+        return;
+    }
+
+  g_array_append_val (supported_scales, scale);
+}
+
+static gint
+compare_scales (gconstpointer a,
+                gconstpointer b)
+{
+  gfloat f = *(gfloat *) a - *(gfloat *) b;
+
+  if (f < 0)
+    return -1;
+
+  if (f > 0)
+    return 1;
+
+  return 0;
+}
+
+static void
+ensure_supported_monitor_scales (GfMonitorManager *manager)
+{
+  GfMonitorManagerXrandr *xrandr;
+  GfMonitorScalesConstraint constraints;
+  GArray *supported_scales;
+  GList *l;
+
+  xrandr = GF_MONITOR_MANAGER_XRANDR (manager);
+
+  if (xrandr->supported_scales)
+    return;
+
+  constraints = GF_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
+  supported_scales = g_array_new (FALSE, FALSE, sizeof (gfloat));
+
+  for (l = manager->monitors; l; l = l->next)
+    {
+      GfMonitor *monitor;
+      GfMonitorMode *monitor_mode;
+      gfloat *monitor_scales;
+      gint n_monitor_scales;
+      gint i;
+
+      monitor = l->data;
+      monitor_mode = gf_monitor_get_preferred_mode (monitor);
+      monitor_scales = gf_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);
+    }
+
+  xrandr->supported_scales = (gfloat *) supported_scales->data;
+  xrandr->n_supported_scales = supported_scales->len;
+  g_array_free (supported_scales, FALSE);
+}
+
+static void
+gf_monitor_manager_xrandr_rebuild_derived (GfMonitorManager *manager,
+                                           GfMonitorsConfig *config)
+{
+  GfMonitorManagerXrandr *xrandr;
+
+  xrandr = GF_MONITOR_MANAGER_XRANDR (manager);
+
+  g_clear_pointer (&xrandr->supported_scales, g_free);
+  gf_monitor_manager_rebuild_derived (manager, config);
+}
+
 static gboolean
 xrandr_set_crtc_config (GfMonitorManagerXrandr *xrandr,
                         gboolean                save_timestamp,
@@ -1421,6 +1514,7 @@ gf_monitor_manager_xrandr_finalize (GObject *object)
   xrandr = GF_MONITOR_MANAGER_XRANDR (object);
 
   g_clear_pointer (&xrandr->resources, XRRFreeScreenResources);
+  g_clear_pointer (&xrandr->supported_scales, g_free);
 
   G_OBJECT_CLASS (gf_monitor_manager_xrandr_parent_class)->finalize (object);
 }
@@ -1683,7 +1777,7 @@ gf_monitor_manager_xrandr_apply_monitors_config (GfMonitorManager        *manage
 
   if (!config)
     {
-      gf_monitor_manager_rebuild_derived (manager, NULL);
+      gf_monitor_manager_xrandr_rebuild_derived (manager, NULL);
       return TRUE;
     }
 
@@ -1717,7 +1811,7 @@ gf_monitor_manager_xrandr_apply_monitors_config (GfMonitorManager        *manage
         }
       else
         {
-          gf_monitor_manager_rebuild_derived (manager, config);
+          gf_monitor_manager_xrandr_rebuild_derived (manager, config);
         }
     }
 
@@ -1934,13 +2028,15 @@ gf_monitor_manager_xrandr_calculate_supported_scales (GfMonitorManager
                                                       GfMonitorMode              *monitor_mode,
                                                       gint                       *n_supported_scales)
 {
-  GfMonitorScalesConstraint constraints;
+  GfMonitorManagerXrandr *xrandr;
 
-  constraints = GF_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
+  xrandr = GF_MONITOR_MANAGER_XRANDR (manager);
+
+  ensure_supported_monitor_scales (manager);
 
-  return gf_monitor_calculate_supported_scales (monitor, monitor_mode,
-                                                constraints,
-                                                n_supported_scales);
+  *n_supported_scales = xrandr->n_supported_scales;
+  return g_memdup (xrandr->supported_scales,
+                   xrandr->n_supported_scales * sizeof (gfloat));
 }
 
 static GfMonitorManagerCapability
@@ -2050,7 +2146,7 @@ gf_monitor_manager_xrandr_handle_xevent (GfMonitorManagerXrandr *xrandr,
           config = gf_monitor_config_manager_get_current (config_manager);
         }
 
-      gf_monitor_manager_rebuild_derived (manager, config);
+      gf_monitor_manager_xrandr_rebuild_derived (manager, config);
     }
 
   return TRUE;


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