[mutter] tests: Move window-shown verification to test-runner
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] tests: Move window-shown verification to test-runner
- Date: Tue, 17 Jul 2018 14:53:53 +0000 (UTC)
commit 6d12d2eac21003607182f3daebd8579bbf5bbb32
Author: Jonas Ådahl <jadahl gmail com>
Date: Thu Jul 12 10:25:16 2018 +0200
tests: Move window-shown verification to test-runner
Previously we relied on the test-client to make sure that a window was
shown. For X11, we did not need to do anything, but for Wayland we had
to make sure we had drawn the first frame, otherwise mutter wouldn't
have a buffer making the window not showable.
Doing it this way doesn't work anymore however, since the 'after-paint'
event will be emitted even if we didn't actually paint anything. This is
the case with current Gtk under Wayland, where we won't draw until the
compositor has configured the surface. In effect, this mean we'll get a
dummy after-paint emission before the first frame is actually painted.
Instead, move the verification that a "show" command has completed by
having the test-runner wait for a "shown" signal on the window, which is
emitted in the end of meta_window_show(). This requires an additional
call to gdk_display_sync() in the test-client after creating the window,
to make sure that the window creation vents has been received in the
compositor.
src/core/window.c | 18 ++++++++++++++
src/tests/test-client.c | 26 +------------------
src/tests/test-runner.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 83 insertions(+), 27 deletions(-)
---
diff --git a/src/core/window.c b/src/core/window.c
index 3322ffb0f..7ded9f3aa 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -195,6 +195,7 @@ enum
UNMANAGED,
SIZE_CHANGED,
POSITION_CHANGED,
+ SHOWN,
LAST_SIGNAL
};
@@ -642,6 +643,20 @@ meta_window_class_init (MetaWindowClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 0);
+ /**
+ * MetaWindow::shown:
+ * @window: a #MetaWindow
+ *
+ * This is emitted after a window has been shown.
+ */
+ window_signals[SHOWN] =
+ g_signal_new ("shown",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+
/**
* MetaWindow::size-changed:
* @window: a #MetaWindow
@@ -2553,6 +2568,9 @@ meta_window_show (MetaWindow *window)
g_signal_emit_by_name (window->display, "window-demands-attention",
window);
}
+
+ if (did_show)
+ g_signal_emit (window, window_signals[SHOWN], 0);
}
static void
diff --git a/src/tests/test-client.c b/src/tests/test-client.c
index 583608300..0c8eafc98 100644
--- a/src/tests/test-client.c
+++ b/src/tests/test-client.c
@@ -41,16 +41,6 @@ lookup_window (const char *window_id)
return window;
}
-static void
-on_after_paint (GdkFrameClock *clock,
- GMainLoop *loop)
-{
- g_signal_handlers_disconnect_by_func (clock,
- (gpointer) on_after_paint,
- loop);
- g_main_loop_quit (loop);
-}
-
static void
process_line (const char *line)
{
@@ -170,25 +160,11 @@ process_line (const char *line)
}
GtkWidget *window = lookup_window (argv[1]);
- GdkWindow *gdk_window = gtk_widget_get_window (window);
if (!window)
goto out;
gtk_widget_show (window);
-
- /* When a Wayland client, we cannot be really sure that the window has
- * been mappable until after we have painted. So, in order to have the
- * test runner rely on the "show" command to have done what the client
- * needs to do in order for a window to be mappable compositor side, lets
- * wait with returning until after the first frame.
- */
- GdkFrameClock *frame_clock = gdk_window_get_frame_clock (gdk_window);
- GMainLoop *loop = g_main_loop_new (NULL, FALSE);
- g_signal_connect (frame_clock, "after-paint",
- G_CALLBACK (on_after_paint),
- loop);
- g_main_loop_run (loop);
- g_main_loop_unref (loop);
+ gdk_display_sync (gdk_display_get_default ());
}
else if (strcmp (argv[0], "hide") == 0)
{
diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c
index 7b0917f21..5c3d25bc9 100644
--- a/src/tests/test-runner.c
+++ b/src/tests/test-runner.c
@@ -327,6 +327,39 @@ test_case_check_xserver_stacking (TestCase *test,
return *error == NULL;
}
+typedef struct _WaitForShownData
+{
+ GMainLoop *loop;
+ MetaWindow *window;
+ guint shown_handler_id;
+} WaitForShownData;
+
+static void
+on_window_shown (MetaWindow *window,
+ WaitForShownData *data)
+{
+ g_main_loop_quit (data->loop);
+}
+
+static gboolean
+test_case_wait_for_showing_before_redraw (gpointer user_data)
+{
+ WaitForShownData *data = user_data;
+
+ if (meta_window_is_hidden (data->window))
+ {
+ data->shown_handler_id = g_signal_connect (data->window, "shown",
+ G_CALLBACK (on_window_shown),
+ data);
+ }
+ else
+ {
+ g_main_loop_quit (data->loop);
+ }
+
+ return FALSE;
+}
+
static gboolean
test_case_do (TestCase *test,
int argc,
@@ -407,8 +440,37 @@ test_case_do (TestCase *test,
NULL))
return FALSE;
}
- else if (strcmp (argv[0], "show") == 0 ||
- strcmp (argv[0], "hide") == 0 ||
+ else if (strcmp (argv[0], "show") == 0)
+ {
+ if (argc != 2)
+ BAD_COMMAND("usage: %s <client-id>/<window-id>", argv[0]);
+
+ TestClient *client;
+ const char *window_id;
+ if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
+ return FALSE;
+
+ if (!test_client_do (client, error, argv[0], window_id, NULL))
+ return FALSE;
+
+ MetaWindow *window = test_client_find_window (client, window_id, error);
+ if (!window)
+ return FALSE;
+
+ WaitForShownData data = {
+ .loop = g_main_loop_new (NULL, FALSE),
+ .window = window,
+ };
+ meta_later_add (META_LATER_BEFORE_REDRAW,
+ test_case_wait_for_showing_before_redraw,
+ &data,
+ NULL);
+ g_main_loop_run (data.loop);
+ if (data.shown_handler_id)
+ g_signal_handler_disconnect (window, data.shown_handler_id);
+ g_main_loop_unref (data.loop);
+ }
+ else if (strcmp (argv[0], "hide") == 0 ||
strcmp (argv[0], "activate") == 0 ||
strcmp (argv[0], "raise") == 0 ||
strcmp (argv[0], "lower") == 0 ||
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]