#include <memory>
#include "base/memory/raw_ptr.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/test/test_layers.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/view.h"
#include "ui/views/view_constants_aura.h"
#include "ui/views/widget/widget.h"
namespace views {
namespace {
void SetWindowAndLayerName(aura::Window* window, const std::string& name) {
window->SetName(name);
window->layer()->SetName(name);
}
std::string ChildWindowNamesAsString(const aura::Window& parent) {
std::string names;
for (const aura::Window* child : parent.children()) {
if (!names.empty()) {
names += " ";
}
names += child->GetName();
}
return names;
}
class WindowReordererTest : public ViewsTestBase {
protected:
std::unique_ptr<Widget> CreateControlWidget(aura::Window* parent) {
Widget::InitParams params =
CreateParamsForTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET,
Widget::InitParams::TYPE_CONTROL);
params.parent = parent;
return CreateTestWidget(std::move(params));
}
};
TEST_F(WindowReordererTest, Basic) {
std::unique_ptr<Widget> parent = CreateControlWidget(root_window());
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
View* contents_view = parent->SetContentsView(std::make_unique<View>());
auto* v = contents_view->AddChildView(std::make_unique<View>());
v->SetPaintToLayer();
v->layer()->SetName("v");
std::unique_ptr<Widget> w1 = CreateControlWidget(parent_window);
SetWindowAndLayerName(w1->GetNativeView(), "w1");
w1->Show();
std::unique_ptr<Widget> w2 = CreateControlWidget(parent_window);
SetWindowAndLayerName(w2->GetNativeView(), "w2");
w2->Show();
EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v w1 w2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
auto* host_view2 = contents_view->AddChildView(std::make_unique<View>());
w2->GetNativeView()->SetProperty(kHostViewKey, host_view2);
EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v w2 w1",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
auto* host_view1 = contents_view->AddChildViewAt(std::make_unique<View>(), 0);
w1->GetNativeView()->SetProperty(kHostViewKey, host_view1);
EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w1 v w2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
contents_view->ReorderChildView(host_view1, contents_view->children().size());
EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v w2 w1",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
contents_view->ReorderChildView(host_view2, contents_view->children().size());
EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v w1 w2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
contents_view->ReorderChildView(v, contents_view->children().size());
EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w1 w2 v",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
contents_view->ReorderChildView(host_view2, contents_view->children().size());
EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w1 v w2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
}
TEST_F(WindowReordererTest, Association) {
std::unique_ptr<Widget> parent = CreateControlWidget(root_window());
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
View* contents_view = parent->SetContentsView(std::make_unique<View>());
aura::Window* w1 =
aura::test::CreateTestWindow({.parent = parent->GetNativeWindow(),
.bounds = {100, 100},
.window_id = 0})
.release();
SetWindowAndLayerName(w1, "w1");
aura::Window* w2 =
aura::test::CreateTestWindow({.bounds = {100, 100}, .window_id = 0})
.release();
SetWindowAndLayerName(w2, "w2");
auto* host_view2 = contents_view->AddChildView(std::make_unique<View>());
w2->SetProperty(views::kHostViewKey, host_view2);
EXPECT_EQ("w1", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w1", ui::test::ChildLayerNamesAsString(*parent_window->layer()));
parent_window->AddChild(w2);
EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w2 w1",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
auto* host_view1 = contents_view->AddChildViewAt(std::make_unique<View>(), 0);
EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w2 w1",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
w1->SetProperty(views::kHostViewKey, host_view1);
EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w1 w2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
contents_view->RemoveChildView(host_view2);
contents_view->AddChildViewAt(host_view2, 0);
EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("w2 w1",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
}
TEST_F(WindowReordererTest, HostViewParentHasLayer) {
std::unique_ptr<Widget> parent = CreateControlWidget(root_window());
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
View* contents_view = parent->SetContentsView(std::make_unique<View>());
View* v1 = contents_view->AddChildView(std::make_unique<View>());
View* v11 = v1->AddChildView(std::make_unique<View>());
v11->SetPaintToLayer();
v11->layer()->SetName("v11");
std::unique_ptr<Widget> w = CreateControlWidget(parent_window);
SetWindowAndLayerName(w->GetNativeView(), "w");
w->Show();
View* v12 = v1->AddChildView(std::make_unique<View>());
w->GetNativeView()->SetProperty(kHostViewKey, v12);
View* v13 = v1->AddChildView(std::make_unique<View>());
v13->SetPaintToLayer();
v13->layer()->SetName("v13");
View* v2 = contents_view->AddChildView(std::make_unique<View>());
v2->SetPaintToLayer();
v2->layer()->SetName("v2");
EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v11 w v13 v2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
v1->SetPaintToLayer();
v1->layer()->SetName("v1");
EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v1 w v2",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
v2->AddChildView(v1->RemoveChildViewT(v12));
EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window));
EXPECT_EQ("v1 v2 w",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
}
TEST_F(WindowReordererTest, ViewWithLayerBeneath) {
std::unique_ptr<Widget> parent = CreateControlWidget(root_window());
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
View* contents_view = parent->SetContentsView(std::make_unique<View>());
View* view_with_layer_beneath =
contents_view->AddChildView(std::make_unique<View>());
ui::Layer layer_beneath;
view_with_layer_beneath->AddLayerToRegion(&layer_beneath,
LayerRegion::kBelow);
ASSERT_NE(nullptr, view_with_layer_beneath->layer());
view_with_layer_beneath->layer()->SetName("view");
layer_beneath.SetName("beneath");
EXPECT_EQ("beneath view",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
std::unique_ptr<Widget> child_widget = CreateControlWidget(parent_window);
SetWindowAndLayerName(child_widget->GetNativeView(), "child_widget");
child_widget->Show();
View* host_view = contents_view->AddChildView(std::make_unique<View>());
child_widget->GetNativeView()->SetProperty(kHostViewKey, host_view);
EXPECT_EQ("beneath view child_widget",
ui::test::ChildLayerNamesAsString(*parent_window->layer()));
}
}
}