1
0
Fork 0

display-config: Add HasExternalMonitor property

This aims to replace gnome-setting-daemon manually trying to figure this
state out, currently via libgnome-rr.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3861>
This commit is contained in:
Jonas Ådahl 2024-07-01 21:54:13 +02:00
parent cc0ec14712
commit 7c7e147fd2
4 changed files with 222 additions and 0 deletions

View file

@ -521,5 +521,12 @@
<arg name="output" direction="in" type="u" />
<arg name="ctm" direction="in" type="(ttttttttt)" />
</method>
<!--
HasExternalmonitor:
True if there is an external monitor connected and activated.
-->
<property name="HasExternalMonitor" type="b" access="read" />
</interface>
</node>

View file

@ -1205,11 +1205,36 @@ update_night_light_supported (MetaMonitorManager *manager)
night_light_supported);
}
static void
update_has_external_monitor (MetaMonitorManager *monitor_manager)
{
GList *l;
gboolean has_external_monitor = FALSE;
for (l = meta_monitor_manager_get_monitors (monitor_manager); l; l = l->next)
{
MetaMonitor *monitor = l->data;
if (meta_monitor_is_laptop_panel (monitor))
continue;
if (!meta_monitor_is_active (monitor))
continue;
has_external_monitor = TRUE;
break;
}
meta_dbus_display_config_set_has_external_monitor (monitor_manager->display_config,
has_external_monitor);
}
static void
meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
{
meta_backend_monitors_changed (manager->backend);
update_has_external_monitor (manager);
update_backlight (manager, TRUE);
g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0);
@ -1247,6 +1272,7 @@ meta_monitor_manager_setup (MetaMonitorManager *manager)
meta_monitor_manager_notify_monitors_changed (manager);
update_has_external_monitor (manager);
update_backlight (manager, TRUE);
manager->in_init = FALSE;

View file

