diff --git a/src/tests/wayland-test-clients/meson.build b/src/tests/wayland-test-clients/meson.build
index 1cdf1e62e..7a1846ea3 100644
--- a/src/tests/wayland-test-clients/meson.build
+++ b/src/tests/wayland-test-clients/meson.build
@@ -66,6 +66,9 @@ wayland_test_clients = [
{
'name': 'subsurface-reparenting',
},
+ {
+ 'name': 'toplevel-reuse-surface',
+ },
{
'name': 'toplevel-show-states',
},
diff --git a/src/tests/wayland-test-clients/toplevel-reuse-surface.c b/src/tests/wayland-test-clients/toplevel-reuse-surface.c
new file mode 100644
index 000000000..0428523f1
--- /dev/null
+++ b/src/tests/wayland-test-clients/toplevel-reuse-surface.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include "config.h"
+
+#include
+#include
+
+#include "wayland-test-client-utils.h"
+
+typedef enum _State
+{
+ STATE_INIT = 0,
+ STATE_WAIT_FOR_CONFIGURE_1,
+ STATE_WAIT_FOR_CONFIGURE_2,
+ STATE_WAIT_FOR_EFFECTS,
+ STATE_DONE,
+} State;
+
+typedef struct _TestWindow
+{
+ WaylandDisplay *display;
+ struct wl_surface *wl_surface;
+ struct xdg_surface *xdg_surface;
+ struct xdg_toplevel *xdg_toplevel;
+ State state;
+} TestWindow;
+
+static void
+handle_xdg_surface_configure (void *data,
+ struct xdg_surface *xdg_surface,
+ uint32_t serial);
+
+static const struct xdg_surface_listener xdg_surface_listener = {
+ handle_xdg_surface_configure,
+};
+
+static void
+handle_xdg_surface_configure (void *data,
+ struct xdg_surface *xdg_surface,
+ uint32_t serial)
+{
+ TestWindow *window = data;
+ WaylandDisplay *display = window->display;
+
+ switch (window->state)
+ {
+ case STATE_WAIT_FOR_CONFIGURE_1:
+ draw_surface (display, window->wl_surface, 700, 500, 0xff00ff00);
+ xdg_surface_ack_configure (window->xdg_surface, serial);
+ wl_surface_commit (window->wl_surface);
+
+ window->state = STATE_WAIT_FOR_EFFECTS;
+ wait_for_effects_completed (display, window->wl_surface);
+
+ xdg_toplevel_destroy (window->xdg_toplevel);
+ xdg_surface_destroy (window->xdg_surface);
+ wl_surface_attach (window->wl_surface, NULL, 0, 0);
+ wl_surface_commit (window->wl_surface);
+ window->xdg_surface =
+ xdg_wm_base_get_xdg_surface (display->xdg_wm_base, window->wl_surface);
+ xdg_surface_add_listener (window->xdg_surface,
+ &xdg_surface_listener, window);
+ window->xdg_toplevel = xdg_surface_get_toplevel (window->xdg_surface);
+ xdg_toplevel_set_title (window->xdg_toplevel,
+ "toplevel-reuse-surface-test");
+ wl_surface_commit (window->wl_surface);
+ window->state = STATE_WAIT_FOR_CONFIGURE_2;
+ break;
+ case STATE_WAIT_FOR_CONFIGURE_2:
+ draw_surface (display, window->wl_surface, 700, 500, 0xff00ff00);
+ xdg_surface_ack_configure (window->xdg_surface, serial);
+ wl_surface_commit (window->wl_surface);
+
+ window->state = STATE_WAIT_FOR_EFFECTS;
+ wait_for_effects_completed (display, window->wl_surface);
+
+ window->state = STATE_DONE;
+ break;
+ default:
+ break;
+ }
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ g_autoptr (WaylandDisplay) display = NULL;
+ TestWindow window;
+
+ display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER);
+ window.display = display;
+
+ window.wl_surface = wl_compositor_create_surface (display->compositor);
+ window.xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base,
+ window.wl_surface);
+ xdg_surface_add_listener (window.xdg_surface, &xdg_surface_listener, &window);
+ window.xdg_toplevel = xdg_surface_get_toplevel (window.xdg_surface);
+
+ xdg_toplevel_set_title (window.xdg_toplevel,
+ "toplevel-reuse-surface-test");
+ wl_surface_commit (window.wl_surface);
+
+ window.state = STATE_WAIT_FOR_CONFIGURE_1;
+
+ while (window.state != STATE_DONE)
+ {
+ if (wl_display_dispatch (display->display) == -1)
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/tests/wayland-unit-tests.c b/src/tests/wayland-unit-tests.c
index b9d9cf5bd..df87bbce2 100644
--- a/src/tests/wayland-unit-tests.c
+++ b/src/tests/wayland-unit-tests.c
@@ -562,6 +562,16 @@ toplevel_activation (void)
meta_wayland_test_client_finish (wayland_test_client);
}
+static void
+toplevel_reuse_surface (void)
+{
+ MetaWaylandTestClient *wayland_test_client;
+
+ wayland_test_client =
+ meta_wayland_test_client_new (test_context, "toplevel-reuse-surface");
+ meta_wayland_test_client_finish (wayland_test_client);
+}
+
static gboolean
mark_later_as_done (gpointer user_data)
{
@@ -1039,6 +1049,8 @@ init_tests (void)
g_test_add_func ("/wayland/toplevel/bounds/monitors",
toplevel_bounds_monitors);
#endif
+ g_test_add_func ("/wayland/toplevel/reuse-surface",
+ toplevel_reuse_surface);
g_test_add_func ("/wayland/xdg-foreign/set-parent-of",
xdg_foreign_set_parent_of);
g_test_add_func ("/wayland/toplevel/show-states",