OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/common/wm/workspace_controller.h" | 5 #include "ash/common/wm/workspace_controller.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "ash/common/session/session_controller.h" | 9 #include "ash/common/session/session_controller.h" |
10 #include "ash/common/shelf/shelf_layout_manager.h" | 10 #include "ash/common/shelf/shelf_layout_manager.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "ash/shell.h" | 23 #include "ash/shell.h" |
24 #include "ash/test/ash_test_base.h" | 24 #include "ash/test/ash_test_base.h" |
25 #include "ash/test/shell_test_api.h" | 25 #include "ash/test/shell_test_api.h" |
26 #include "ash/wm/window_state_aura.h" | 26 #include "ash/wm/window_state_aura.h" |
27 #include "ash/wm/window_util.h" | 27 #include "ash/wm/window_util.h" |
28 #include "base/strings/string_number_conversions.h" | 28 #include "base/strings/string_number_conversions.h" |
29 #include "ui/aura/client/aura_constants.h" | 29 #include "ui/aura/client/aura_constants.h" |
30 #include "ui/aura/test/test_window_delegate.h" | 30 #include "ui/aura/test/test_window_delegate.h" |
31 #include "ui/aura/test/test_windows.h" | 31 #include "ui/aura/test/test_windows.h" |
32 #include "ui/aura/window.h" | 32 #include "ui/aura/window.h" |
33 #include "ui/aura/window_event_dispatcher.h" | |
34 #include "ui/base/hit_test.h" | 33 #include "ui/base/hit_test.h" |
35 #include "ui/base/ui_base_types.h" | |
36 #include "ui/compositor/layer.h" | |
37 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | 34 #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
38 #include "ui/display/screen.h" | 35 #include "ui/display/screen.h" |
39 #include "ui/events/event_utils.h" | 36 #include "ui/events/event_utils.h" |
40 #include "ui/events/test/event_generator.h" | 37 #include "ui/events/test/event_generator.h" |
41 #include "ui/views/widget/widget.h" | 38 #include "ui/views/widget/widget.h" |
42 #include "ui/wm/core/window_animations.h" | |
43 #include "ui/wm/core/window_util.h" | 39 #include "ui/wm/core/window_util.h" |
44 | 40 |
45 using aura::Window; | 41 using aura::Window; |
46 | 42 |
47 namespace ash { | 43 namespace ash { |
48 | 44 |
49 // Returns a string containing the names of all the children of |window| (in | 45 // Returns a string containing the names of all the children of |window| (in |
50 // order). Each entry is separated by a space. | 46 // order). Each entry is separated by a space. |
51 std::string GetWindowNames(const aura::Window* window) { | 47 std::string GetWindowNames(const aura::Window* window) { |
52 std::string result; | 48 std::string result; |
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 EXPECT_EQ(snapped_bounds, window->bounds()); | 1332 EXPECT_EQ(snapped_bounds, window->bounds()); |
1337 EXPECT_TRUE(window_state->bounds_changed_by_user()); | 1333 EXPECT_TRUE(window_state->bounds_changed_by_user()); |
1338 | 1334 |
1339 // Minimize and Restore |window|, the restored bounds should be equal to the | 1335 // Minimize and Restore |window|, the restored bounds should be equal to the |
1340 // bounds of left snapped state. | 1336 // bounds of left snapped state. |
1341 window_state->Minimize(); | 1337 window_state->Minimize(); |
1342 window_state->Restore(); | 1338 window_state->Restore(); |
1343 EXPECT_EQ(snapped_bounds, window->bounds()); | 1339 EXPECT_EQ(snapped_bounds, window->bounds()); |
1344 } | 1340 } |
1345 | 1341 |
1346 namespace { | |
1347 | |
1348 // Used by DragMaximizedNonTrackedWindow to track how many times the window | |
1349 // hierarchy changes affecting the specified window. | |
1350 class DragMaximizedNonTrackedWindowObserver : public aura::WindowObserver { | |
1351 public: | |
1352 DragMaximizedNonTrackedWindowObserver(aura::Window* window) | |
1353 : change_count_(0), window_(window) {} | |
1354 | |
1355 // Number of times OnWindowHierarchyChanged() has been received. | |
1356 void clear_change_count() { change_count_ = 0; } | |
1357 int change_count() const { return change_count_; } | |
1358 | |
1359 // aura::WindowObserver overrides: | |
1360 // Counts number of times a window is reparented. Ignores reparenting into and | |
1361 // from a docked container which is expected when a tab is dragged. | |
1362 void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override { | |
1363 if (params.target != window_ || | |
1364 (params.old_parent->id() == kShellWindowId_DefaultContainer && | |
1365 params.new_parent->id() == kShellWindowId_DockedContainer) || | |
1366 (params.old_parent->id() == kShellWindowId_DockedContainer && | |
1367 params.new_parent->id() == kShellWindowId_DefaultContainer)) { | |
1368 return; | |
1369 } | |
1370 change_count_++; | |
1371 } | |
1372 | |
1373 private: | |
1374 int change_count_; | |
1375 aura::Window* window_; | |
1376 | |
1377 DISALLOW_COPY_AND_ASSIGN(DragMaximizedNonTrackedWindowObserver); | |
1378 }; | |
1379 | |
1380 } // namespace | |
1381 | |
1382 // Verifies that a new maximized window becomes visible after its activation | 1342 // Verifies that a new maximized window becomes visible after its activation |
1383 // is requested, even though it does not become activated because a system | 1343 // is requested, even though it does not become activated because a system |
1384 // modal window is active. | 1344 // modal window is active. |
1385 TEST_F(WorkspaceControllerTest, SwitchFromModal) { | 1345 TEST_F(WorkspaceControllerTest, SwitchFromModal) { |
1386 std::unique_ptr<Window> modal_window(CreateTestWindowUnparented()); | 1346 std::unique_ptr<Window> modal_window(CreateTestWindowUnparented()); |
1387 modal_window->SetBounds(gfx::Rect(10, 11, 21, 22)); | 1347 modal_window->SetBounds(gfx::Rect(10, 11, 21, 22)); |
1388 modal_window->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_SYSTEM); | 1348 modal_window->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_SYSTEM); |
1389 ParentWindowInPrimaryRootWindow(modal_window.get()); | 1349 ParentWindowInPrimaryRootWindow(modal_window.get()); |
1390 modal_window->Show(); | 1350 modal_window->Show(); |
1391 wm::ActivateWindow(modal_window.get()); | 1351 wm::ActivateWindow(modal_window.get()); |
1392 | 1352 |
1393 std::unique_ptr<Window> maximized_window(CreateTestWindow()); | 1353 std::unique_ptr<Window> maximized_window(CreateTestWindow()); |
1394 maximized_window->SetProperty(aura::client::kShowStateKey, | 1354 maximized_window->SetProperty(aura::client::kShowStateKey, |
1395 ui::SHOW_STATE_MAXIMIZED); | 1355 ui::SHOW_STATE_MAXIMIZED); |
1396 maximized_window->Show(); | 1356 maximized_window->Show(); |
1397 wm::ActivateWindow(maximized_window.get()); | 1357 wm::ActivateWindow(maximized_window.get()); |
1398 EXPECT_TRUE(maximized_window->IsVisible()); | 1358 EXPECT_TRUE(maximized_window->IsVisible()); |
1399 } | 1359 } |
1400 | 1360 |
1401 namespace { | |
1402 | |
1403 // Subclass of WorkspaceControllerTest that runs tests with docked windows | |
1404 // enabled and disabled. | |
1405 class WorkspaceControllerTestDragging : public WorkspaceControllerTest { | |
1406 public: | |
1407 WorkspaceControllerTestDragging() {} | |
1408 ~WorkspaceControllerTestDragging() override {} | |
1409 | |
1410 private: | |
1411 DISALLOW_COPY_AND_ASSIGN(WorkspaceControllerTestDragging); | |
1412 }; | |
1413 | |
1414 } // namespace | |
1415 | |
1416 // Verifies that when dragging a window over the shelf overlap is detected | 1361 // Verifies that when dragging a window over the shelf overlap is detected |
1417 // during and after the drag. | 1362 // during and after the drag. |
1418 TEST_F(WorkspaceControllerTestDragging, DragWindowOverlapShelf) { | 1363 TEST_F(WorkspaceControllerTest, DragWindowOverlapShelf) { |
1419 aura::test::TestWindowDelegate delegate; | 1364 aura::test::TestWindowDelegate delegate; |
1420 delegate.set_window_component(HTCAPTION); | 1365 delegate.set_window_component(HTCAPTION); |
1421 std::unique_ptr<Window> w1(aura::test::CreateTestWindowWithDelegate( | 1366 std::unique_ptr<Window> w1(aura::test::CreateTestWindowWithDelegate( |
1422 &delegate, ui::wm::WINDOW_TYPE_NORMAL, gfx::Rect(5, 5, 100, 50), NULL)); | 1367 &delegate, ui::wm::WINDOW_TYPE_NORMAL, gfx::Rect(5, 5, 100, 50), NULL)); |
1423 ParentWindowInPrimaryRootWindow(w1.get()); | 1368 ParentWindowInPrimaryRootWindow(w1.get()); |
1424 | 1369 |
1425 GetPrimaryShelf()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | 1370 GetPrimaryShelf()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); |
1426 | 1371 |
1427 // Drag near the shelf. | 1372 // Drag near the shelf. |
1428 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), | 1373 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), |
1429 gfx::Point()); | 1374 gfx::Point()); |
1430 generator.MoveMouseTo(10, 10); | 1375 generator.MoveMouseTo(10, 10); |
1431 generator.PressLeftButton(); | 1376 generator.PressLeftButton(); |
1432 generator.MoveMouseTo(100, shelf_layout_manager()->GetIdealBounds().y() - 70); | 1377 generator.MoveMouseTo(100, shelf_layout_manager()->GetIdealBounds().y() - 70); |
1433 | 1378 |
1434 // Shelf should not be in overlapped state. | 1379 // Shelf should not be in overlapped state. |
1435 EXPECT_FALSE(GetWindowOverlapsShelf()); | 1380 EXPECT_FALSE(GetWindowOverlapsShelf()); |
1436 | 1381 |
1437 generator.MoveMouseTo(100, shelf_layout_manager()->GetIdealBounds().y() - 20); | 1382 generator.MoveMouseTo(100, shelf_layout_manager()->GetIdealBounds().y() - 20); |
1438 | 1383 |
1439 // Shelf should detect overlap. Overlap state stays after mouse is released. | 1384 // Shelf should detect overlap. Overlap state stays after mouse is released. |
1440 EXPECT_TRUE(GetWindowOverlapsShelf()); | 1385 EXPECT_TRUE(GetWindowOverlapsShelf()); |
1441 generator.ReleaseLeftButton(); | 1386 generator.ReleaseLeftButton(); |
1442 EXPECT_TRUE(GetWindowOverlapsShelf()); | 1387 EXPECT_TRUE(GetWindowOverlapsShelf()); |
1443 } | 1388 } |
1444 | 1389 |
1445 // Verifies that when dragging a window autohidden shelf stays hidden during | 1390 // Verifies that when dragging a window autohidden shelf stays hidden during |
1446 // and after the drag. | 1391 // and after the drag. |
1447 TEST_F(WorkspaceControllerTestDragging, DragWindowKeepsShelfAutohidden) { | 1392 TEST_F(WorkspaceControllerTest, DragWindowKeepsShelfAutohidden) { |
1448 aura::test::TestWindowDelegate delegate; | 1393 aura::test::TestWindowDelegate delegate; |
1449 delegate.set_window_component(HTCAPTION); | 1394 delegate.set_window_component(HTCAPTION); |
1450 std::unique_ptr<Window> w1(aura::test::CreateTestWindowWithDelegate( | 1395 std::unique_ptr<Window> w1(aura::test::CreateTestWindowWithDelegate( |
1451 &delegate, ui::wm::WINDOW_TYPE_NORMAL, gfx::Rect(5, 5, 100, 50), NULL)); | 1396 &delegate, ui::wm::WINDOW_TYPE_NORMAL, gfx::Rect(5, 5, 100, 50), NULL)); |
1452 ParentWindowInPrimaryRootWindow(w1.get()); | 1397 ParentWindowInPrimaryRootWindow(w1.get()); |
1453 | 1398 |
1454 WmShelf* shelf = GetPrimaryShelf(); | 1399 WmShelf* shelf = GetPrimaryShelf(); |
1455 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | 1400 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); |
1456 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); | 1401 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); |
1457 | 1402 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1592 ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(), | 1537 ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(), |
1593 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); | 1538 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); |
1594 ui::EventTarget* target = targeter->FindTargetForEvent(root, &touch); | 1539 ui::EventTarget* target = targeter->FindTargetForEvent(root, &touch); |
1595 if (points[i].is_target_hit) | 1540 if (points[i].is_target_hit) |
1596 EXPECT_EQ(window.get(), target); | 1541 EXPECT_EQ(window.get(), target); |
1597 else | 1542 else |
1598 EXPECT_NE(window.get(), target); | 1543 EXPECT_NE(window.get(), target); |
1599 } | 1544 } |
1600 } | 1545 } |
1601 | 1546 |
1602 // Verifies events targeting just outside the window edges for docked windows. | |
1603 TEST_F(WorkspaceControllerTest, WindowEdgeHitTestDocked) { | |
1604 aura::test::TestWindowDelegate delegate; | |
1605 // Make window smaller than the minimum docked area so that the window edges | |
1606 // are exposed. | |
1607 delegate.set_maximum_size(gfx::Size(180, 200)); | |
1608 std::unique_ptr<Window> window(aura::test::CreateTestWindowWithDelegate( | |
1609 &delegate, 123, gfx::Rect(20, 10, 100, 50), NULL)); | |
1610 ParentWindowInPrimaryRootWindow(window.get()); | |
1611 aura::Window* docked_container = Shell::GetContainer( | |
1612 window->GetRootWindow(), kShellWindowId_DockedContainer); | |
1613 docked_container->AddChild(window.get()); | |
1614 window->Show(); | |
1615 aura::Window* root = window->GetRootWindow(); | |
1616 ui::EventTargeter* targeter = | |
1617 root->GetHost()->dispatcher()->GetDefaultEventTargeter(); | |
1618 const gfx::Rect bounds = window->bounds(); | |
1619 const int kNumPoints = 5; | |
1620 struct { | |
1621 const char* direction; | |
1622 gfx::Point location; | |
1623 bool is_target_hit; | |
1624 } points[kNumPoints] = { | |
1625 {"left", gfx::Point(bounds.x() - 2, bounds.y() + 10), true}, | |
1626 {"top", gfx::Point(bounds.x() + 10, bounds.y() - 2), true}, | |
1627 {"right", gfx::Point(bounds.right() + 2, bounds.y() + 10), true}, | |
1628 {"bottom", gfx::Point(bounds.x() + 10, bounds.bottom() + 2), true}, | |
1629 {"outside", gfx::Point(bounds.x() + 10, bounds.y() - 31), false}, | |
1630 }; | |
1631 for (int i = 0; i < kNumPoints; ++i) { | |
1632 SCOPED_TRACE(points[i].direction); | |
1633 const gfx::Point& location = points[i].location; | |
1634 ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, location, location, | |
1635 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE); | |
1636 ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse); | |
1637 if (points[i].is_target_hit) | |
1638 EXPECT_EQ(window.get(), target); | |
1639 else | |
1640 EXPECT_NE(window.get(), target); | |
1641 | |
1642 ui::TouchEvent touch( | |
1643 ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(), | |
1644 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); | |
1645 target = targeter->FindTargetForEvent(root, &touch); | |
1646 if (points[i].is_target_hit) | |
1647 EXPECT_EQ(window.get(), target); | |
1648 else | |
1649 EXPECT_NE(window.get(), target); | |
1650 } | |
1651 } | |
1652 | |
1653 } // namespace ash | 1547 } // namespace ash |
OLD | NEW |