tests: Add more session management tests
Ensure that windows get restored either in maximized and unmaximized state. And ensure that monitors being removed result in windows snapping back to reachable positions. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4311>
This commit is contained in:
parent
e82cc58614
commit
351f2fddff
@ -92,6 +92,7 @@ void meta_context_set_trace_file (MetaContext *context,
|
||||
const char *trace_file);
|
||||
#endif
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaSessionManager * meta_context_get_session_manager (MetaContext *context);
|
||||
|
||||
META_EXPORT_TEST
|
||||
|
@ -660,6 +660,7 @@ gboolean meta_window_has_fullscreen_monitors (MetaWindow *window);
|
||||
void meta_window_adjust_fullscreen_monitor_rect (MetaWindow *window,
|
||||
MtkRectangle *monitor_rect);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_window_resize_frame (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
|
@ -93,6 +93,9 @@ wayland_test_clients = [
|
||||
{
|
||||
'name': 'xdg-session-management-replace',
|
||||
},
|
||||
{
|
||||
'name': 'xdg-session-management-restore',
|
||||
},
|
||||
{
|
||||
'name': 'xdg-toplevel-bounds',
|
||||
},
|
||||
|
220
src/tests/wayland-test-clients/xdg-session-management-restore.c
Normal file
220
src/tests/wayland-test-clients/xdg-session-management-restore.c
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "wayland-test-client-utils.h"
|
||||
|
||||
#include "session-management-v1-client-protocol.h"
|
||||
|
||||
typedef struct _TestDisplayState
|
||||
{
|
||||
struct xx_session_manager_v1 *session_manager;
|
||||
} TestDisplayState;
|
||||
|
||||
static gboolean running = FALSE;
|
||||
|
||||
static void
|
||||
handle_registry_global (void *user_data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t id,
|
||||
const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
WaylandDisplay *display = user_data;
|
||||
TestDisplayState *test_state = display->test_state;
|
||||
|
||||
if (strcmp (interface, "xx_session_manager_v1") == 0)
|
||||
{
|
||||
test_state->session_manager =
|
||||
wl_registry_bind (registry, id, &xx_session_manager_v1_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_registry_global_remove (void *user_data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t name)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
handle_registry_global,
|
||||
handle_registry_global_remove
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean received_created;
|
||||
gboolean received_restored;
|
||||
} TestCreateState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean configured;
|
||||
gboolean restored;
|
||||
} ToplevelSessionState;
|
||||
|
||||
static void
|
||||
test_create_created (void *user_data,
|
||||
struct xx_session_v1 *xdg_session_v1,
|
||||
const char *id)
|
||||
{
|
||||
TestCreateState *state = user_data;
|
||||
|
||||
state->received_created = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_create_restored (void *user_data,
|
||||
struct xx_session_v1 *xdg_session_v1)
|
||||
{
|
||||
TestCreateState *state = user_data;
|
||||
|
||||
state->received_restored = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_create_replaced (void *user_data,
|
||||
struct xx_session_v1 *xdg_session_v1)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xx_session_v1_listener test_create_session_listener = {
|
||||
test_create_created,
|
||||
test_create_restored,
|
||||
test_create_replaced,
|
||||
};
|
||||
|
||||
static void
|
||||
toplevel_restored (void *user_data,
|
||||
struct xx_toplevel_session_v1 *toplevel_session,
|
||||
struct xdg_toplevel *toplevel)
|
||||
{
|
||||
ToplevelSessionState *toplevel_state = user_data;
|
||||
|
||||
toplevel_state->restored = TRUE;
|
||||
}
|
||||
|
||||
static struct xx_toplevel_session_v1_listener toplevel_session_listener = {
|
||||
toplevel_restored,
|
||||
};
|
||||
|
||||
static void
|
||||
on_toplevel_configured (WaylandSurface *surface,
|
||||
ToplevelSessionState *toplevel_state)
|
||||
{
|
||||
toplevel_state->configured = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
simple (WaylandDisplay *display,
|
||||
const char *session_id)
|
||||
{
|
||||
TestDisplayState *test_state = display->test_state;
|
||||
g_autoptr (WaylandSurface) toplevel1 = NULL;
|
||||
struct xx_session_v1 *session;
|
||||
struct xx_toplevel_session_v1 *toplevel_session1;
|
||||
TestCreateState state = {};
|
||||
ToplevelSessionState toplevel_state1 = {};
|
||||
|
||||
toplevel1 = wayland_surface_new (display, "toplevel1",
|
||||
100, 100, 0xff50ff50);
|
||||
g_signal_connect (toplevel1, "configure",
|
||||
G_CALLBACK (on_toplevel_configured),
|
||||
&toplevel_state1);
|
||||
|
||||
session =
|
||||
xx_session_manager_v1_get_session (test_state->session_manager,
|
||||
XX_SESSION_MANAGER_V1_REASON_LAUNCH,
|
||||
session_id);
|
||||
xx_session_v1_add_listener (session, &test_create_session_listener, &state);
|
||||
|
||||
while (!state.received_created && !state.received_restored)
|
||||
wayland_display_dispatch (display);
|
||||
|
||||
if (session_id)
|
||||
g_assert_true (state.received_restored);
|
||||
else
|
||||
g_assert_true (state.received_created);
|
||||
|
||||
toplevel_session1 = xx_session_v1_restore_toplevel (session,
|
||||
toplevel1->xdg_toplevel,
|
||||
"toplevel1");
|
||||
xx_toplevel_session_v1_add_listener (toplevel_session1,
|
||||
&toplevel_session_listener,
|
||||
&toplevel_state1);
|
||||
|
||||
wl_surface_commit (toplevel1->wl_surface);
|
||||
|
||||
running = TRUE;
|
||||
while (running)
|
||||
wayland_display_dispatch (display);
|
||||
|
||||
xx_toplevel_session_v1_destroy (toplevel_session1);
|
||||
xx_session_v1_destroy (session);
|
||||
}
|
||||
|
||||
static void
|
||||
on_surface_painted (WaylandDisplay *display,
|
||||
WaylandSurface *surface)
|
||||
{
|
||||
static gboolean first_painted = FALSE;
|
||||
|
||||
if (first_painted)
|
||||
return;
|
||||
|
||||
first_painted = TRUE;
|
||||
|
||||
/* Sync point to let parent test do checks */
|
||||
test_driver_sync_point (display->test_driver, 0, NULL);
|
||||
wait_for_sync_event (display, 0);
|
||||
running = FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
g_autoptr (WaylandDisplay) display = NULL;
|
||||
struct wl_registry *registry;
|
||||
TestDisplayState *test_state;
|
||||
const char *session_id = NULL;
|
||||
|
||||
if (argc > 1)
|
||||
session_id = argv[1];
|
||||
|
||||
display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER);
|
||||
test_state = g_new0 (TestDisplayState, 1);
|
||||
display->test_state = test_state;
|
||||
display->destroy_test_state = g_free;
|
||||
|
||||
g_signal_connect (display, "surface-painted",
|
||||
G_CALLBACK (on_surface_painted), NULL);
|
||||
|
||||
registry = wl_display_get_registry (display->display);
|
||||
wl_registry_add_listener (registry, ®istry_listener, display);
|
||||
wl_display_roundtrip (display->display);
|
||||
|
||||
g_assert_nonnull (test_state->session_manager);
|
||||
|
||||
simple (display, session_id);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -37,6 +37,7 @@
|
||||
#include "wayland/meta-wayland-client-private.h"
|
||||
#include "wayland/meta-wayland-filter-manager.h"
|
||||
#include "wayland/meta-wayland-surface-private.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
|
||||
#include "dummy-client-protocol.h"
|
||||
#include "dummy-server-protocol.h"
|
||||
@ -629,6 +630,17 @@ wait_until_after_paint (void)
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_session_instantiated (MetaSessionManager *session_manager,
|
||||
const char *name,
|
||||
MetaSessionState *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
char **session_id = user_data;
|
||||
|
||||
*session_id = g_strdup (name);
|
||||
}
|
||||
|
||||
static void
|
||||
set_struts (MtkRectangle rect,
|
||||
MetaSide side)
|
||||
@ -684,6 +696,226 @@ get_primary_logical_monitor_layout (void)
|
||||
return meta_logical_monitor_get_layout (logical_monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_sessions_restore (void)
|
||||
{
|
||||
MetaSessionManager *session_manager;
|
||||
MetaWaylandTestClient *wayland_test_client;
|
||||
MetaBackend *backend = meta_context_get_backend (test_context);
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
MetaWindow *window;
|
||||
MtkRectangle frame_rect;
|
||||
g_autofree char *session_id = NULL;
|
||||
|
||||
session_manager = meta_context_get_session_manager (test_context);
|
||||
g_signal_connect (session_manager, "session-instantiated",
|
||||
G_CALLBACK (on_session_instantiated), &session_id);
|
||||
|
||||
/* Launch client once, resize window */
|
||||
wayland_test_client =
|
||||
meta_wayland_test_client_new (test_context, "xdg-session-management-restore");
|
||||
|
||||
wait_for_sync_point (0);
|
||||
wait_for_paint (stage);
|
||||
|
||||
window = find_client_window ("toplevel1");
|
||||
g_assert_nonnull (window);
|
||||
|
||||
g_assert_nonnull (window->monitor);
|
||||
frame_rect = meta_window_config_get_rect (window->config);
|
||||
g_assert_cmpint (frame_rect.width, ==, 100);
|
||||
g_assert_cmpint (frame_rect.height, ==, 100);
|
||||
|
||||
meta_window_move_resize_frame (window, FALSE, 123, 234, 200, 200);
|
||||
wait_for_paint (stage);
|
||||
|
||||
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
||||
meta_wayland_test_client_finish (wayland_test_client);
|
||||
|
||||
g_assert_nonnull (session_id);
|
||||
|
||||
/* Launch client again, check window size persists */
|
||||
wayland_test_client =
|
||||
meta_wayland_test_client_new_with_args (test_context,
|
||||
"xdg-session-management-restore",
|
||||
session_id,
|
||||
NULL);
|
||||
|
||||
wait_for_sync_point (0);
|
||||
|
||||
window = find_client_window ("toplevel1");
|
||||
g_assert_nonnull (window);
|
||||
|
||||
g_assert_nonnull (window->monitor);
|
||||
frame_rect = meta_window_config_get_rect (window->config);
|
||||
g_assert_cmpint (frame_rect.x, ==, 123);
|
||||
g_assert_cmpint (frame_rect.y, ==, 234);
|
||||
g_assert_cmpint (frame_rect.width, ==, 200);
|
||||
g_assert_cmpint (frame_rect.height, ==, 200);
|
||||
|
||||
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
||||
meta_wayland_test_client_finish (wayland_test_client);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_sessions_restore_fullscreen (void)
|
||||
{
|
||||
MetaSessionManager *session_manager;
|
||||
g_autoptr (MetaVirtualMonitor) second_virtual_monitor = NULL;
|
||||
MetaBackend *backend = meta_context_get_backend (test_context);
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
MetaWaylandTestClient *wayland_test_client;
|
||||
MetaWindow *window;
|
||||
MtkRectangle frame_rect, monitor_layout;
|
||||
g_autofree char *session_id = NULL;
|
||||
|
||||
monitor_layout = get_primary_logical_monitor_layout ();
|
||||
|
||||
second_virtual_monitor = meta_create_test_monitor (test_context,
|
||||
800, 600, 60.0);
|
||||
|
||||
session_manager = meta_context_get_session_manager (test_context);
|
||||
g_signal_connect (session_manager, "session-instantiated",
|
||||
G_CALLBACK (on_session_instantiated), &session_id);
|
||||
|
||||
/* Launch client once, resize window */
|
||||
wayland_test_client =
|
||||
meta_wayland_test_client_new (test_context, "xdg-session-management-restore");
|
||||
|
||||
wait_for_sync_point (0);
|
||||
wait_for_paint (stage);
|
||||
|
||||
window = find_client_window ("toplevel1");
|
||||
g_assert_nonnull (window);
|
||||
|
||||
/* Move to second monitor */
|
||||
meta_window_move_resize_frame (window, FALSE,
|
||||
monitor_layout.width + 123, 123, 100, 100);
|
||||
wait_for_paint (stage);
|
||||
|
||||
frame_rect = meta_window_config_get_rect (window->config);
|
||||
g_assert_cmpint (frame_rect.x, ==, monitor_layout.width + 123);
|
||||
g_assert_cmpint (frame_rect.y, ==, 123);
|
||||
g_assert_cmpint (frame_rect.width, ==, 100);
|
||||
g_assert_cmpint (frame_rect.height, ==, 100);
|
||||
|
||||
meta_window_make_fullscreen (window);
|
||||
|
||||
while (!meta_window_wayland_is_acked_fullscreen (META_WINDOW_WAYLAND (window)))
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
frame_rect = meta_window_config_get_rect (window->config);
|
||||
g_assert_cmpint (frame_rect.x, ==, 640);
|
||||
g_assert_cmpint (frame_rect.y, ==, 0);
|
||||
g_assert_cmpint (frame_rect.width, ==, 800);
|
||||
g_assert_cmpint (frame_rect.height, ==, 600);
|
||||
|
||||
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
||||
meta_wayland_test_client_finish (wayland_test_client);
|
||||
|
||||
g_assert_nonnull (session_id);
|
||||
|
||||
/* Launch client again, check window persists maximized on second monitor */
|
||||
wayland_test_client =
|
||||
meta_wayland_test_client_new_with_args (test_context,
|
||||
"xdg-session-management-restore",
|
||||
session_id,
|
||||
NULL);
|
||||
|
||||
wait_for_sync_point (0);
|
||||
|
||||
window = find_client_window ("toplevel1");
|
||||
g_assert_nonnull (window);
|
||||
|
||||
g_assert_nonnull (window->monitor);
|
||||
frame_rect = meta_window_config_get_rect (window->config);
|
||||
g_assert_cmpint (frame_rect.x, ==, monitor_layout.width);
|
||||
g_assert_cmpint (frame_rect.y, ==, 0);
|
||||
g_assert_cmpint (frame_rect.width, ==, 800);
|
||||
g_assert_cmpint (frame_rect.height, ==, 600);
|
||||
|
||||
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
||||
meta_wayland_test_client_finish (wayland_test_client);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_sessions_restore_fullscreen_monitor_removed (void)
|
||||
{
|
||||
MetaSessionManager *session_manager;
|
||||
g_autoptr (MetaVirtualMonitor) second_virtual_monitor = NULL;
|
||||
MetaBackend *backend = meta_context_get_backend (test_context);
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
MetaWaylandTestClient *wayland_test_client;
|
||||
MetaWindow *window;
|
||||
MtkRectangle frame_rect, monitor_layout;
|
||||
g_autofree char *session_id = NULL;
|
||||
|
||||
monitor_layout = get_primary_logical_monitor_layout ();
|
||||
|
||||
second_virtual_monitor = meta_create_test_monitor (test_context,
|
||||
640, 480, 60.0);
|
||||
|
||||
session_manager = meta_context_get_session_manager (test_context);
|
||||
g_signal_connect (session_manager, "session-instantiated",
|
||||
G_CALLBACK (on_session_instantiated), &session_id);
|
||||
|
||||
/* Launch client once, resize window */
|
||||
wayland_test_client =
|
||||
meta_wayland_test_client_new (test_context, "xdg-session-management-restore");
|
||||
|
||||
wait_for_sync_point (0);
|
||||
wait_for_paint (stage);
|
||||
|
||||
window = find_client_window ("toplevel1");
|
||||
g_assert_nonnull (window);
|
||||
|
||||
/* Move to second monitor */
|
||||
meta_window_move_resize_frame (window, FALSE,
|
||||
monitor_layout.width, 123, 100, 100);
|
||||
meta_window_make_fullscreen (window);
|
||||
|
||||
while (!meta_window_wayland_is_acked_fullscreen (META_WINDOW_WAYLAND (window)))
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
frame_rect = meta_window_config_get_rect (window->config);
|
||||
g_assert_cmpint (frame_rect.x, ==, monitor_layout.width);
|
||||
g_assert_cmpint (frame_rect.y, ==, 0);
|
||||
g_assert_cmpint (frame_rect.width, ==, 640);
|
||||
g_assert_cmpint (frame_rect.height, ==, 480);
|
||||
|
||||
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
||||
meta_wayland_test_client_finish (wayland_test_client);
|
||||
|
||||
g_assert_nonnull (session_id);
|
||||
|
||||
/* Destroy second monitor */
|
||||
g_clear_object (&second_virtual_monitor);
|
||||
wait_for_paint (stage);
|
||||
|
||||
/* Launch client again, check window moves to first monitor */
|
||||
wayland_test_client =
|
||||
meta_wayland_test_client_new_with_args (test_context,
|
||||
"xdg-session-management-restore",
|
||||
session_id,
|
||||
NULL);
|
||||
|
||||
wait_for_sync_point (0);
|
||||
wait_for_paint (stage);
|
||||
|
||||
window = find_client_window ("toplevel1");
|
||||
g_assert_nonnull (window);
|
||||
|
||||
g_assert_nonnull (window->monitor);
|
||||
frame_rect = meta_window_config_get_rect (window->config);
|
||||
g_assert_cmpint (frame_rect.x, ==, 0);
|
||||
g_assert_cmpint (frame_rect.y, ==, 0);
|
||||
g_assert_cmpint (frame_rect.width, ==, 640);
|
||||
g_assert_cmpint (frame_rect.height, ==, 480);
|
||||
|
||||
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
||||
meta_wayland_test_client_finish (wayland_test_client);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_bounds_struts (void)
|
||||
{
|
||||
@ -1070,10 +1302,18 @@ init_tests (void)
|
||||
toplevel_sessions);
|
||||
g_test_add_func ("/wayland/toplevel/sessions-replace",
|
||||
toplevel_sessions_replace);
|
||||
g_test_add_func ("/wayland/toplevel/sessions-restore",
|
||||
toplevel_sessions_restore);
|
||||
#ifdef MUTTER_PRIVILEGED_TEST
|
||||
(void)(toplevel_sessions_restore_fullscreen);
|
||||
(void)(toplevel_sessions_restore_fullscreen_monitor_removed);
|
||||
(void)(toplevel_bounds_struts);
|
||||
(void)(toplevel_bounds_monitors);
|
||||
#else
|
||||
g_test_add_func ("/wayland/toplevel/sessions-restore-fullscreen",
|
||||
toplevel_sessions_restore_fullscreen);
|
||||
g_test_add_func ("/wayland/toplevel/sessions-restore-fullscreen-monitor-removed",
|
||||
toplevel_sessions_restore_fullscreen_monitor_removed);
|
||||
g_test_add_func ("/wayland/toplevel/bounds/struts",
|
||||
toplevel_bounds_struts);
|
||||
g_test_add_func ("/wayland/toplevel/bounds/monitors",
|
||||
|
Loading…
x
Reference in New Issue
Block a user