diff --git a/src/backends/meta-orientation-manager.c b/src/backends/meta-orientation-manager.c index 52a1d1de6..7989aa84f 100644 --- a/src/backends/meta-orientation-manager.c +++ b/src/backends/meta-orientation-manager.c @@ -52,6 +52,7 @@ struct _MetaOrientationManager GCancellable *cancellable; guint iio_watch_id; + guint sync_idle_id; GDBusProxy *iio_proxy; MetaOrientation prev_orientation; MetaOrientation curr_orientation; @@ -135,13 +136,39 @@ sync_state (MetaOrientationManager *self) g_signal_emit (self, signals[ORIENTATION_CHANGED], 0); } +static gboolean +changed_idle (gpointer user_data) +{ + MetaOrientationManager *self = user_data; + + self->sync_idle_id = 0; + sync_state (self); + + return G_SOURCE_REMOVE; +} + +static void +queue_sync_state (MetaOrientationManager *self) +{ + /* We need this idle to avoid triggering events happening while the session + * is not active (under X11), ideally this should be handled by stopping + * events if the session is not active, but we'll need a MetaLogind available + * in all the backends for having this working. + */ + + if (self->sync_idle_id) + return; + + self->sync_idle_id = g_idle_add (changed_idle, self); +} + static void orientation_lock_changed (GSettings *settings, gchar *key, gpointer user_data) { MetaOrientationManager *self = user_data; - sync_state (self); + queue_sync_state (self); } static void @@ -151,7 +178,7 @@ iio_properties_changed (GDBusProxy *proxy, gpointer user_data) { MetaOrientationManager *self = user_data; - sync_state (self); + queue_sync_state (self); } static void @@ -288,6 +315,7 @@ meta_orientation_manager_finalize (GObject *object) g_clear_object (&self->cancellable); g_bus_unwatch_name (self->iio_watch_id); + g_clear_handle_id (&self->sync_idle_id, g_source_remove); g_clear_object (&self->iio_proxy); g_clear_object (&self->settings); diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c index 73cff8c7f..6b93db0ae 100644 --- a/src/tests/monitor-unit-tests.c +++ b/src/tests/monitor-unit-tests.c @@ -36,6 +36,7 @@ #include "tests/monitor-test-utils.h" #include "tests/meta-test-utils.h" #include "tests/unit-tests.h" +#include "tests/orientation-manager-unit-tests.h" #include "x11/meta-x11-display-private.h" static MonitorTestCase initial_test_case = { @@ -3551,8 +3552,13 @@ typedef MetaSensorsProxyMock MetaSensorsProxyAutoResetMock; static void meta_sensors_proxy_reset (MetaSensorsProxyMock *proxy) { + MetaBackend *backend = meta_get_backend (); + MetaOrientationManager *orientation_manager = + meta_backend_get_orientation_manager (backend); + meta_sensors_proxy_mock_set_orientation (proxy, META_ORIENTATION_NORMAL); + wait_for_orientation_changes (orientation_manager); g_object_unref (proxy); } G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaSensorsProxyAutoResetMock, @@ -3875,6 +3881,7 @@ meta_test_monitor_orientation_initial_rotated (void) touch_device = meta_test_add_touch_device (backend); orientation = META_ORIENTATION_LEFT_UP; meta_sensors_proxy_mock_set_orientation (orientation_mock, orientation); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, @@ -3981,6 +3988,7 @@ meta_test_monitor_orientation_initial_rotated_no_touch_mode (void) orientation_mock = meta_sensors_proxy_mock_get (); orientation = META_ORIENTATION_LEFT_UP; meta_sensors_proxy_mock_set_orientation (orientation_mock, orientation); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, @@ -4097,6 +4105,7 @@ meta_test_monitor_orientation_initial_stored_rotated (void) touch_device = meta_test_add_touch_device (backend); orientation = META_ORIENTATION_RIGHT_UP; meta_sensors_proxy_mock_set_orientation (orientation_mock, orientation); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, @@ -4122,6 +4131,11 @@ meta_test_monitor_orientation_initial_stored_rotated (void) orientation = META_ORIENTATION_LEFT_UP; meta_sensors_proxy_mock_set_orientation (orientation_mock, orientation); + wait_for_orientation_changes (orientation_manager); + g_assert_cmpuint ( + meta_orientation_manager_get_orientation (orientation_manager), + ==, + orientation); meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); meta_monitor_manager_lid_is_closed_changed (monitor_manager); @@ -4136,6 +4150,7 @@ meta_test_monitor_orientation_initial_stored_rotated (void) orientation = META_ORIENTATION_RIGHT_UP; meta_sensors_proxy_mock_set_orientation (orientation_mock, orientation); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, @@ -4247,6 +4262,7 @@ meta_test_monitor_orientation_initial_stored_rotated_no_touch (void) orientation_mock = meta_sensors_proxy_mock_get (); orientation = META_ORIENTATION_RIGHT_UP; meta_sensors_proxy_mock_set_orientation (orientation_mock, orientation); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, @@ -4390,6 +4406,7 @@ meta_test_monitor_orientation_changes (void) MetaMonitorsConfig *previous; meta_sensors_proxy_mock_set_orientation (orientation_mock, i); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, i); @@ -4418,6 +4435,7 @@ meta_test_monitor_orientation_changes (void) meta_sensors_proxy_mock_set_orientation (orientation_mock, META_ORIENTATION_NORMAL); + wait_for_orientation_changes (orientation_manager); META_TEST_LOG_CALL ("Checking configuration per orientation", check_monitor_configuration_per_orientation ( &test_case.expect, 0, META_ORIENTATION_NORMAL, @@ -4435,6 +4453,7 @@ meta_test_monitor_orientation_changes (void) MetaMonitorsConfig *previous; meta_sensors_proxy_mock_set_orientation (orientation_mock, i); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, i); @@ -4611,6 +4630,7 @@ meta_test_monitor_orientation_changes_with_hotplugging (void) for (i = META_N_ORIENTATIONS - 1; i > META_ORIENTATION_UNDEFINED; i--) { meta_sensors_proxy_mock_set_orientation (orientation_mock, i); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, i); @@ -4622,6 +4642,7 @@ meta_test_monitor_orientation_changes_with_hotplugging (void) meta_sensors_proxy_mock_set_orientation (orientation_mock, META_ORIENTATION_NORMAL); + wait_for_orientation_changes (orientation_manager); check_monitor_configuration (&test_case.expect); /* External monitor connected */ @@ -4642,6 +4663,7 @@ meta_test_monitor_orientation_changes_with_hotplugging (void) for (i = META_N_ORIENTATIONS - 1; i > META_ORIENTATION_UNDEFINED; i--) { meta_sensors_proxy_mock_set_orientation (orientation_mock, i); + wait_for_orientation_changes (orientation_manager); g_assert_cmpuint ( meta_orientation_manager_get_orientation (orientation_manager), ==, i); @@ -4653,6 +4675,7 @@ meta_test_monitor_orientation_changes_with_hotplugging (void) meta_sensors_proxy_mock_set_orientation (orientation_mock, META_ORIENTATION_NORMAL); + wait_for_orientation_changes (orientation_manager); check_monitor_configuration (&test_case.expect); /* Lid closed */ @@ -4672,11 +4695,13 @@ meta_test_monitor_orientation_changes_with_hotplugging (void) for (i = META_N_ORIENTATIONS - 1; i > META_ORIENTATION_UNDEFINED; i--) { meta_sensors_proxy_mock_set_orientation (orientation_mock, i); + wait_for_orientation_changes (orientation_manager); check_monitor_configuration (&test_case.expect); } meta_sensors_proxy_mock_set_orientation (orientation_mock, META_ORIENTATION_NORMAL); + wait_for_orientation_changes (orientation_manager); /* * The second part of this test emulate the following at each device rotation: @@ -4719,6 +4744,7 @@ meta_test_monitor_orientation_changes_with_hotplugging (void) /* Change orientation */ meta_sensors_proxy_mock_set_orientation (orientation_mock, i); + wait_for_orientation_changes (orientation_manager); check_monitor_configuration (&test_case.expect); /* Open the lid */ @@ -4734,6 +4760,7 @@ meta_test_monitor_orientation_changes_with_hotplugging (void) meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); emulate_hotplug (test_setup); + wait_for_orientation_changes (orientation_manager); META_TEST_LOG_CALL ("Checking configuration per orientation", check_monitor_configuration_per_orientation ( &test_case.expect, 0, i, 1024, 768)); @@ -4770,6 +4797,7 @@ meta_test_monitor_orientation_changes_with_hotplugging (void) meta_sensors_proxy_mock_set_orientation (orientation_mock, META_ORIENTATION_NORMAL); + wait_for_orientation_changes (orientation_manager); } static void diff --git a/src/tests/orientation-manager-unit-tests.c b/src/tests/orientation-manager-unit-tests.c index 74a861ab0..a936dccb7 100644 --- a/src/tests/orientation-manager-unit-tests.c +++ b/src/tests/orientation-manager-unit-tests.c @@ -24,6 +24,44 @@ #include "tests/meta-sensors-proxy-mock.h" +static void +on_orientation_changed (gpointer data) +{ + gboolean *changed = data; + + *changed = TRUE; +} + +static gboolean +on_max_wait_timeout (gpointer data) +{ + guint *timeout_id = data; + + *timeout_id = 0; + + return G_SOURCE_REMOVE; +} + +void +wait_for_orientation_changes (MetaOrientationManager *orientation_manager) +{ + gboolean changed = FALSE; + gulong connection_id; + guint timeout_id; + + timeout_id = g_timeout_add (300, on_max_wait_timeout, &timeout_id); + connection_id = g_signal_connect_swapped (orientation_manager, + "orientation-changed", + G_CALLBACK (on_orientation_changed), + &changed); + + while (!changed && timeout_id) + g_main_context_iteration (NULL, TRUE); + + g_clear_handle_id (&timeout_id, g_source_remove); + g_signal_handler_disconnect (orientation_manager, connection_id); +} + static void meta_test_orientation_manager_no_daemon (void) { @@ -64,6 +102,7 @@ meta_test_orientation_manager_has_accelerometer (void) meta_sensors_proxy_mock_set_property (orientation_mock, "HasAccelerometer", g_variant_new_boolean (TRUE)); + wait_for_orientation_changes (manager); g_debug ("Checking whether accelerometer is present"); g_assert_true (meta_orientation_manager_has_accelerometer (manager)); @@ -104,6 +143,7 @@ meta_test_orientation_manager_accelerometer_orientations (void) { changed_called = FALSE; meta_sensors_proxy_mock_set_orientation (orientation_mock, i); + wait_for_orientation_changes (manager); g_debug ("Checking orientation %d", i); g_assert_cmpuint (meta_orientation_manager_get_orientation (manager), diff --git a/src/tests/orientation-manager-unit-tests.h b/src/tests/orientation-manager-unit-tests.h index 34b175f0c..56eff09d1 100644 --- a/src/tests/orientation-manager-unit-tests.h +++ b/src/tests/orientation-manager-unit-tests.h @@ -21,6 +21,10 @@ #ifndef ORIENTATION_MANAGER_UNIT_TESTS_H #define ORIENTATION_MANAGER_UNIT_TESTS_H +#include "backends/meta-orientation-manager.h" + void init_orientation_manager_tests (void); +void wait_for_orientation_changes (MetaOrientationManager *orientation_manager); + #endif /* ORIENTATION_MANAGER_UNIT_TESTS_H */