diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c index 5f8324338..0a895c0a5 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -1038,6 +1038,7 @@ create_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager, MetaMonitorManager *monitor_manager = config_manager->monitor_manager; MetaLogicalMonitorConfig *logical_monitor_config; MetaLogicalMonitorConfig *current_logical_monitor_config; + MetaMonitorsConfig *config; GList *logical_monitor_configs, *current_configs; MetaLogicalMonitorLayoutMode layout_mode; @@ -1085,10 +1086,13 @@ create_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager, } layout_mode = base_config->layout_mode; - return meta_monitors_config_new (monitor_manager, - logical_monitor_configs, - layout_mode, - META_MONITORS_CONFIG_FLAG_NONE); + config = meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); + meta_monitors_config_set_parent_config (config, base_config); + + return config; } MetaMonitorsConfig * @@ -1121,6 +1125,9 @@ meta_monitor_config_manager_create_for_builtin_orientation (MetaMonitorConfigMan MetaMonitorsConfig * meta_monitor_config_manager_create_for_rotate_monitor (MetaMonitorConfigManager *config_manager) { + if (!config_manager->current_config) + return NULL; + return create_for_builtin_display_rotation (config_manager, config_manager->current_config, TRUE, @@ -1319,11 +1326,37 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager return config; } +static MetaMonitorsConfig * +get_root_config (MetaMonitorsConfig *config) +{ + if (!config->parent_config) + return config; + + return get_root_config (config->parent_config); +} + +static gboolean +has_same_root_config (MetaMonitorsConfig *config_a, + MetaMonitorsConfig *config_b) +{ + return get_root_config (config_a) == get_root_config (config_b); +} + void meta_monitor_config_manager_set_current (MetaMonitorConfigManager *config_manager, MetaMonitorsConfig *config) { - if (config_manager->current_config) + MetaMonitorsConfig *current_config = config_manager->current_config; + gboolean overrides_current = FALSE; + + if (config && current_config && + has_same_root_config (config, current_config)) + { + overrides_current = meta_monitors_config_key_equal (config->key, + current_config->key); + } + + if (current_config && !overrides_current) { g_queue_push_head (&config_manager->config_history, g_object_ref (config_manager->current_config)); @@ -1522,6 +1555,16 @@ meta_monitors_config_set_switch_config (MetaMonitorsConfig *config, config->switch_config = switch_config; } +void +meta_monitors_config_set_parent_config (MetaMonitorsConfig *config, + MetaMonitorsConfig *parent_config) +{ + g_assert (config != parent_config); + g_assert (!parent_config || parent_config->parent_config != config); + + g_set_object (&config->parent_config, parent_config); +} + MetaMonitorsConfig * meta_monitors_config_new_full (GList *logical_monitor_configs, GList *disabled_monitor_specs, @@ -1583,6 +1626,7 @@ meta_monitors_config_finalize (GObject *object) { MetaMonitorsConfig *config = META_MONITORS_CONFIG (object); + g_clear_object (&config->parent_config); meta_monitors_config_key_free (config->key); g_list_free_full (config->logical_monitor_configs, (GDestroyNotify) meta_logical_monitor_config_free); diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h index 0b37665bc..025bafb8f 100644 --- a/src/backends/meta-monitor-config-manager.h +++ b/src/backends/meta-monitor-config-manager.h @@ -62,6 +62,7 @@ struct _MetaMonitorsConfig { GObject parent; + MetaMonitorsConfig *parent_config; MetaMonitorsConfigKey *key; GList *logical_monitor_configs; @@ -157,6 +158,10 @@ META_EXPORT_TEST void meta_monitors_config_set_switch_config (MetaMonitorsConfig *config, MetaMonitorSwitchConfigType switch_config); +META_EXPORT_TEST +void meta_monitors_config_set_parent_config (MetaMonitorsConfig *config, + MetaMonitorsConfig *parent_config); + META_EXPORT_TEST unsigned int meta_monitors_config_key_hash (gconstpointer config_key); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 30fcee971..1e34f17da 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -773,6 +773,18 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) config = meta_monitor_config_manager_get_previous (manager->config_manager); if (config) { + g_autoptr (MetaMonitorsConfig) oriented_config = NULL; + + if (manager->panel_orientation_managed) + { + oriented_config = + meta_monitor_config_manager_create_for_builtin_orientation ( + manager->config_manager, config); + + if (oriented_config) + config = oriented_config; + } + config = g_object_ref (config); if (meta_monitor_manager_is_config_complete (manager, config)) @@ -891,6 +903,9 @@ handle_orientation_change (MetaOrientationManager *orientation_manager, current_config = meta_monitor_config_manager_get_current (manager->config_manager); + if (!current_config) + return; + config = meta_monitor_config_manager_create_for_orientation (manager->config_manager, current_config, diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c index d79d4f37c..dff80cbc9 100644 --- a/src/tests/monitor-unit-tests.c +++ b/src/tests/monitor-unit-tests.c @@ -302,6 +302,107 @@ meta_test_monitor_config_store_set_current_on_empty (void) g_assert_null (meta_monitor_config_manager_pop_previous (config_manager)); } +static void +meta_test_monitor_config_store_set_current_with_parent_on_empty (void) +{ + g_autoptr (MetaMonitorsConfig) parent_config = NULL; + g_autoptr (MetaMonitorsConfig) child_config1 = NULL; + g_autoptr (MetaMonitorsConfig) child_config2 = NULL; + g_autoptr (MetaMonitorsConfig) child_config3 = NULL; + g_autoptr (MetaMonitorsConfig) linear_config = NULL; + g_autoptr (MetaMonitorsConfig) fallback_config = NULL; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorsConfig *old_current; + + parent_config = meta_monitor_config_manager_create_linear (config_manager); + + child_config1 = meta_monitor_config_manager_create_linear (config_manager); + meta_monitors_config_set_parent_config (child_config1, parent_config); + old_current = meta_monitor_config_manager_get_current (config_manager); + + g_assert_null (old_current); + g_assert_nonnull (child_config1); + + meta_monitor_config_manager_set_current (config_manager, child_config1); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + child_config1); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + g_assert_null (meta_monitor_config_manager_get_previous (config_manager)); + g_assert_null (meta_monitor_config_manager_pop_previous (config_manager)); + + child_config2 = meta_monitor_config_manager_create_linear (config_manager); + meta_monitors_config_set_parent_config (child_config2, parent_config); + g_assert (child_config2->parent_config == parent_config); + + old_current = meta_monitor_config_manager_get_current (config_manager); + g_assert_nonnull (old_current->parent_config); + meta_monitor_config_manager_set_current (config_manager, child_config2); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + child_config2); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + g_assert_null (meta_monitor_config_manager_get_previous (config_manager)); + g_assert_null (meta_monitor_config_manager_pop_previous (config_manager)); + + child_config3 = meta_monitor_config_manager_create_linear (config_manager); + meta_monitors_config_set_parent_config (child_config3, child_config2); + + old_current = meta_monitor_config_manager_get_current (config_manager); + g_assert_nonnull (old_current->parent_config); + meta_monitor_config_manager_set_current (config_manager, child_config3); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + child_config3); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + g_assert_null (meta_monitor_config_manager_get_previous (config_manager)); + g_assert_null (meta_monitor_config_manager_pop_previous (config_manager)); + + linear_config = meta_monitor_config_manager_create_linear (config_manager); + g_assert_null (linear_config->parent_config); + + old_current = meta_monitor_config_manager_get_current (config_manager); + g_assert_nonnull (old_current->parent_config); + meta_monitor_config_manager_set_current (config_manager, linear_config); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + linear_config); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + g_assert (meta_monitor_config_manager_get_previous (config_manager) == + child_config3); + + fallback_config = + meta_monitor_config_manager_create_fallback (config_manager); + g_assert_null (fallback_config->parent_config); + + old_current = meta_monitor_config_manager_get_current (config_manager); + g_assert_null (old_current->parent_config); + meta_monitor_config_manager_set_current (config_manager, fallback_config); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + fallback_config); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + + g_assert (meta_monitor_config_manager_get_previous (config_manager) == + linear_config); + g_assert (meta_monitor_config_manager_pop_previous (config_manager) == + linear_config); + g_assert (meta_monitor_config_manager_get_previous (config_manager) == + child_config3); + g_assert (meta_monitor_config_manager_pop_previous (config_manager) == + child_config3); + g_assert_null (meta_monitor_config_manager_get_previous (config_manager)); + g_assert_null (meta_monitor_config_manager_pop_previous (config_manager)); +} + static void meta_test_monitor_config_store_set_current (void) { @@ -340,6 +441,88 @@ meta_test_monitor_config_store_set_current (void) g_assert_null (meta_monitor_config_manager_pop_previous (config_manager)); } +static void +meta_test_monitor_config_store_set_current_with_parent (void) +{ + g_autoptr (MetaMonitorsConfig) child_config = NULL; + g_autoptr (MetaMonitorsConfig) other_child = NULL; + g_autoptr (MetaMonitorsConfig) linear_config = NULL; + g_autoptr (MetaMonitorsConfig) fallback_config = NULL; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorsConfig *old_current; + + linear_config = meta_monitor_config_manager_create_linear (config_manager); + g_assert_null (linear_config->parent_config); + + old_current = meta_monitor_config_manager_get_current (config_manager); + g_assert_null (old_current); + meta_monitor_config_manager_set_current (config_manager, linear_config); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + linear_config); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + g_assert_null (meta_monitor_config_manager_get_previous (config_manager)); + g_assert_null (meta_monitor_config_manager_pop_previous (config_manager)); + + fallback_config = meta_monitor_config_manager_create_fallback (config_manager); + g_assert_nonnull (fallback_config); + g_assert_null (fallback_config->parent_config); + + old_current = meta_monitor_config_manager_get_current (config_manager); + g_assert_nonnull (old_current); + g_assert_null (old_current->parent_config); + meta_monitor_config_manager_set_current (config_manager, fallback_config); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + fallback_config); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + g_assert (meta_monitor_config_manager_get_previous (config_manager) == + old_current); + + child_config = meta_monitor_config_manager_create_linear (config_manager); + old_current = meta_monitor_config_manager_get_current (config_manager); + meta_monitors_config_set_parent_config (child_config, old_current); + + g_assert_nonnull (child_config); + g_assert_nonnull (old_current); + g_assert (old_current == fallback_config); + g_assert_null (old_current->parent_config); + + meta_monitor_config_manager_set_current (config_manager, child_config); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + child_config); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + g_assert (meta_monitor_config_manager_get_previous (config_manager) == + linear_config); + + other_child = meta_monitor_config_manager_create_linear (config_manager); + meta_monitors_config_set_parent_config (other_child, old_current); + + old_current = meta_monitor_config_manager_get_current (config_manager); + g_assert_nonnull (old_current->parent_config); + g_assert (old_current == child_config); + meta_monitor_config_manager_set_current (config_manager, other_child); + + g_assert (meta_monitor_config_manager_get_current (config_manager) == + other_child); + g_assert (meta_monitor_config_manager_get_current (config_manager) != + old_current); + g_assert (meta_monitor_config_manager_get_previous (config_manager) == + linear_config); + g_assert (meta_monitor_config_manager_pop_previous (config_manager) == + linear_config); + + g_assert_null (meta_monitor_config_manager_get_previous (config_manager)); + g_assert_null (meta_monitor_config_manager_pop_previous (config_manager)); +} + static void meta_test_monitor_config_store_set_current_max_size (void) { @@ -7044,8 +7227,12 @@ init_monitor_tests (void) add_monitor_test ("/backends/monitor/config-store/set_current-on-empty", meta_test_monitor_config_store_set_current_on_empty); + add_monitor_test ("/backends/monitor/config-store/set_current-with-parent-on-empty", + meta_test_monitor_config_store_set_current_with_parent_on_empty); add_monitor_test ("/backends/monitor/config-store/set_current", meta_test_monitor_config_store_set_current); + add_monitor_test ("/backends/monitor/config-store/set_current-with-parent", + meta_test_monitor_config_store_set_current_with_parent); add_monitor_test ("/backends/monitor/config-store/set_current-max-size", meta_test_monitor_config_store_set_current_max_size); add_monitor_test ("/backends/monitor/config-store/set_current-null",