diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index c369d4960..600422032 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -71,6 +71,9 @@ struct _MetaMonitorManagerXrandr int max_screen_width; int max_screen_height; + + float *supported_scales; + int n_supported_scales; }; struct _MetaMonitorManagerXrandrClass @@ -1481,6 +1484,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, @@ -1492,7 +1506,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; } @@ -1526,7 +1540,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); } } @@ -1782,6 +1796,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, @@ -1789,12 +1873,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 @@ -1874,6 +1960,7 @@ meta_monitor_manager_xrandr_finalize (GObject *object) manager_xrandr->resources = NULL; 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); } @@ -1949,7 +2036,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;