From 479bb6921da3d7004a74c4c7db999534b32ff214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= Date: Tue, 5 Nov 2024 12:26:42 +0100 Subject: [PATCH 3/3] monitor-manager: Configure for lease monitors in ApplyMonitorsConfig Add a new property to the ApplyMonitorsConfig D-Bus API allowing to set a list of monitors for lease. Part-of: --- .../org.gnome.Mutter.DisplayConfig.xml | 6 ++ src/backends/meta-monitor-manager.c | 85 ++++++++++++++++++- src/tests/monitor-unit-tests.c | 60 +++++++++++++ 3 files changed, 147 insertions(+), 4 deletions(-) diff --git a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml index 192c08a796..fec38a34a8 100644 --- a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml +++ b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml @@ -501,6 +501,12 @@ * "layout-mode" (u): layout mode the passed configuration is in; may only be set when changing the layout mode is supported (see GetCurrentState). + * "monitors-for-lease" (a(ssss)): a list of monitors to be made available for + lease. Monitors listed here must not be listed in @logical_monitors: + * s connector: connector name (e.g. HDMI-1, DP-1, etc) + * s vendor: vendor name + * s product: product name + * s serial: product serial --> diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 127181df60..abe1db6649 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -2713,6 +2713,74 @@ is_valid_layout_mode (MetaLogicalMonitorLayoutMode layout_mode) return FALSE; } +static GList * +create_disabled_monitor_specs_for_config (MetaMonitorManager *monitor_manager, + GList *logical_monitor_configs) +{ + GList *disabled_monitor_specs = NULL; + GList *monitors; + GList *l; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + if (!meta_logical_monitor_configs_have_visible_monitor (monitor_manager, + logical_monitor_configs, + monitor)) + { + MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor); + + disabled_monitor_specs = + g_list_prepend (disabled_monitor_specs, + meta_monitor_spec_clone (monitor_spec)); + } + } + + return disabled_monitor_specs; +} + +static GList * +create_for_lease_monitor_specs_from_variant (GVariant *properties_variant) +{ + GList *for_lease_monitor_specs = NULL; + g_autoptr (GVariant) for_lease_variant = NULL; + GVariantIter iter; + char *connector = NULL; + char *vendor = NULL; + char *product = NULL; + char *serial = NULL; + + if (!properties_variant) + return NULL; + + for_lease_variant = g_variant_lookup_value (properties_variant, + "monitors-for-lease", + G_VARIANT_TYPE ("a(ssss)")); + if (!for_lease_variant) + return NULL; + + g_variant_iter_init (&iter, for_lease_variant); + while (g_variant_iter_next (&iter, "(ssss)", &connector, &vendor, &product, &serial)) + { + MetaMonitorSpec *monitor_spec; + + monitor_spec = g_new0 (MetaMonitorSpec, 1); + *monitor_spec = (MetaMonitorSpec) { + .connector = connector, + .vendor = vendor, + .product = product, + .serial = serial + }; + + for_lease_monitor_specs = + g_list_append (for_lease_monitor_specs, monitor_spec); + } + + return for_lease_monitor_specs; +} + static gboolean meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skeleton, GDBusMethodInvocation *invocation, @@ -2730,6 +2798,8 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet GVariantIter logical_monitor_configs_iter; MetaMonitorsConfig *config; GList *logical_monitor_configs = NULL; + GList *disabled_monitor_specs = NULL; + GList *for_lease_monitor_specs = NULL; GError *error = NULL; if (serial != manager->serial) @@ -2818,10 +2888,17 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet logical_monitor_config); } - config = meta_monitors_config_new (manager, - logical_monitor_configs, - layout_mode, - META_MONITORS_CONFIG_FLAG_NONE); + disabled_monitor_specs = + create_disabled_monitor_specs_for_config (manager, + logical_monitor_configs); + for_lease_monitor_specs = + create_for_lease_monitor_specs_from_variant (properties_variant); + + config = meta_monitors_config_new_full (logical_monitor_configs, + disabled_monitor_specs, + for_lease_monitor_specs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); if (!meta_verify_monitors_config (config, manager, &error)) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c index 1f87c36528..380f55cc75 100644 --- a/src/tests/monitor-unit-tests.c +++ b/src/tests/monitor-unit-tests.c @@ -9564,6 +9564,10 @@ meta_test_monitor_custom_for_lease_config_dbus (void) MetaMonitorTestSetup *test_setup; g_autoptr (GDBusProxy) display_config_proxy = NULL; g_autoptr (GVariant) state = NULL; + uint32_t serial; + GVariantBuilder b; + g_autoptr (GVariant) apply_config_ret = NULL; + g_autoptr (GVariant) new_state = NULL; test_setup = meta_create_monitor_test_setup (test_backend, &test_case_setup, @@ -9597,6 +9601,62 @@ meta_test_monitor_custom_for_lease_config_dbus (void) assert_monitor_state (state, 0, "DP-1", FALSE); assert_monitor_state (state, 1, "DP-2", TRUE); + + /* Swap monitor for lease */ + serial = g_variant_get_uint32 (g_variant_get_child_value (state, 0)); + + g_variant_builder_init (&b, G_VARIANT_TYPE ("(uua(iiduba(ssa{sv}))a{sv})")); + g_variant_builder_add (&b, "u", serial); /* Serial from GetCurrentState */ + g_variant_builder_add (&b, "u", 1); /* Method: Temporary */ + + /* Logical monitors */ + g_variant_builder_open (&b, G_VARIANT_TYPE ("a(iiduba(ssa{sv}))")); + g_variant_builder_open (&b, G_VARIANT_TYPE ("(iiduba(ssa{sv}))")); + g_variant_builder_add (&b, "i", 0); /* x */ + g_variant_builder_add (&b, "i", 0); /* y */ + g_variant_builder_add (&b, "d", 1.0); /* Scale */ + g_variant_builder_add (&b, "u", 0); /* Transform */ + g_variant_builder_add (&b, "b", TRUE); /* Primary */ + g_variant_builder_add_parsed (&b, "[(%s, %s, @a{sv} {})]", /* Monitors */ + "DP-2", + "800x600@60.000"); + g_variant_builder_close (&b); + g_variant_builder_close (&b); + + /* Properties */ + g_variant_builder_open (&b, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add_parsed (&b, "{'monitors-for-lease', <[(%s, %s, %s, %s)]>}", + "DP-1", + "MetaProduct\'s Inc.", + "MetaMonitor", + "0x123456"); + g_variant_builder_close (&b); + + g_dbus_proxy_call (display_config_proxy, + "ApplyMonitorsConfig", + g_variant_builder_end (&b), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + on_proxy_call_cb, + &apply_config_ret); + while (!apply_config_ret) + g_main_context_iteration (NULL, TRUE); + + /* Check that monitors changed */ + g_dbus_proxy_call (display_config_proxy, + "GetCurrentState", + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + on_proxy_call_cb, + &new_state); + while (!new_state) + g_main_context_iteration (NULL, TRUE); + + assert_monitor_state (new_state, 0, "DP-1", TRUE); + assert_monitor_state (new_state, 1, "DP-2", FALSE); } static gboolean -- 2.48.1