kathenas / rpms / mutter

Forked from rpms/mutter 5 years ago
Clone

Blame SOURCES/0001-monitor-config-manager-Handle-multiple-builtin-panel.patch

0e33ea
From 19024a5b2eff02b22cdb3fc90142f522dd361996 Mon Sep 17 00:00:00 2001
0e33ea
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
0e33ea
Date: Fri, 27 Nov 2020 09:03:38 +0100
0e33ea
Subject: [PATCH] monitor-config-manager: Handle multiple builtin panels
0e33ea
 gracefully
0e33ea
0e33ea
While multiple built-in panels isn't actually supported in any
0e33ea
meaningful manner, if we would ever end up with such a situation, e.g.
0e33ea
due to kernel bugs[0], we shouldn't crash when trying to set an
0e33ea
'external only' without any external monitors.
0e33ea
0e33ea
While we could handle this with more degraded functionality (e.g. don't
0e33ea
support the 'switch' method of monitor configuration at all), handle it
0e33ea
by simply not trying to switch to external-only when there are no,
0e33ea
according to the kernel, external monitors available. This would e.g.
0e33ea
still allow betwene 'mirror-all', and 'linear' switches.
0e33ea
0e33ea
The crash itself was disguised as an arbitrary X11 BadValue error, due
0e33ea
to mutter trying to resize the root window to 0x0, as the monitor
0e33ea
configuration that was applied consisted of zero logical monitors, thus
0e33ea
was effectively empty.
0e33ea
0e33ea
[0] https://bugzilla.redhat.com/show_bug.cgi?id=1896904
0e33ea
0e33ea
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1899260
0e33ea
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1607>
0e33ea
---
0e33ea
 src/backends/meta-monitor-config-manager.c |   3 +
0e33ea
 src/tests/monitor-unit-tests.c             | 145 +++++++++++++++++++++
0e33ea
 2 files changed, 148 insertions(+)
0e33ea
0e33ea
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
0e33ea
index bc1a39db8..d62bad52d 100644
0e33ea
--- a/src/backends/meta-monitor-config-manager.c
0e33ea
+++ b/src/backends/meta-monitor-config-manager.c
0e33ea
@@ -1157,6 +1157,9 @@ create_for_switch_config_external (MetaMonitorConfigManager *config_manager)
0e33ea
       x += logical_monitor_config->layout.width;
0e33ea
     }
0e33ea
 
0e33ea
+  if (!logical_monitor_configs)
0e33ea
+    return NULL;
0e33ea
+
0e33ea
   return meta_monitors_config_new (monitor_manager,
0e33ea
                                    logical_monitor_configs,
0e33ea
                                    layout_mode,
0e33ea
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
0e33ea
index f47544b03..725f84173 100644
0e33ea
--- a/src/tests/monitor-unit-tests.c
0e33ea
+++ b/src/tests/monitor-unit-tests.c
0e33ea
@@ -3175,6 +3175,149 @@ meta_test_monitor_non_upright_panel (void)
0e33ea
   check_monitor_configuration (&test_case);
0e33ea
 }
0e33ea
 
