window_finder_unittest.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/public/cpp/window_finder.h"
  5. #include "ash/shell.h"
  6. #include "ash/test/ash_test_base.h"
  7. #include "ash/wm/container_finder.h"
  8. #include "ash/wm/overview/overview_controller.h"
  9. #include "ash/wm/overview/overview_grid.h"
  10. #include "ash/wm/overview/overview_item.h"
  11. #include "ash/wm/overview/overview_session.h"
  12. #include "ash/wm/window_state.h"
  13. #include "ui/aura/test/test_window_delegate.h"
  14. #include "ui/aura/window_observer.h"
  15. #include "ui/aura/window_targeter.h"
  16. #include "ui/gfx/geometry/insets.h"
  17. namespace ash {
  18. using WindowFinderTest = AshTestBase;
  19. TEST_F(WindowFinderTest, RealTopmostCanBeNullptr) {
  20. std::unique_ptr<aura::Window> window1 =
  21. CreateTestWindow(gfx::Rect(0, 0, 100, 100));
  22. std::set<aura::Window*> ignore;
  23. EXPECT_EQ(window1.get(), GetTopmostWindowAtPoint(gfx::Point(10, 10), ignore));
  24. }
  25. TEST_F(WindowFinderTest, ToplevelCanBeNotDrawn) {
  26. aura::test::TestWindowDelegate delegate;
  27. auto window = std::make_unique<aura::Window>(&delegate,
  28. aura::client::WINDOW_TYPE_POPUP);
  29. window->Init(ui::LAYER_NOT_DRAWN);
  30. gfx::Rect bounds(0, 0, 100, 100);
  31. window->SetBounds(bounds);
  32. auto* parent = GetDefaultParentForWindow(window.get(), bounds);
  33. parent->AddChild(window.get());
  34. window->Show();
  35. std::set<aura::Window*> ignore;
  36. EXPECT_EQ(window.get(), GetTopmostWindowAtPoint(gfx::Point(10, 10), ignore));
  37. }
  38. TEST_F(WindowFinderTest, MultipleDisplays) {
  39. UpdateDisplay("300x200,400x300");
  40. std::unique_ptr<aura::Window> window1 =
  41. CreateTestWindow(gfx::Rect(0, 0, 100, 100));
  42. std::unique_ptr<aura::Window> window2 =
  43. CreateTestWindow(gfx::Rect(300, 0, 100, 100));
  44. ASSERT_NE(window1->GetRootWindow(), window2->GetRootWindow());
  45. std::set<aura::Window*> ignore;
  46. EXPECT_EQ(window1.get(), GetTopmostWindowAtPoint(gfx::Point(10, 10), ignore));
  47. EXPECT_EQ(window2.get(),
  48. GetTopmostWindowAtPoint(gfx::Point(310, 10), ignore));
  49. EXPECT_EQ(nullptr, GetTopmostWindowAtPoint(gfx::Point(10, 210), ignore));
  50. }
  51. TEST_F(WindowFinderTest, WindowTargeterWithHitTestRects) {
  52. std::unique_ptr<aura::Window> window1 =
  53. CreateTestWindow(gfx::Rect(0, 0, 100, 100));
  54. std::unique_ptr<aura::Window> window2 =
  55. CreateTestWindow(gfx::Rect(0, 0, 100, 100));
  56. std::set<aura::Window*> ignore;
  57. EXPECT_EQ(window2.get(), GetTopmostWindowAtPoint(gfx::Point(10, 10), ignore));
  58. auto targeter = std::make_unique<aura::WindowTargeter>();
  59. targeter->SetInsets(gfx::Insets::TLBR(0, 50, 0, 0));
  60. window2->SetEventTargeter(std::move(targeter));
  61. EXPECT_EQ(window1.get(), GetTopmostWindowAtPoint(gfx::Point(10, 10), ignore));
  62. EXPECT_EQ(window2.get(), GetTopmostWindowAtPoint(gfx::Point(60, 10), ignore));
  63. }
  64. // Tests that when overview is active, GetTopmostWindowAtPoint() will return
  65. // the window in overview that contains the specified screen point, even though
  66. // it might be a minimized window.
  67. TEST_F(WindowFinderTest, TopmostWindowWithOverviewActive) {
  68. UpdateDisplay("500x400");
  69. std::unique_ptr<aura::Window> window1 =
  70. CreateTestWindow(gfx::Rect(0, 0, 100, 100));
  71. std::unique_ptr<aura::Window> window2 =
  72. CreateTestWindow(gfx::Rect(0, 0, 100, 100));
  73. OverviewController* overview_controller = Shell::Get()->overview_controller();
  74. EnterOverview();
  75. EXPECT_TRUE(overview_controller->InOverviewSession());
  76. // Get |window1| and |window2|'s transformed bounds in overview.
  77. OverviewGrid* grid =
  78. overview_controller->overview_session()->GetGridWithRootWindow(
  79. window1->GetRootWindow());
  80. gfx::Rect bounds1 = gfx::ToEnclosedRect(
  81. grid->GetOverviewItemContaining(window1.get())->target_bounds());
  82. gfx::Rect bounds2 = gfx::ToEnclosedRect(
  83. grid->GetOverviewItemContaining(window2.get())->target_bounds());
  84. std::set<aura::Window*> ignore;
  85. EXPECT_EQ(window1.get(),
  86. GetTopmostWindowAtPoint(bounds1.CenterPoint(), ignore));
  87. EXPECT_EQ(window2.get(),
  88. GetTopmostWindowAtPoint(bounds2.CenterPoint(), ignore));
  89. WindowState::Get(window1.get())->Minimize();
  90. EXPECT_EQ(window1.get(),
  91. GetTopmostWindowAtPoint(bounds1.CenterPoint(), ignore));
  92. }
  93. namespace {
  94. // Defines an observer that tries to get the top-most window while the window it
  95. // observes is being destroyed. This is to verify that the destroying window
  96. // cannot be found and returned as the top-most one.
  97. class WindowDestroyingObserver : public aura::WindowObserver {
  98. public:
  99. WindowDestroyingObserver(const gfx::Point& screen_point, aura::Window* window)
  100. : screen_point_(screen_point), window_being_observed_(window) {
  101. window_being_observed_->AddObserver(this);
  102. }
  103. aura::Window* top_most_window_while_destroying() const {
  104. return top_most_window_while_destroying_;
  105. }
  106. ~WindowDestroyingObserver() override { StopObserving(); }
  107. // aura::WindowObserver:
  108. void OnWindowDestroying(aura::Window* window) override {
  109. StopObserving();
  110. top_most_window_while_destroying_ =
  111. GetTopmostWindowAtPoint(screen_point_, /*ignore=*/{});
  112. }
  113. private:
  114. void StopObserving() {
  115. if (window_being_observed_) {
  116. window_being_observed_->RemoveObserver(this);
  117. window_being_observed_ = nullptr;
  118. }
  119. }
  120. // The point in screen coordinates at which we'll get the top-most window when
  121. // `window_being_observed_` is destroying.
  122. const gfx::Point screen_point_;
  123. aura::Window* window_being_observed_;
  124. // This is the window we find as the top-most window while
  125. // `window_being_observed_` is being destroyed.
  126. aura::Window* top_most_window_while_destroying_ = nullptr;
  127. };
  128. } // namespace
  129. TEST_F(WindowFinderTest, WindowBeingDestroyedCannotBeReturned) {
  130. std::unique_ptr<aura::Window> window =
  131. CreateTestWindow(gfx::Rect(0, 0, 100, 100));
  132. auto* window_ptr = window.get();
  133. WindowDestroyingObserver observer{window->GetBoundsInScreen().CenterPoint(),
  134. window_ptr};
  135. window.reset();
  136. EXPECT_NE(window_ptr, observer.top_most_window_while_destroying());
  137. }
  138. } // namespace ash