Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Unified Diff: ash/wm/solo_window_tracker_unittest.cc

Issue 121773003: Makes Window::Init take a WindowLayerType instead of LayerType. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge to master Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ash/wm/drag_window_resizer_unittest.cc ('k') | ash/wm/stacking_controller_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/wm/solo_window_tracker_unittest.cc
diff --git a/ash/wm/solo_window_tracker_unittest.cc b/ash/wm/solo_window_tracker_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d134c4089ab6d129d6ae0a96553458c7d8c0ea21
--- /dev/null
+++ b/ash/wm/solo_window_tracker_unittest.cc
@@ -0,0 +1,429 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/wm/solo_window_tracker.h"
+
+#include "ash/ash_constants.h"
+#include "ash/ash_switches.h"
+#include "ash/root_window_controller.h"
+#include "ash/screen_ash.h"
+#include "ash/shell.h"
+#include "ash/shell_window_ids.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/wm/window_resizer.h"
+#include "ash/wm/window_state.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/test/event_generator.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_observer.h"
+#include "ui/base/hit_test.h"
+#include "ui/gfx/screen.h"
+
+namespace ash {
+
+namespace {
+
+class WindowRepaintChecker : public aura::WindowObserver {
+ public:
+ explicit WindowRepaintChecker(aura::Window* window)
+ : window_(window),
+ is_paint_scheduled_(false) {
+ window_->AddObserver(this);
+ }
+
+ virtual ~WindowRepaintChecker() {
+ if (window_)
+ window_->RemoveObserver(this);
+ }
+
+ bool IsPaintScheduledAndReset() {
+ bool result = is_paint_scheduled_;
+ is_paint_scheduled_ = false;
+ return result;
+ }
+
+ private:
+ // aura::WindowObserver overrides:
+ virtual void OnWindowPaintScheduled(aura::Window* window,
+ const gfx::Rect& region) OVERRIDE {
+ is_paint_scheduled_ = true;
+ }
+ virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
+ DCHECK_EQ(window_, window);
+ window_ = NULL;
+ }
+
+ aura::Window* window_;
+ bool is_paint_scheduled_;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowRepaintChecker);
+};
+
+} // namespace
+
+class SoloWindowTrackerTest : public test::AshTestBase {
+ public:
+ SoloWindowTrackerTest() {
+ }
+ virtual ~SoloWindowTrackerTest() {
+ }
+
+ // Helpers methods to create test windows in the primary root window.
+ aura::Window* CreateWindowInPrimary() {
+ aura::Window* window = new aura::Window(NULL);
+ window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
+ window->Init(aura::WINDOW_LAYER_TEXTURED);
+ window->SetBounds(gfx::Rect(100, 100));
+ ParentWindowInPrimaryRootWindow(window);
+ return window;
+ }
+ aura::Window* CreateAlwaysOnTopWindowInPrimary() {
+ aura::Window* window = new aura::Window(NULL);
+ window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
+ window->Init(aura::WINDOW_LAYER_TEXTURED);
+ window->SetBounds(gfx::Rect(100, 100));
+ window->SetProperty(aura::client::kAlwaysOnTopKey, true);
+ ParentWindowInPrimaryRootWindow(window);
+ return window;
+ }
+ aura::Window* CreatePanelWindowInPrimary() {
+ aura::Window* window = new aura::Window(NULL);
+ window->SetType(ui::wm::WINDOW_TYPE_PANEL);
+ window->Init(aura::WINDOW_LAYER_TEXTURED);
+ window->SetBounds(gfx::Rect(100, 100));
+ ParentWindowInPrimaryRootWindow(window);
+ return window;
+ }
+
+ // Drag |window| to the dock.
+ void DockWindow(aura::Window* window) {
+ // Because the tests use windows without delegates,
+ // aura::test::EventGenerator cannot be used.
+ gfx::Point drag_to =
+ ash::ScreenAsh::GetDisplayBoundsInParent(window).top_right();
+ scoped_ptr<WindowResizer> resizer(CreateWindowResizer(
+ window,
+ window->bounds().origin(),
+ HTCAPTION,
+ aura::client::WINDOW_MOVE_SOURCE_MOUSE));
+ resizer->Drag(drag_to, 0);
+ resizer->CompleteDrag();
+ EXPECT_EQ(internal::kShellWindowId_DockedContainer,
+ window->parent()->id());
+ }
+
+ // Drag |window| out of the dock.
+ void UndockWindow(aura::Window* window) {
+ gfx::Point drag_to =
+ ash::ScreenAsh::GetDisplayWorkAreaBoundsInParent(window).top_right() -
+ gfx::Vector2d(10, 0);
+ scoped_ptr<WindowResizer> resizer(CreateWindowResizer(
+ window,
+ window->bounds().origin(),
+ HTCAPTION,
+ aura::client::WINDOW_MOVE_SOURCE_MOUSE));
+ resizer->Drag(drag_to, 0);
+ resizer->CompleteDrag();
+ EXPECT_NE(internal::kShellWindowId_DockedContainer,
+ window->parent()->id());
+ }
+
+ // Returns the primary display.
+ gfx::Display GetPrimaryDisplay() {
+ return ash::Shell::GetInstance()->GetScreen()->GetPrimaryDisplay();
+ }
+
+ // Returns the secondary display.
+ gfx::Display GetSecondaryDisplay() {
+ return ScreenAsh::GetSecondaryDisplay();
+ }
+
+ // Returns the window which uses the solo header, if any, on the primary
+ // display.
+ aura::Window* GetWindowWithSoloHeaderInPrimary() {
+ return GetWindowWithSoloHeader(Shell::GetPrimaryRootWindow());
+ }
+
+ // Returns the window which uses the solo header, if any, in |root|.
+ aura::Window* GetWindowWithSoloHeader(aura::Window* root) {
+ SoloWindowTracker* solo_window_tracker =
+ internal::GetRootWindowController(root)->solo_window_tracker();
+ return solo_window_tracker ?
+ solo_window_tracker->GetWindowWithSoloHeader() : NULL;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SoloWindowTrackerTest);
+};
+
+TEST_F(SoloWindowTrackerTest, Basic) {
+ scoped_ptr<aura::Window> w1(CreateWindowInPrimary());
+ w1->Show();
+
+ // We only have one window, so it should use a solo header.
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Create a second window.
+ scoped_ptr<aura::Window> w2(CreateWindowInPrimary());
+ w2->Show();
+
+ // Now there are two windows, so we should not use solo headers.
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+
+ // Hide one window. Solo should be enabled.
+ w2->Hide();
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Show that window. Solo should be disabled.
+ w2->Show();
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+
+ // Minimize the first window. Solo should be enabled.
+ wm::GetWindowState(w1.get())->Minimize();
+ EXPECT_EQ(w2.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Close the minimized window.
+ w1.reset();
+ EXPECT_EQ(w2.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Open an always-on-top window (which lives in a different container).
+ scoped_ptr<aura::Window> w3(CreateAlwaysOnTopWindowInPrimary());
+ w3->Show();
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+
+ // Close the always-on-top window.
+ w3.reset();
+ EXPECT_EQ(w2.get(), GetWindowWithSoloHeaderInPrimary());
+}
+
+// Test that docked windows never use the solo header and that the presence of a
+// docked window prevents all other windows from the using the solo window
+// header.
+TEST_F(SoloWindowTrackerTest, DockedWindow) {
+ if (!switches::UseDockedWindows() || !SupportsHostWindowResize())
+ return;
+
+ scoped_ptr<aura::Window> w1(CreateWindowInPrimary());
+ w1->Show();
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+
+ DockWindow(w1.get());
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+
+ UndockWindow(w1.get());
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+
+ scoped_ptr<aura::Window> w2(CreateWindowInPrimary());
+ w2->Show();
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+
+ DockWindow(w2.get());
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+
+ wm::GetWindowState(w2.get())->Minimize();
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+}
+
+// Panels should not "count" for computing solo window headers, and the panel
+// itself should never use the solo header.
+TEST_F(SoloWindowTrackerTest, Panel) {
+ scoped_ptr<aura::Window> w1(CreateWindowInPrimary());
+ w1->Show();
+
+ // We only have one window, so it should use a solo header.
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Create a panel window.
+ scoped_ptr<aura::Window> w2(CreatePanelWindowInPrimary());
+ w2->Show();
+
+ // Despite two windows, the first window should still be considered "solo"
+ // because panels aren't included in the computation.
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Even after closing the first window, the panel is still not considered
+ // solo.
+ w1.reset();
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+}
+
+// Modal dialogs should not use solo headers.
+TEST_F(SoloWindowTrackerTest, Modal) {
+ scoped_ptr<aura::Window> w1(CreateWindowInPrimary());
+ w1->Show();
+
+ // We only have one window, so it should use a solo header.
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Create a fake modal window.
+ scoped_ptr<aura::Window> w2(CreateWindowInPrimary());
+ w2->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
+ w2->Show();
+
+ // Despite two windows, the first window should still be considered "solo"
+ // because modal windows aren't included in the computation.
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+}
+
+// Constrained windows should not use solo headers.
+TEST_F(SoloWindowTrackerTest, Constrained) {
+ scoped_ptr<aura::Window> w1(CreateWindowInPrimary());
+ w1->Show();
+
+ // We only have one window, so it should use a solo header.
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Create a fake constrained window.
+ scoped_ptr<aura::Window> w2(CreateWindowInPrimary());
+ w2->SetProperty(aura::client::kConstrainedWindowKey, true);
+ w2->Show();
+
+ // Despite two windows, the first window should still be considered "solo"
+ // because constrained windows aren't included in the computation.
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+}
+
+// Non-drawing windows should not affect the solo computation.
+TEST_F(SoloWindowTrackerTest, NotDrawn) {
+ aura::Window* w = CreateWindowInPrimary();
+ w->Show();
+
+ // We only have one window, so it should use a solo header.
+ EXPECT_EQ(w, GetWindowWithSoloHeaderInPrimary());
+
+ // Create non-drawing window similar to DragDropTracker.
+ aura::Window* not_drawn = new aura::Window(NULL);
+ not_drawn->SetType(ui::wm::WINDOW_TYPE_NORMAL);
+ not_drawn->Init(aura::WINDOW_LAYER_NOT_DRAWN);
+ ParentWindowInPrimaryRootWindow(not_drawn);
+ not_drawn->Show();
+
+ // Despite two windows, the first window should still be considered "solo"
+ // because non-drawing windows aren't included in the computation.
+ EXPECT_EQ(w, GetWindowWithSoloHeaderInPrimary());
+}
+
+TEST_F(SoloWindowTrackerTest, MultiDisplay) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ UpdateDisplay("1000x600,600x400");
+
+ scoped_ptr<aura::Window> w1(CreateWindowInPrimary());
+ w1->SetBoundsInScreen(gfx::Rect(0, 0, 100, 100), GetPrimaryDisplay());
+ w1->Show();
+ WindowRepaintChecker checker1(w1.get());
+ scoped_ptr<aura::Window> w2(CreateWindowInPrimary());
+ w2->SetBoundsInScreen(gfx::Rect(0, 0, 100, 100), GetPrimaryDisplay());
+ w2->Show();
+ WindowRepaintChecker checker2(w2.get());
+
+ // Now there are two windows in the same display, so we should not use solo
+ // headers.
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+ EXPECT_TRUE(checker1.IsPaintScheduledAndReset());
+
+ // Moves the second window to the secondary display. Both w1/w2 should be
+ // solo.
+ w2->SetBoundsInScreen(gfx::Rect(1200, 0, 100, 100),
+ ScreenAsh::GetSecondaryDisplay());
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+ EXPECT_EQ(w2.get(), GetWindowWithSoloHeader(w2->GetRootWindow()));
+ EXPECT_TRUE(checker1.IsPaintScheduledAndReset());
+ EXPECT_TRUE(checker2.IsPaintScheduledAndReset());
+
+ // Open two more windows in the primary display.
+ scoped_ptr<aura::Window> w3(CreateWindowInPrimary());
+ w3->SetBoundsInScreen(gfx::Rect(0, 0, 100, 100), GetPrimaryDisplay());
+ w3->Show();
+ scoped_ptr<aura::Window> w4(CreateWindowInPrimary());
+ w4->SetBoundsInScreen(gfx::Rect(0, 0, 100, 100), GetPrimaryDisplay());
+ w4->Show();
+
+ // Because the primary display has three windows w1, w3, and w4, they
+ // shouldn't be solo. w2 should be solo.
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+ EXPECT_EQ(w2.get(), GetWindowWithSoloHeader(w2->GetRootWindow()));
+ EXPECT_TRUE(checker1.IsPaintScheduledAndReset());
+
+ // Move w4 to the secondary display. Now w2 shouldn't be solo anymore.
+ w4->SetBoundsInScreen(gfx::Rect(1200, 0, 100, 100), GetSecondaryDisplay());
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+ EXPECT_EQ(NULL, GetWindowWithSoloHeader(w2->GetRootWindow()));
+ EXPECT_TRUE(checker2.IsPaintScheduledAndReset());
+
+ // Moves w3 to the secondary display too. Now w1 should be solo again.
+ w3->SetBoundsInScreen(gfx::Rect(1200, 0, 100, 100), GetSecondaryDisplay());
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+ EXPECT_EQ(NULL, GetWindowWithSoloHeader(w2->GetRootWindow()));
+ EXPECT_TRUE(checker1.IsPaintScheduledAndReset());
+
+ // Change w3's state to maximize. Doesn't affect w1.
+ wm::GetWindowState(w3.get())->Maximize();
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+ EXPECT_EQ(NULL, GetWindowWithSoloHeader(w2->GetRootWindow()));
+
+ // Close w3 and w4.
+ w3.reset();
+ w4.reset();
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+ EXPECT_EQ(w2.get(), GetWindowWithSoloHeader(w2->GetRootWindow()));
+ EXPECT_TRUE(checker2.IsPaintScheduledAndReset());
+
+ // Move w2 back to the primary display.
+ w2->SetBoundsInScreen(gfx::Rect(0, 0, 100, 100), GetPrimaryDisplay());
+ EXPECT_EQ(w1->GetRootWindow(), w2->GetRootWindow());
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+ EXPECT_TRUE(checker1.IsPaintScheduledAndReset());
+ EXPECT_TRUE(checker2.IsPaintScheduledAndReset());
+
+ // Close w2.
+ w2.reset();
+ EXPECT_EQ(w1.get(), GetWindowWithSoloHeaderInPrimary());
+ EXPECT_TRUE(checker1.IsPaintScheduledAndReset());
+}
+
+TEST_F(SoloWindowTrackerTest, ChildWindowVisibility) {
+ aura::Window* w = CreateWindowInPrimary();
+ w->Show();
+
+ // We only have one window, so it should use a solo header.
+ EXPECT_EQ(w, GetWindowWithSoloHeaderInPrimary());
+
+ // Create a child window. This should not affect the solo-ness of |w1|.
+ aura::Window* child = new aura::Window(NULL);
+ child->SetType(ui::wm::WINDOW_TYPE_CONTROL);
+ child->Init(aura::WINDOW_LAYER_TEXTURED);
+ child->SetBounds(gfx::Rect(100, 100));
+ w->AddChild(child);
+ child->Show();
+ EXPECT_EQ(w, GetWindowWithSoloHeaderInPrimary());
+
+ // Changing the visibility of |child| should not affect the solo-ness of |w1|.
+ child->Hide();
+ EXPECT_EQ(w, GetWindowWithSoloHeaderInPrimary());
+}
+
+TEST_F(SoloWindowTrackerTest, CreateAndDeleteSingleWindow) {
+ // Ensure that creating/deleting a window works well and doesn't cause
+ // crashes. See crbug.com/155634
+ scoped_ptr<aura::Window> w(CreateWindowInPrimary());
+ w->Show();
+
+ // We only have one window, so it should use a solo header.
+ EXPECT_EQ(w.get(), GetWindowWithSoloHeaderInPrimary());
+
+ // Close the window.
+ w.reset();
+ EXPECT_EQ(NULL, GetWindowWithSoloHeaderInPrimary());
+
+ // Recreate another window again.
+ w.reset(CreateWindowInPrimary());
+ w->Show();
+ EXPECT_EQ(w.get(), GetWindowWithSoloHeaderInPrimary());
+}
+
+} // namespace ash
« no previous file with comments | « ash/wm/drag_window_resizer_unittest.cc ('k') | ash/wm/stacking_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698