blob: bc2fd61515aa57804129e4ab6eec68c69251accf [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <wayland-server-protocol-core.h>
#include "base/memory/raw_ptr.h"
#include "components/exo/display.h"
#include "components/exo/wayland/test/client_util.h"
#include "components/exo/wayland/test/server_util.h"
#include "components/exo/wayland/test/wayland_server_test.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace exo::wayland {
namespace {
class ClientData : public test::TestClient::CustomData {
public:
std::unique_ptr<wl_surface> surface;
std::unique_ptr<wl_surface> surface2;
};
class WaylandAuraShellServerTest : public test::WaylandServerTest {
public:
WaylandAuraShellServerTest() = default;
WaylandAuraShellServerTest(const WaylandAuraShellServerTest&) = delete;
WaylandAuraShellServerTest& operator=(const WaylandAuraShellServerTest&) =
delete;
~WaylandAuraShellServerTest() override = default;
// test::WaylandServerTest:
void SetUp() override {
WaylandServerTest::SetUp();
display_ = server_->GetDisplay();
}
void TearDown() override { WaylandServerTest::TearDown(); }
void OnAuraShellActivated(zaura_shell*,
wl_surface* gained_active,
wl_surface* lost_active) {
gained_active_ = gained_active;
lost_active_ = lost_active;
activated_call_count_++;
}
void SetupClientSurface() {
PostToClientAndWait([&](test::TestClient* client) {
zaura_shell_add_listener(client->aura_shell(), &kAuraShellListener, this);
auto data = std::make_unique<ClientData>();
data->surface.reset(wl_compositor_create_surface(client->compositor()));
surface_key_ = test::client_util::GetResourceKey(data->surface.get());
client->set_data(std::move(data));
});
}
void SetupMultipleClientSurfaces() {
PostToClientAndWait([&](test::TestClient* client) {
zaura_shell_add_listener(client->aura_shell(), &kAuraShellListener, this);
auto data = std::make_unique<ClientData>();
data->surface.reset(wl_compositor_create_surface(client->compositor()));
data->surface2.reset(wl_compositor_create_surface(client->compositor()));
surface_key_ = test::client_util::GetResourceKey(data->surface.get());
surface_key2_ = test::client_util::GetResourceKey(data->surface2.get());
client->set_data(std::move(data));
});
}
Surface* GetClientSurface(test::ResourceKey surface_key) {
return test::server_util::GetUserDataForResource<Surface>(server_.get(),
surface_key);
}
const zaura_shell_listener kAuraShellListener = {
[](void* data, struct zaura_shell* zaura_shell, uint32_t layout_mode) {},
[](void* data, struct zaura_shell* zaura_shell, uint32_t id) {},
[](void* data,
struct zaura_shell* zaura_shell,
struct wl_array* desk_names) {},
[](void* data,
struct zaura_shell* zaura_shell,
int32_t active_desk_index) {},
[](void* data,
struct zaura_shell* zaura_shell,
struct wl_surface* gained_active,
struct wl_surface* lost_active) {
static_cast<WaylandAuraShellServerTest*>(data)->OnAuraShellActivated(
zaura_shell, gained_active, lost_active);
}};
raw_ptr<Display, ExperimentalAsh> display_;
raw_ptr<wl_surface, ExperimentalAsh> gained_active_ = nullptr;
raw_ptr<wl_surface, ExperimentalAsh> lost_active_ = nullptr;
int32_t activated_call_count_ = 0;
test::ResourceKey surface_key_;
test::ResourceKey surface_key2_;
};
// Home screen -> any window
TEST_F(WaylandAuraShellServerTest, HasFocusedClientChangedSendActivated) {
SetupClientSurface();
Surface* surface = GetClientSurface(surface_key_);
ASSERT_TRUE(surface);
display_->seat()->OnWindowFocused(surface->window(), nullptr);
// Wait until all wayland events are sent.
PostToClientAndWait([]() {});
EXPECT_TRUE(gained_active_ != nullptr);
EXPECT_TRUE(lost_active_ == nullptr);
EXPECT_EQ(1, activated_call_count_);
}
// Exo client window -> Same exo client another window
TEST_F(WaylandAuraShellServerTest, FocusedClientChangedSendActivated) {
SetupMultipleClientSurfaces();
Surface* surface = GetClientSurface(surface_key_);
ASSERT_TRUE(surface);
display_->seat()->OnWindowFocused(surface->window(), nullptr);
// Reset previous gained and lost active info.
gained_active_ = nullptr;
lost_active_ = nullptr;
Surface* surface2 = GetClientSurface(surface_key2_);
ASSERT_TRUE(surface2);
display_->seat()->OnWindowFocused(surface2->window(), surface->window());
// Wait until all wayland events are sent.
PostToClientAndWait([]() {});
EXPECT_TRUE(gained_active_ != nullptr);
EXPECT_TRUE(lost_active_ != nullptr);
EXPECT_EQ(2, activated_call_count_);
}
// Exo client window -> Chrome window
TEST_F(WaylandAuraShellServerTest, FocusedClientChangedToNonExoSendActivated) {
SetupMultipleClientSurfaces();
Surface* surface = GetClientSurface(surface_key_);
ASSERT_TRUE(surface);
display_->seat()->OnWindowFocused(surface->window(), nullptr);
// Reset previous gained and lost active info.
gained_active_ = nullptr;
lost_active_ = nullptr;
Surface* surface2 = GetClientSurface(surface_key2_);
ASSERT_TRUE(surface2);
// Chrome surface doesn't have wayland resource.
SetSurfaceResource(surface2, nullptr);
display_->seat()->OnWindowFocused(surface2->window(), surface->window());
// Wait until all wayland events are sent.
PostToClientAndWait([]() {});
EXPECT_TRUE(gained_active_ == nullptr);
EXPECT_TRUE(lost_active_ != nullptr);
EXPECT_EQ(2, activated_call_count_);
}
// Chrome window -> Chrome window
TEST_F(WaylandAuraShellServerTest,
NonExoFocusedClientChangedNotSendingActivated) {
SetupMultipleClientSurfaces();
Surface* surface = GetClientSurface(surface_key_);
ASSERT_TRUE(surface);
// Chrome surface doesn't have wayland resource.
SetSurfaceResource(surface, nullptr);
display_->seat()->OnWindowFocused(surface->window(), nullptr);
// Reset previous gained and lost active info.
gained_active_ = nullptr;
lost_active_ = nullptr;
Surface* surface2 = GetClientSurface(surface_key2_);
ASSERT_TRUE(surface2);
// Chrome surface doesn't have wayland resource.
SetSurfaceResource(surface2, nullptr);
display_->seat()->OnWindowFocused(surface2->window(), surface->window());
// Wait until all wayland events are sent.
PostToClientAndWait([]() {});
EXPECT_EQ(nullptr, gained_active_.get());
EXPECT_EQ(nullptr, lost_active_.get());
EXPECT_EQ(1, activated_call_count_);
}
} // namespace
} // namespace exo::wayland