0e33ea
+static void
0e33ea
+meta_test_monitor_switch_external_without_external (void)
0e33ea
+{
0e33ea
+  MonitorTestCase test_case = {
0e33ea
+    .setup = {
0e33ea
+      .modes = {
0e33ea
+        {
0e33ea
+          .width = 1024,
0e33ea
+          .height = 768,
0e33ea
+          .refresh_rate = 60.0
0e33ea
+        }
0e33ea
+      },
0e33ea
+      .n_modes = 1,
0e33ea
+      .outputs = {
0e33ea
+        {
0e33ea
+          .crtc = 0,
0e33ea
+          .modes = { 0 },
0e33ea
+          .n_modes = 1,
0e33ea
+          .preferred_mode = 0,
0e33ea
+          .possible_crtcs = { 0 },
0e33ea
+          .n_possible_crtcs = 1,
0e33ea
+          .width_mm = 222,
0e33ea
+          .height_mm = 125,
0e33ea
+          .is_laptop_panel = TRUE
0e33ea
+        },
0e33ea
+        {
0e33ea
+          .crtc = 1,
0e33ea
+          .modes = { 0 },
0e33ea
+          .n_modes = 1,
0e33ea
+          .preferred_mode = 0,
0e33ea
+          .possible_crtcs = { 1 },
0e33ea
+          .n_possible_crtcs = 1,
0e33ea
+          .width_mm = 222,
0e33ea
+          .height_mm = 125,
0e33ea
+          .is_laptop_panel = TRUE
0e33ea
+        }
0e33ea
+      },
0e33ea
+      .n_outputs = 2,
0e33ea
+      .crtcs = {
0e33ea
+        {
0e33ea
+          .current_mode = 0
0e33ea
+        },
0e33ea
+        {
0e33ea
+          .current_mode = 0
0e33ea
+        }
0e33ea
+      },
0e33ea
+      .n_crtcs = 2
0e33ea
+    },
0e33ea
+
0e33ea
+    .expect = {
0e33ea
+      .monitors = {
0e33ea
+        {
0e33ea
+          .outputs = { 0 },
0e33ea
+          .n_outputs = 1,
0e33ea
+          .modes = {
0e33ea
+            {
0e33ea
+              .width = 1024,
0e33ea
+              .height = 768,
0e33ea
+              .refresh_rate = 60.0,
0e33ea
+              .crtc_modes = {
0e33ea
+                {
0e33ea
+                  .output = 0,
0e33ea
+                  .crtc_mode = 0
0e33ea
+                }
0e33ea
+              }
0e33ea
+            }
0e33ea
+          },
0e33ea
+          .n_modes = 1,
0e33ea
+          .current_mode = 0,
0e33ea
+          .width_mm = 222,
0e33ea
+          .height_mm = 125
0e33ea
+        },
0e33ea
+        {
0e33ea
+          .outputs = { 1 },
0e33ea
+          .n_outputs = 1,
0e33ea
+          .modes = {
0e33ea
+            {
0e33ea
+              .width = 1024,
0e33ea
+              .height = 768,
0e33ea
+              .refresh_rate = 60.0,
0e33ea
+              .crtc_modes = {
0e33ea
+                {
0e33ea
+                  .output = 1,
0e33ea
+                  .crtc_mode = 0
0e33ea
+                }
0e33ea
+              }
0e33ea
+            }
0e33ea
+          },
0e33ea
+          .n_modes = 1,
0e33ea
+          .current_mode = 0,
0e33ea
+          .width_mm = 222,
0e33ea
+          .height_mm = 125
0e33ea
+        }
0e33ea
+      },
0e33ea
+      .n_monitors = 2,
0e33ea
+      .logical_monitors = {
0e33ea
+        {
0e33ea
+          .monitors = { 0 },
0e33ea
+          .n_monitors = 1,
0e33ea
+          .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 },
0e33ea
+          .scale = 1
0e33ea
+        },
0e33ea
+        {
0e33ea
+          .monitors = { 1 },
0e33ea
+          .n_monitors = 1,
0e33ea
+          .layout = { .x = 1024, .y = 0, .width = 1024, .height = 768 },
0e33ea
+          .scale = 1
0e33ea
+        }
0e33ea
+      },
0e33ea
+      .n_logical_monitors = 2,
0e33ea
+      .primary_logical_monitor = 0,
0e33ea
+      .n_outputs = 2,
0e33ea
+      .crtcs = {
0e33ea
+        {
0e33ea
+          .current_mode = 0,
0e33ea
+        },
0e33ea
+        {
0e33ea
+          .current_mode = 0,
0e33ea
+        },
0e33ea
+      },
0e33ea
+      .n_crtcs = 2,
0e33ea
+      .n_tiled_monitors = 0,
0e33ea
+      .screen_width = 2048,
0e33ea
+      .screen_height = 768
0e33ea
+    }
0e33ea
+  };
0e33ea
+  MetaMonitorTestSetup *test_setup;
0e33ea
+  MetaBackend *backend = meta_get_backend ();
0e33ea
+  MetaMonitorManager *monitor_manager =
0e33ea
+    meta_backend_get_monitor_manager (backend);
0e33ea
+
0e33ea
+  test_setup = create_monitor_test_setup (&test_case.setup,
0e33ea
+                                          MONITOR_TEST_FLAG_NO_STORED);
0e33ea
+  emulate_hotplug (test_setup);
0e33ea
+  check_monitor_configuration (&test_case);
0e33ea
+
0e33ea
+  meta_monitor_manager_switch_config (monitor_manager,
0e33ea
+                                      META_MONITOR_SWITCH_CONFIG_EXTERNAL);
0e33ea
+  check_monitor_configuration (&test_case);
0e33ea
+
0e33ea
+  check_monitor_test_clients_state ();
0e33ea
+}
0e33ea
+
0e33ea
 static void
0e33ea
 meta_test_monitor_custom_vertical_config (void)
0e33ea
 {
0e33ea
@@ -5969,6 +6112,8 @@ init_monitor_tests (void)
0e33ea
                     meta_test_monitor_preferred_non_first_mode);
0e33ea
   add_monitor_test ("/backends/monitor/non-upright-panel",
0e33ea
                     meta_test_monitor_non_upright_panel);
0e33ea
+  add_monitor_test ("/backends/monitor/switch-external-without-external",
0e33ea
+                    meta_test_monitor_switch_external_without_external);
0e33ea
 
0e33ea
   add_monitor_test ("/backends/monitor/custom/vertical-config",
0e33ea
                     meta_test_monitor_custom_vertical_config);
0e33ea
-- 
0e33ea
2.29.2
0e33ea