diff --git a/src/core/window-private.h b/src/core/window-private.h index 39a23b2a9..ee1225aab 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -684,8 +684,12 @@ void meta_window_resize_frame_with_gravity (MetaWindow *window, gboolean meta_window_should_be_showing_on_workspace (MetaWindow *window, MetaWorkspace *workspace); +META_EXPORT_TEST gboolean meta_window_should_be_showing (MetaWindow *window); +META_EXPORT_TEST +gboolean meta_window_should_show (MetaWindow *window); + void meta_window_update_struts (MetaWindow *window); /* gets position we need to set to stay in current position, diff --git a/src/core/window.c b/src/core/window.c index edfa1ed62..d54d73d40 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1706,6 +1706,41 @@ meta_window_is_showable (MetaWindow *window) return TRUE; } +/** + * meta_window_should_show_on_workspace: + * + * Tells whether a window should be showing on the passed workspace, without + * taking into account whether it can immediately be shown. Whether it can be + * shown or not depends on what windowing system it was created from. + * + * Returns: %TRUE if the window should show. + */ +static gboolean +meta_window_should_show_on_workspace (MetaWindow *window, + MetaWorkspace *workspace) +{ + return (meta_window_located_on_workspace (window, workspace) && + meta_window_showing_on_its_workspace (window)); +} + +/** + * meta_window_should_show: + * + * Tells whether a window should be showing on the current workspace, without + * taking into account whether it can immediately be shown. Whether it can be + * shown or not depends on what windowing system it was created from. + * + * Returns: %TRUE if the window should show. + */ +gboolean +meta_window_should_show (MetaWindow *window) +{ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + MetaWorkspace *active_workspace = workspace_manager->active_workspace; + + return meta_window_should_show_on_workspace (window, active_workspace); +} + /** * meta_window_should_be_showing_on_workspace: * @@ -1722,10 +1757,7 @@ meta_window_should_be_showing_on_workspace (MetaWindow *window, if (!meta_window_is_showable (window)) return FALSE; - /* Windows should be showing if they're located on the - * workspace and they're showing on their own workspace. */ - return (meta_window_located_on_workspace (window, workspace) && - meta_window_showing_on_its_workspace (window)); + return meta_window_should_show_on_workspace (window, workspace); } /** diff --git a/src/tests/wayland-test-clients/meson.build b/src/tests/wayland-test-clients/meson.build index 755e593bd..38ac799d0 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-show-states', + }, { 'name': 'xdg-activation', }, diff --git a/src/tests/wayland-test-clients/toplevel-show-states.c b/src/tests/wayland-test-clients/toplevel-show-states.c new file mode 100644 index 000000000..431436f4c --- /dev/null +++ b/src/tests/wayland-test-clients/toplevel-show-states.c @@ -0,0 +1,59 @@ +/* + * 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 . + */ + +#include "config.h" + +#include +#include + +#include "wayland-test-client-utils.h" + +static gboolean running; + +static void +on_surface_painted (WaylandDisplay *display, + WaylandSurface *surface) +{ + test_driver_sync_point (display->test_driver, 1, NULL); + wl_display_roundtrip (display->display); + running = FALSE; +} + +int +main (int argc, + char **argv) +{ + g_autoptr (WaylandDisplay) display = NULL; + g_autoptr (WaylandSurface) surface = NULL; + + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER | + WAYLAND_DISPLAY_CAPABILITY_XDG_SHELL_V6); + surface = wayland_surface_new (display, "showing-states", 100, 100, 0xffffffff); + wl_surface_commit (surface->wl_surface); + + test_driver_sync_point (display->test_driver, 0, NULL); + wait_for_sync_event (display, 0); + + g_signal_connect (display, "surface-painted", + G_CALLBACK (on_surface_painted), NULL); + + running = TRUE; + while (running) + wayland_display_dispatch (display); + + return EXIT_SUCCESS; +} diff --git a/src/tests/wayland-unit-tests.c b/src/tests/wayland-unit-tests.c index c9f3f32e3..692b723df 100644 --- a/src/tests/wayland-unit-tests.c +++ b/src/tests/wayland-unit-tests.c @@ -844,6 +844,30 @@ xdg_foreign_set_parent_of (void) meta_wayland_test_client_finish (wayland_test_client); } +static void +toplevel_show_states (void) +{ + MetaWaylandTestClient *wayland_test_client; + MetaWindow *window; + + wayland_test_client = + meta_wayland_test_client_new (test_context, "toplevel-show-states"); + + wait_for_sync_point (0); + window = find_client_window ("showing-states"); + + g_assert_true (meta_window_should_show (window)); + g_assert_false (meta_window_should_be_showing (window)); + + meta_wayland_test_driver_emit_sync_event (test_driver, 0); + wait_for_sync_point (1); + + g_assert_true (meta_window_should_show (window)); + g_assert_true (meta_window_should_be_showing (window)); + + meta_wayland_test_client_finish (wayland_test_client); +} + static void on_before_tests (void) { @@ -921,6 +945,8 @@ init_tests (void) #endif g_test_add_func ("/wayland/xdg-foreign/set-parent-of", xdg_foreign_set_parent_of); + g_test_add_func ("/wayland/toplevel/show-states", + toplevel_show_states); } int