From 2035f2f2e26a013ed4f73e10d40c0f286f426aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 8 Feb 2017 10:32:33 +0800 Subject: [PATCH] monitor-config-manager: Verify that logical monitors are adjecent Logical monitors in a configuration must be adjecent to each other, meaning there will be at least one pixel long side touching some other logical monitor. The exception to this is when there is only one logical monitor, which cannot be adjecent to any other. https://bugzilla.gnome.org/show_bug.cgi?id=777732 --- src/backends/meta-monitor-config-manager.c | 35 ++++++++++++++++++++++ src/core/boxes-private.h | 3 ++ src/core/boxes.c | 23 ++++++++++++++ src/tests/unit-tests.c | 33 ++++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c index 85339636e..d604ba715 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -893,6 +893,34 @@ meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_co return TRUE; } +static gboolean +has_adjecent_neighbour (MetaMonitorsConfig *config, + MetaLogicalMonitorConfig *logical_monitor_config) +{ + GList *l; + + if (!config->logical_monitor_configs->next) + { + g_assert (config->logical_monitor_configs->data == + logical_monitor_config); + return TRUE; + } + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *other_logical_monitor_config = l->data; + + if (logical_monitor_config == other_logical_monitor_config) + continue; + + if (meta_rectangle_is_adjecent_to (&logical_monitor_config->layout, + &other_logical_monitor_config->layout)) + return TRUE; + } + + return FALSE; +} + gboolean meta_verify_monitors_config (MetaMonitorsConfig *config, GError **error) @@ -935,6 +963,13 @@ meta_verify_monitors_config (MetaMonitorsConfig *config, has_primary = TRUE; } + if (!has_adjecent_neighbour (config, logical_monitor_config)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Logical monitors not adjecent"); + return FALSE; + } + region = g_list_prepend (region, &logical_monitor_config->layout); } diff --git a/src/core/boxes-private.h b/src/core/boxes-private.h index c2eec0ae0..9b6811ce6 100644 --- a/src/core/boxes-private.h +++ b/src/core/boxes-private.h @@ -215,4 +215,7 @@ GList* meta_rectangle_find_nonintersected_monitor_edges ( const GList *monitor_rects, const GSList *all_struts); +gboolean meta_rectangle_is_adjecent_to (MetaRectangle *rect, + MetaRectangle *other); + #endif /* META_BOXES_PRIVATE_H */ diff --git a/src/core/boxes.c b/src/core/boxes.c index 2a70497ca..35e9ac3cd 100644 --- a/src/core/boxes.c +++ b/src/core/boxes.c @@ -2013,3 +2013,26 @@ meta_rectangle_find_nonintersected_monitor_edges ( return ret; } + +gboolean +meta_rectangle_is_adjecent_to (MetaRectangle *rect, + MetaRectangle *other) +{ + int rect_x1 = rect->x; + int rect_y1 = rect->y; + int rect_x2 = rect->x + rect->width; + int rect_y2 = rect->y + rect->height; + int other_x1 = other->x; + int other_y1 = other->y; + int other_x2 = other->x + other->width; + int other_y2 = other->y + other->height; + + if ((rect_x1 == other_x2 || rect_x2 == other_x1) && + !(rect_y2 <= other_y1 || rect_y1 >= other_y2)) + return TRUE; + else if ((rect_y1 == other_y2 || rect_y2 == other_y1) && + !(rect_x2 <= other_x1 || rect_x1 >= other_x2)) + return TRUE; + else + return FALSE; +} diff --git a/src/tests/unit-tests.c b/src/tests/unit-tests.c index 1138aeb33..7e5a1e8d2 100644 --- a/src/tests/unit-tests.c +++ b/src/tests/unit-tests.c @@ -26,6 +26,7 @@ #include #include "compositor/meta-plugin-manager.h" +#include "core/boxes-private.h" #include "core/main-private.h" #include "tests/meta-backend-test.h" #include "tests/monitor-unit-tests.h" @@ -180,6 +181,36 @@ meta_test_util_later_schedule_from_later (void) g_assert_cmpint (data.state, ==, META_TEST_LATER_FINISHED); } +static void +meta_test_adjecent_to (void) +{ + MetaRectangle base = { .x = 10, .y = 10, .width = 10, .height = 10 }; + MetaRectangle adjecent[] = { + { .x = 20, .y = 10, .width = 10, .height = 10 }, + { .x = 0, .y = 10, .width = 10, .height = 10 }, + { .x = 0, .y = 1, .width = 10, .height = 10 }, + { .x = 20, .y = 19, .width = 10, .height = 10 }, + { .x = 10, .y = 20, .width = 10, .height = 10 }, + { .x = 10, .y = 0, .width = 10, .height = 10 }, + }; + MetaRectangle not_adjecent[] = { + { .x = 0, .y = 0, .width = 10, .height = 10 }, + { .x = 20, .y = 20, .width = 10, .height = 10 }, + { .x = 21, .y = 10, .width = 10, .height = 10 }, + { .x = 10, .y = 21, .width = 10, .height = 10 }, + { .x = 10, .y = 5, .width = 10, .height = 10 }, + { .x = 11, .y = 10, .width = 10, .height = 10 }, + { .x = 19, .y = 10, .width = 10, .height = 10 }, + }; + unsigned int i; + + for (i = 0; i < G_N_ELEMENTS (adjecent); i++) + g_assert (meta_rectangle_is_adjecent_to (&base, &adjecent[i])); + + for (i = 0; i < G_N_ELEMENTS (not_adjecent); i++) + g_assert (!meta_rectangle_is_adjecent_to (&base, ¬_adjecent[i])); +} + static gboolean run_tests (gpointer data) { @@ -202,6 +233,8 @@ init_tests (int argc, char **argv) g_test_add_func ("/util/meta-later/schedule-from-later", meta_test_util_later_schedule_from_later); + g_test_add_func ("/core/boxes/adjecent-to", meta_test_adjecent_to); + init_monitor_store_tests (); init_monitor_tests (); }