diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c index 9de418a5d..6d695dd57 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -542,19 +542,76 @@ meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager typedef enum _MonitorMatchRule { MONITOR_MATCH_ALL = 0, - MONITOR_MATCH_EXTERNAL = (1 << 0) + MONITOR_MATCH_EXTERNAL = (1 << 0), + MONITOR_MATCH_BUILTIN = (1 << 1), + MONITOR_MATCH_VISIBLE = (1 << 2), + MONITOR_MATCH_WITH_SUGGESTED_POSITION = (1 << 3), } MonitorMatchRule; +static gboolean +monitor_matches_rule (MetaMonitor *monitor, + MetaMonitorManager *monitor_manager, + MonitorMatchRule match_rule) +{ + if (!monitor) + return FALSE; + + if (match_rule & MONITOR_MATCH_BUILTIN) + { + if (!meta_monitor_is_laptop_panel (monitor)) + return FALSE; + } + else if (match_rule & MONITOR_MATCH_EXTERNAL) + { + if (meta_monitor_is_laptop_panel (monitor)) + return FALSE; + } + + if (match_rule & MONITOR_MATCH_VISIBLE) + { + if (meta_monitor_is_laptop_panel (monitor) && + is_lid_closed (monitor_manager)) + return FALSE; + } + + if (match_rule & MONITOR_MATCH_WITH_SUGGESTED_POSITION) + { + if (!meta_monitor_get_suggested_position (monitor, NULL, NULL)) + return FALSE; + } + + return TRUE; +} + +static GList * +find_monitors (MetaMonitorManager *monitor_manager, + MonitorMatchRule match_rule) +{ + GList *result = NULL; + GList *monitors, *l; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = g_list_last (monitors); l; l = l->prev) + { + MetaMonitor *monitor = l->data; + + if (monitor_matches_rule (monitor, monitor_manager, match_rule)) + result = g_list_prepend (result, monitor); + } + + return result; +} + static MetaMonitor * find_monitor_with_highest_preferred_resolution (MetaMonitorManager *monitor_manager, MonitorMatchRule match_rule) { - GList *monitors; + g_autoptr (GList) monitors = NULL; GList *l; int largest_area = 0; MetaMonitor *largest_monitor = NULL; - monitors = meta_monitor_manager_get_monitors (monitor_manager); + monitors = find_monitors (monitor_manager, match_rule); for (l = monitors; l; l = l->next) { MetaMonitor *monitor = l->data; @@ -562,12 +619,6 @@ find_monitor_with_highest_preferred_resolution (MetaMonitorManager *monitor_mana int width, height; int area; - if (match_rule & MONITOR_MATCH_EXTERNAL) - { - if (meta_monitor_is_laptop_panel (monitor)) - continue; - } - mode = meta_monitor_get_preferred_mode (monitor); meta_monitor_mode_get_resolution (mode, &width, &height); area = width * height; @@ -593,38 +644,28 @@ find_monitor_with_highest_preferred_resolution (MetaMonitorManager *monitor_mana * alternatives, except if no other alternatives exist. */ static MetaMonitor * -find_primary_monitor (MetaMonitorManager *monitor_manager) +find_primary_monitor (MetaMonitorManager *monitor_manager, + MonitorMatchRule match_rule) { MetaMonitor *monitor; - if (is_lid_closed (monitor_manager)) - { - monitor = meta_monitor_manager_get_primary_monitor (monitor_manager); - if (monitor && !meta_monitor_is_laptop_panel (monitor)) - return monitor; + match_rule |= MONITOR_MATCH_VISIBLE; - monitor = - find_monitor_with_highest_preferred_resolution (monitor_manager, - MONITOR_MATCH_EXTERNAL); - if (monitor) - return monitor; + monitor = meta_monitor_manager_get_primary_monitor (monitor_manager); + if (monitor_matches_rule (monitor, monitor_manager, match_rule)) + return monitor; - return find_monitor_with_highest_preferred_resolution (monitor_manager, - MONITOR_MATCH_ALL); - } - else - { - monitor = meta_monitor_manager_get_primary_monitor (monitor_manager); - if (monitor) - return monitor; + monitor = meta_monitor_manager_get_laptop_panel (monitor_manager); + if (monitor_matches_rule (monitor, monitor_manager, match_rule)) + return monitor; - monitor = meta_monitor_manager_get_laptop_panel (monitor_manager); - if (monitor) - return monitor; + monitor = find_monitor_with_highest_preferred_resolution (monitor_manager, + match_rule); + if (monitor) + return monitor; - return find_monitor_with_highest_preferred_resolution (monitor_manager, - MONITOR_MATCH_ALL); - } + return find_monitor_with_highest_preferred_resolution (monitor_manager, + MONITOR_MATCH_ALL); } static MetaMonitorConfig * @@ -744,20 +785,22 @@ MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager) { MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + g_autoptr (GList) monitors = NULL; GList *logical_monitor_configs; MetaMonitor *primary_monitor; MetaLogicalMonitorLayoutMode layout_mode; MetaLogicalMonitorConfig *primary_logical_monitor_config; int x; - GList *monitors; GList *l; MetaMonitorsConfig *monitors_config; - primary_monitor = find_primary_monitor (monitor_manager); + primary_monitor = find_primary_monitor (monitor_manager, + MONITOR_MATCH_VISIBLE); if (!primary_monitor) return NULL; layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + monitors = find_monitors (monitor_manager, MONITOR_MATCH_VISIBLE); primary_logical_monitor_config = create_preferred_logical_monitor_config (monitor_manager, @@ -770,7 +813,6 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana primary_logical_monitor_config); x = primary_logical_monitor_config->layout.width; - monitors = meta_monitor_manager_get_monitors (monitor_manager); for (l = monitors; l; l = l->next) { MetaMonitor *monitor = l->data; @@ -779,10 +821,6 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana if (monitor == primary_monitor) continue; - if (meta_monitor_is_laptop_panel (monitor) && - is_lid_closed (monitor_manager)) - continue; - logical_monitor_config = create_preferred_logical_monitor_config (monitor_manager, monitor, @@ -815,7 +853,7 @@ meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_ma MetaLogicalMonitorLayoutMode layout_mode; MetaLogicalMonitorConfig *primary_logical_monitor_config; - primary_monitor = find_primary_monitor (monitor_manager); + primary_monitor = find_primary_monitor (monitor_manager, MONITOR_MATCH_ALL); if (!primary_monitor) return NULL; @@ -842,21 +880,24 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m { MetaMonitorManager *monitor_manager = config_manager->monitor_manager; MetaLogicalMonitorConfig *primary_logical_monitor_config = NULL; + g_autoptr (GList) monitors = NULL; MetaMonitor *primary_monitor; MetaLogicalMonitorLayoutMode layout_mode; GList *logical_monitor_configs; GList *region; - int x, y; - GList *monitors; GList *l; + int x, y; - primary_monitor = find_primary_monitor (monitor_manager); + primary_monitor = find_primary_monitor (monitor_manager, + MONITOR_MATCH_WITH_SUGGESTED_POSITION); if (!primary_monitor) return NULL; if (!meta_monitor_get_suggested_position (primary_monitor, &x, &y)) return NULL; + monitors = find_monitors (monitor_manager, + MONITOR_MATCH_WITH_SUGGESTED_POSITION); layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); primary_logical_monitor_config = @@ -870,7 +911,6 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m primary_logical_monitor_config); region = g_list_prepend (NULL, &primary_logical_monitor_config->layout); - monitors = meta_monitor_manager_get_monitors (monitor_manager); for (l = monitors; l; l = l->next) { MetaMonitor *monitor = l->data; @@ -879,8 +919,7 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m if (monitor == primary_monitor) continue; - if (!meta_monitor_get_suggested_position (monitor, &x, &y)) - continue; + meta_monitor_get_suggested_position (monitor, &x, &y); logical_monitor_config = create_preferred_logical_monitor_config (monitor_manager, @@ -1211,24 +1250,21 @@ static MetaMonitorsConfig * create_for_switch_config_external (MetaMonitorConfigManager *config_manager) { MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + g_autoptr (GList) monitors = NULL; GList *logical_monitor_configs = NULL; int x = 0; MetaLogicalMonitorLayoutMode layout_mode; - GList *monitors; GList *l; MetaMonitorsConfig *monitors_config; + monitors = find_monitors (monitor_manager, MONITOR_MATCH_EXTERNAL); layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); - monitors = meta_monitor_manager_get_monitors (monitor_manager); for (l = monitors; l; l = l->next) { MetaMonitor *monitor = l->data; MetaLogicalMonitorConfig *logical_monitor_config; - if (meta_monitor_is_laptop_panel (monitor)) - continue; - logical_monitor_config = create_preferred_logical_monitor_config (monitor_manager, monitor,