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