| // | |
| // Copyright 2026 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // window_system_unittest.cpp: Unit tests for the X11-vs-Wayland selection policy. | |
| #include "common/linux/window_system.h" | |
| #include <gtest/gtest.h> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include "common/system_utils.h" | |
| namespace angle | |
| { | |
| namespace | |
| { | |
| // Clears the session variables and restores them on destruction, so tests do | |
| // not depend on the session the test runner itself is in. | |
| class ScopedSessionEnvironment | |
| { | |
| public: | |
| ScopedSessionEnvironment() | |
| { | |
| for (const char *name : kSessionVars) | |
| { | |
| mSaved.emplace_back(name, GetEnvironmentVar(name)); | |
| UnsetEnvironmentVar(name); | |
| } | |
| } | |
| ~ScopedSessionEnvironment() | |
| { | |
| for (const auto &[name, value] : mSaved) | |
| { | |
| if (value.empty()) | |
| { | |
| UnsetEnvironmentVar(name); | |
| } | |
| else | |
| { | |
| SetEnvironmentVar(name, value.c_str()); | |
| } | |
| } | |
| } | |
| private: | |
| static constexpr const char *kSessionVars[] = {"WAYLAND_DISPLAY", "XDG_SESSION_TYPE", | |
| "DESKTOP_SESSION"}; | |
| std::vector<std::pair<const char *, std::string>> mSaved; | |
| }; | |
| // Both backends compiled: the preference wins. | |
| TEST(WindowSystemTest, BothCompiled) | |
| { | |
| EXPECT_EQ(WindowSystem::X11, ChoosePreferredWindowSystem(/*x11=*/true, /*wayland=*/true, | |
| /*preferred=*/WindowSystem::X11)); | |
| EXPECT_EQ(WindowSystem::Wayland, | |
| ChoosePreferredWindowSystem(/*x11=*/true, /*wayland=*/true, | |
| /*preferred=*/WindowSystem::Wayland)); | |
| } | |
| // Only one backend compiled: it is always chosen regardless of the environment. | |
| TEST(WindowSystemTest, SingleBackend) | |
| { | |
| EXPECT_EQ(WindowSystem::X11, ChoosePreferredWindowSystem(/*x11=*/true, /*wayland=*/false, | |
| /*preferred=*/WindowSystem::X11)); | |
| EXPECT_EQ(WindowSystem::X11, ChoosePreferredWindowSystem(/*x11=*/true, /*wayland=*/false, | |
| /*preferred=*/WindowSystem::Wayland)); | |
| EXPECT_EQ(WindowSystem::Wayland, ChoosePreferredWindowSystem(/*x11=*/false, /*wayland=*/true, | |
| /*preferred=*/WindowSystem::X11)); | |
| EXPECT_EQ(WindowSystem::Wayland, | |
| ChoosePreferredWindowSystem(/*x11=*/false, /*wayland=*/true, | |
| /*preferred=*/WindowSystem::Wayland)); | |
| } | |
| // Neither backend compiled: nothing can be selected. | |
| TEST(WindowSystemTest, NeitherCompiled) | |
| { | |
| EXPECT_EQ(WindowSystem::Unspecified, | |
| ChoosePreferredWindowSystem(/*x11=*/false, /*wayland=*/false, | |
| /*preferred=*/WindowSystem::X11)); | |
| EXPECT_EQ(WindowSystem::Unspecified, | |
| ChoosePreferredWindowSystem(/*x11=*/false, /*wayland=*/false, | |
| /*preferred=*/WindowSystem::Wayland)); | |
| } | |
| // An X11 session, or no session information at all, is not a Wayland session. | |
| TEST(WindowSystemTest, SessionNotWayland) | |
| { | |
| ScopedSessionEnvironment scopedEnvironment; | |
| EXPECT_FALSE(IsWaylandSession()); | |
| SetEnvironmentVar("XDG_SESSION_TYPE", "x11"); | |
| SetEnvironmentVar("DESKTOP_SESSION", "plasmax11"); | |
| EXPECT_FALSE(IsWaylandSession()); | |
| } | |
| // Any one of the session variables on its own marks a Wayland session, which is | |
| // what keeps this in agreement with rx::IsXWayland(). | |
| TEST(WindowSystemTest, SessionWayland) | |
| { | |
| ScopedSessionEnvironment scopedEnvironment; | |
| SetEnvironmentVar("WAYLAND_DISPLAY", "wayland-1"); | |
| EXPECT_TRUE(IsWaylandSession()); | |
| UnsetEnvironmentVar("WAYLAND_DISPLAY"); | |
| SetEnvironmentVar("XDG_SESSION_TYPE", "wayland"); | |
| EXPECT_TRUE(IsWaylandSession()); | |
| UnsetEnvironmentVar("XDG_SESSION_TYPE"); | |
| SetEnvironmentVar("DESKTOP_SESSION", "plasmawayland"); | |
| EXPECT_TRUE(IsWaylandSession()); | |
| } | |
| // The session hints must not pick a backend. A Wayland session reached through | |
| // XWayland exports no WAYLAND_DISPLAY, so it is a Wayland session but resolves | |
| // to X11 when both backends are compiled. | |
| TEST(WindowSystemTest, SessionHintsDoNotSelectWayland) | |
| { | |
| ScopedSessionEnvironment scopedEnvironment; | |
| SetEnvironmentVar("XDG_SESSION_TYPE", "wayland"); | |
| SetEnvironmentVar("DESKTOP_SESSION", "plasmawayland"); | |
| EXPECT_TRUE(IsWaylandSession()); | |
| EXPECT_FALSE(IsWaylandDisplay()); | |
| EXPECT_EQ(WindowSystem::X11, GetWindowSystemFromEnvironment()); | |
| EXPECT_EQ(WindowSystem::X11, ChoosePreferredWindowSystem(/*x11=*/true, /*wayland=*/true, | |
| GetWindowSystemFromEnvironment())); | |
| // WAYLAND_DISPLAY is what moves selection to Wayland. | |
| SetEnvironmentVar("WAYLAND_DISPLAY", "wayland-1"); | |
| EXPECT_TRUE(IsWaylandDisplay()); | |
| EXPECT_EQ(WindowSystem::Wayland, GetWindowSystemFromEnvironment()); | |
| EXPECT_EQ(WindowSystem::Wayland, ChoosePreferredWindowSystem(/*x11=*/true, /*wayland=*/true, | |
| GetWindowSystemFromEnvironment())); | |
| } | |
| // A preference for a backend that is not compiled in falls back to one that is. | |
| TEST(WindowSystemTest, PreferenceNotCompiled) | |
| { | |
| EXPECT_EQ(WindowSystem::X11, ChoosePreferredWindowSystem( | |
| /*x11=*/true, /*wayland=*/false, | |
| /*preferred=*/WindowSystem::Wayland)); | |
| EXPECT_EQ(WindowSystem::Wayland, ChoosePreferredWindowSystem( | |
| /*x11=*/false, /*wayland=*/true, | |
| /*preferred=*/WindowSystem::X11)); | |
| EXPECT_EQ(WindowSystem::X11, ChoosePreferredWindowSystem( | |
| /*x11=*/true, /*wayland=*/true, | |
| /*preferred=*/WindowSystem::Unspecified)); | |
| } | |
| } // namespace | |
| } // namespace angle |