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



commit f803c0ee0a4a8148e1ac352f5d0b3050d042febf
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Fri May 1 15:53:55 2020 +0200

    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>

 src/backends/meta-monitor-config-manager.c |  54 ++++++++-
 src/backends/meta-monitor-config-manager.h |   5 +
 src/backends/meta-monitor-manager.c        |  15 +++
 src/tests/monitor-unit-tests.c             | 187 +++++++++++++++++++++++++++++
 4 files changed, 256 insertions(+), 5 deletions(-)
---
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index 5f8324338d..0a895c0a5e 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 0b37665bc7..025bafb8f3 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 30fcee9712..1e34f17da4 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 d79d4f37c4..dff80cbc92 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",


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