monitor-manager: Add config relationships and use it for orientation events

When we get an orientation event we don't care about keeping track of the
configuration changes, but actually we can consider the new configuration
just a variant of the previous one, adapted to floating device hardware
events, so we only want to apply it if possible, but we don't want to keep
a record of it for reverting capabilities.

Doing that would in fact, break the ability of reverting back to an actual
temporary or persistent configuration.
For example when device orientation events happen while we're waiting for
an user resolution change confirmation, we would save our new rotated
configuration in the history, making then impossible to revert back to
the original persistent one.

So in such case, don't keep track of those configurations in the history,
but only keep track of the last one as current, checking whether the
new current is child or sibling of the previously one.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1221
Related to: https://gitlab.gnome.org/GNOME/mutter/-/issues/646

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1233>
This commit is contained in:
Marco Trevisan (Treviño) 2020-05-01 15:53:55 +02:00 committed by Jonas Ådahl
parent db68a2a91c
commit f803c0ee0a
4 changed files with 256 additions and 5 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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",