Index: components/mus/ws/window_manager_client_apptest.cc |
diff --git a/components/mus/ws/window_manager_client_apptest.cc b/components/mus/ws/window_manager_client_apptest.cc |
index 5a2cd989d9c6b72ca18dd2a390feca3050312ce1..2587c4b0ef5097eb55ca7081c7ea044ec2a626d9 100644 |
--- a/components/mus/ws/window_manager_client_apptest.cc |
+++ b/components/mus/ws/window_manager_client_apptest.cc |
@@ -23,6 +23,12 @@ namespace ws { |
namespace { |
+int ValidIndexOf(const Window::Children& windows, Window* window) { |
+ Window::Children::const_iterator it = |
+ std::find(windows.begin(), windows.end(), window); |
+ return (it != windows.end()) ? (it - windows.begin()) : -1; |
+} |
+ |
class BoundsChangeObserver : public WindowObserver { |
public: |
explicit BoundsChangeObserver(Window* window) : window_(window) { |
@@ -201,6 +207,13 @@ class WindowServerTest : public WindowServerTestBase { |
public: |
WindowServerTest() {} |
+ Window* NewVisibleWindow(Window* parent, WindowTreeConnection* connection) { |
+ Window* window = connection->NewWindow(); |
+ window->SetVisible(true); |
+ parent->AddChild(window); |
+ return window; |
+ } |
+ |
// Embeds another version of the test app @ window. This runs a run loop until |
// a response is received, or a timeout. On success the new WindowServer is |
// returned. |
@@ -623,6 +636,13 @@ class FocusChangeObserver : public WindowObserver { |
MOJO_DISALLOW_COPY_AND_ASSIGN(FocusChangeObserver); |
}; |
+bool WaitForWindowToHaveFocus(Window* window) { |
+ if (window->HasFocus()) |
+ return true; |
+ FocusChangeObserver observer(window); |
+ return WindowServerTestBase::DoRunLoopWithTimeout(); |
+} |
+ |
} // namespace |
TEST_F(WindowServerTest, Focus) { |
@@ -657,8 +677,7 @@ TEST_F(WindowServerTest, Focus) { |
} |
{ |
// Add an observer on the Window that loses focus, and make sure the |
- // observer |
- // sees the right values. |
+ // observer sees the right values. |
FocusChangeObserver observer(window11); |
embedded->GetRoot()->SetFocus(); |
ASSERT_TRUE(DoRunLoopWithTimeout()); |
@@ -669,6 +688,64 @@ TEST_F(WindowServerTest, Focus) { |
} |
} |
+TEST_F(WindowServerTest, Activation) { |
+ Window* parent = |
+ NewVisibleWindow(window_manager()->GetRoot(), window_manager()); |
+ Window* child1 = NewVisibleWindow(parent, window_manager()); |
+ Window* child2 = NewVisibleWindow(parent, window_manager()); |
+ Window* child3 = NewVisibleWindow(parent, window_manager()); |
+ |
+ child1->AddTransientWindow(child3); |
+ |
+ WindowTreeConnection* embedded1 = Embed(child1).connection; |
+ ASSERT_NE(nullptr, embedded1); |
+ WindowTreeConnection* embedded2 = Embed(child2).connection; |
+ ASSERT_NE(nullptr, embedded2); |
+ |
+ Window* child11 = NewVisibleWindow(embedded1->GetRoot(), embedded1); |
+ Window* child21 = NewVisibleWindow(embedded2->GetRoot(), embedded2); |
+ |
+ WaitForTreeSizeToMatch(parent, 6); |
+ |
+ // Allow the child windows to be activated. |
+ host()->AddActivationParent(parent->id()); |
+ |
+ // |child2| and |child3| are stacked about |child1|. |
+ EXPECT_GT(ValidIndexOf(parent->children(), child2), |
+ ValidIndexOf(parent->children(), child1)); |
+ EXPECT_GT(ValidIndexOf(parent->children(), child3), |
+ ValidIndexOf(parent->children(), child1)); |
+ |
+ // Set focus on |child11|. This should activate |child1|, and raise it over |
+ // |child2|. But |child3| should still be above |child1| because of |
+ // transiency. |
+ child11->SetFocus(); |
+ ASSERT_TRUE(WaitForWindowToHaveFocus(child11)); |
+ ASSERT_TRUE( |
+ WaitForWindowToHaveFocus(window_manager()->GetWindowById(child11->id()))); |
+ EXPECT_EQ(child11->id(), window_manager()->GetFocusedWindow()->id()); |
+ EXPECT_EQ(child11->id(), embedded1->GetFocusedWindow()->id()); |
+ EXPECT_EQ(nullptr, embedded2->GetFocusedWindow()); |
+ EXPECT_GT(ValidIndexOf(parent->children(), child1), |
+ ValidIndexOf(parent->children(), child2)); |
+ EXPECT_GT(ValidIndexOf(parent->children(), child3), |
+ ValidIndexOf(parent->children(), child1)); |
+ |
+ // Set focus on |child21|. This should activate |child2|, and raise it over |
+ // |child1|. |
+ child21->SetFocus(); |
+ ASSERT_TRUE(WaitForWindowToHaveFocus(child21)); |
+ ASSERT_TRUE( |
+ WaitForWindowToHaveFocus(window_manager()->GetWindowById(child21->id()))); |
+ EXPECT_EQ(child21->id(), window_manager()->GetFocusedWindow()->id()); |
+ EXPECT_EQ(child21->id(), embedded2->GetFocusedWindow()->id()); |
+ EXPECT_EQ(nullptr, embedded1->GetFocusedWindow()); |
+ EXPECT_GT(ValidIndexOf(parent->children(), child2), |
+ ValidIndexOf(parent->children(), child1)); |
+ EXPECT_GT(ValidIndexOf(parent->children(), child3), |
+ ValidIndexOf(parent->children(), child1)); |
+} |
+ |
namespace { |
class DestroyedChangedObserver : public WindowObserver { |