@ -124,6 +124,7 @@ gboolean meta_monitor_get_max_bpc (MetaMonitor *monitor,
MetaOutputRGBRange meta_monitor_get_rgb_range (MetaMonitor *monitor);
META_EXPORT_TEST
gboolean meta_monitor_is_laptop_panel (MetaMonitor *monitor);
gboolean meta_monitor_is_virtual (MetaMonitor *monitor);

View file

@ -4113,6 +4113,191 @@ meta_test_monitor_switch_config_remember_scale (void)
check_monitor_test_clients_state ();
}
static void
wait_for_boolean_property (GDBusProxy *proxy,
const char *property_name,
gboolean expected_value)
{
g_debug ("Waiting for property '%s' to become %s on '%s'",
property_name,
expected_value ? "TRUE" : "FALSE",
g_dbus_proxy_get_interface_name (proxy));
while (TRUE)
{
g_autoptr (GVariant) value_variant = NULL;
value_variant = g_dbus_proxy_get_cached_property (proxy, property_name);
g_assert_nonnull (value_variant);
if (g_variant_get_boolean (value_variant) == expected_value)
break;
g_main_context_iteration (NULL, TRUE);
}
}
static void
proxy_ready_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GDBusProxy *proxy;
GDBusProxy **display_config_proxy_ptr = user_data;
g_autoptr (GError) error = NULL;
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
g_assert_nonnull (proxy);
g_assert_no_error (error);
*display_config_proxy_ptr = proxy;
}
static void
meta_test_monitor_has_external_monitor (void)
{
MonitorTestCaseSetup test_case_setup = {
.modes = {
{
.width = 800,
.height = 600,
.refresh_rate = 60.0
},
},
.n_modes = 1,
.outputs = {
{
.crtc = -1,
.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 = FALSE,
}
},
.n_outputs = 2,
.crtcs = {
{
.current_mode = -1
}
},
.n_crtcs = 2
};
MetaBackend *backend = meta_context_get_backend (test_context);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaMonitorTestSetup *test_setup;
GList *monitors;
MetaMonitor *first_monitor;
MetaMonitor *second_monitor;
g_autoptr (GDBusProxy) display_config_proxy = NULL;
g_autoptr (GError) error = NULL;
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
NULL,
"org.gnome.Mutter.DisplayConfig",
"/org/gnome/Mutter/DisplayConfig",
"org.gnome.Mutter.DisplayConfig",
NULL,
proxy_ready_cb,
&display_config_proxy);
while (!display_config_proxy)
g_main_context_iteration (NULL, TRUE);
g_debug ("Connecting one builtin and one external monitor");
test_setup = meta_create_monitor_test_setup (test_backend,
&test_case_setup,
MONITOR_TEST_FLAG_NO_STORED);
emulate_hotplug (test_setup);
monitors = meta_monitor_manager_get_monitors (monitor_manager);
g_assert_cmpuint (g_list_length (monitors), ==, 2);
first_monitor = g_list_nth_data (monitors, 0);
second_monitor = g_list_nth_data (monitors, 1);
g_assert_true (meta_monitor_is_laptop_panel (first_monitor));
g_assert_true (meta_monitor_is_active (first_monitor));
g_assert_false (meta_monitor_is_laptop_panel (second_monitor));
g_assert_true (meta_monitor_is_active (second_monitor));
wait_for_boolean_property (G_DBUS_PROXY (display_config_proxy),
"HasExternalMonitor",
TRUE);
g_debug ("Disconnecting external monitor");
test_case_setup.n_outputs = 1;
test_setup = meta_create_monitor_test_setup (test_backend,
&test_case_setup,
MONITOR_TEST_FLAG_NO_STORED);
emulate_hotplug (test_setup);
monitors = meta_monitor_manager_get_monitors (monitor_manager);
g_assert_cmpuint (g_list_length (monitors), ==, 1);
first_monitor = g_list_nth_data (monitors, 0);
g_assert_true (meta_monitor_is_laptop_panel (first_monitor));
g_assert_true (meta_monitor_is_active (first_monitor));
wait_for_boolean_property (G_DBUS_PROXY (display_config_proxy),
"HasExternalMonitor",
FALSE);
g_debug ("Reconnect external monitor.");
test_case_setup.n_outputs = 2;
test_setup = meta_create_monitor_test_setup (test_backend,
&test_case_setup,
MONITOR_TEST_FLAG_NO_STORED);
emulate_hotplug (test_setup);
monitors = meta_monitor_manager_get_monitors (monitor_manager);
g_assert_cmpuint (g_list_length (monitors), ==, 2);
first_monitor = g_list_nth_data (monitors, 0);
second_monitor = g_list_nth_data (monitors, 1);
g_assert_true (meta_monitor_is_laptop_panel (first_monitor));
g_assert_true (meta_monitor_is_active (first_monitor));
g_assert_false (meta_monitor_is_laptop_panel (second_monitor));
g_assert_true (meta_monitor_is_active (second_monitor));
wait_for_boolean_property (G_DBUS_PROXY (display_config_proxy),
"HasExternalMonitor",
TRUE);
g_debug ("Disable external monitor.");
meta_monitor_manager_switch_config (monitor_manager,
META_MONITOR_SWITCH_CONFIG_BUILTIN);
while (g_main_context_iteration (NULL, FALSE));
monitors = meta_monitor_manager_get_monitors (monitor_manager);
g_assert_cmpuint (g_list_length (monitors), ==, 2);
first_monitor = g_list_nth_data (monitors, 0);
second_monitor = g_list_nth_data (monitors, 1);
g_assert_true (meta_monitor_is_laptop_panel (first_monitor));
g_assert_true (meta_monitor_is_active (first_monitor));
g_assert_false (meta_monitor_is_laptop_panel (second_monitor));
g_assert_false (meta_monitor_is_active (second_monitor));
wait_for_boolean_property (G_DBUS_PROXY (display_config_proxy),
"HasExternalMonitor",
FALSE);
}
static void
check_monitor_configuration_per_orientation (MonitorTestCase *test_case,
unsigned int monitor_index,
@ -10153,6 +10338,9 @@ init_monitor_tests (void)
add_monitor_test ("/backends/monitor/switch-config-remember-scale",
meta_test_monitor_switch_config_remember_scale);
add_monitor_test ("/backends/monitor/has-external-monitor",
meta_test_monitor_has_external_monitor);
add_monitor_test ("/backends/monitor/orientation/is-managed",
meta_test_monitor_orientation_is_managed);
add_monitor_test ("/backends/monitor/orientation/initial-rotated",