mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
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.
This commit is contained in:
parent
356cad094b
commit
6d12d2eac2
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 ||
|
||||
|
Loading…
Reference in New Issue
Block a user