Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 1 | // Copyright (c) 2012 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 | |
| 5 | #include "ash/wm/drag_window_resizer.h" |
| 6 | |
| 7 | #include "ash/display/mouse_cursor_event_filter.h" |
| 8 | #include "ash/root_window_controller.h" |
| 9 | #include "ash/shelf/shelf_layout_manager.h" |
| 10 | #include "ash/shell.h" |
| 11 | #include "ash/shell_window_ids.h" |
| 12 | #include "ash/test/ash_test_base.h" |
| 13 | #include "ash/test/cursor_manager_test_api.h" |
| 14 | #include "ash/wm/drag_window_controller.h" |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame] | 15 | #include "ash/wm/window_util.h" |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 16 | #include "base/strings/string_number_conversions.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 17 | #include "base/strings/stringprintf.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 18 | #include "ui/aura/client/aura_constants.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 19 | #include "ui/aura/test/test_window_delegate.h" |
Torne (Richard Coles) | a140131 | 2014-03-18 10:20:56 +0000 | [diff] [blame] | 20 | #include "ui/aura/window_event_dispatcher.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 21 | #include "ui/base/hit_test.h" |
| 22 | #include "ui/base/ui_base_types.h" |
Torne (Richard Coles) | a140131 | 2014-03-18 10:20:56 +0000 | [diff] [blame] | 23 | #include "ui/compositor/layer_tree_owner.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 24 | #include "ui/gfx/insets.h" |
| 25 | #include "ui/gfx/screen.h" |
| 26 | #include "ui/views/widget/widget.h" |
Torne (Richard Coles) | a140131 | 2014-03-18 10:20:56 +0000 | [diff] [blame] | 27 | #include "ui/wm/core/window_util.h" |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 28 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 29 | namespace ash { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 30 | namespace { |
| 31 | |
| 32 | const int kRootHeight = 600; |
| 33 | |
| 34 | } // namespace |
| 35 | |
| 36 | class DragWindowResizerTest : public test::AshTestBase { |
| 37 | public: |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 38 | DragWindowResizerTest() {} |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 39 | virtual ~DragWindowResizerTest() {} |
| 40 | |
| 41 | virtual void SetUp() OVERRIDE { |
| 42 | AshTestBase::SetUp(); |
| 43 | UpdateDisplay(base::StringPrintf("800x%d", kRootHeight)); |
| 44 | |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 45 | aura::Window* root = Shell::GetPrimaryRootWindow(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 46 | gfx::Rect root_bounds(root->bounds()); |
| 47 | EXPECT_EQ(kRootHeight, root_bounds.height()); |
| 48 | EXPECT_EQ(800, root_bounds.width()); |
| 49 | Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets()); |
| 50 | window_.reset(new aura::Window(&delegate_)); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 51 | window_->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
| 52 | window_->Init(aura::WINDOW_LAYER_NOT_DRAWN); |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 53 | ParentWindowInPrimaryRootWindow(window_.get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 54 | window_->set_id(1); |
| 55 | |
| 56 | always_on_top_window_.reset(new aura::Window(&delegate2_)); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 57 | always_on_top_window_->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 58 | always_on_top_window_->SetProperty(aura::client::kAlwaysOnTopKey, true); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 59 | always_on_top_window_->Init(aura::WINDOW_LAYER_NOT_DRAWN); |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 60 | ParentWindowInPrimaryRootWindow(always_on_top_window_.get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 61 | always_on_top_window_->set_id(2); |
| 62 | |
| 63 | system_modal_window_.reset(new aura::Window(&delegate3_)); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 64 | system_modal_window_->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 65 | system_modal_window_->SetProperty(aura::client::kModalKey, |
| 66 | ui::MODAL_TYPE_SYSTEM); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 67 | system_modal_window_->Init(aura::WINDOW_LAYER_NOT_DRAWN); |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 68 | ParentWindowInPrimaryRootWindow(system_modal_window_.get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 69 | system_modal_window_->set_id(3); |
| 70 | |
| 71 | transient_child_ = new aura::Window(&delegate4_); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 72 | transient_child_->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
| 73 | transient_child_->Init(aura::WINDOW_LAYER_NOT_DRAWN); |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 74 | ParentWindowInPrimaryRootWindow(transient_child_); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 75 | transient_child_->set_id(4); |
| 76 | |
| 77 | transient_parent_.reset(new aura::Window(&delegate5_)); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 78 | transient_parent_->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
| 79 | transient_parent_->Init(aura::WINDOW_LAYER_NOT_DRAWN); |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 80 | ParentWindowInPrimaryRootWindow(transient_parent_.get()); |
Torne (Richard Coles) | a140131 | 2014-03-18 10:20:56 +0000 | [diff] [blame] | 81 | ::wm::AddTransientChild(transient_parent_.get(), transient_child_); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 82 | transient_parent_->set_id(5); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 83 | |
| 84 | panel_window_.reset(new aura::Window(&delegate6_)); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 85 | panel_window_->SetType(ui::wm::WINDOW_TYPE_PANEL); |
| 86 | panel_window_->Init(aura::WINDOW_LAYER_NOT_DRAWN); |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 87 | ParentWindowInPrimaryRootWindow(panel_window_.get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | virtual void TearDown() OVERRIDE { |
| 91 | window_.reset(); |
| 92 | always_on_top_window_.reset(); |
| 93 | system_modal_window_.reset(); |
| 94 | transient_parent_.reset(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 95 | panel_window_.reset(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 96 | AshTestBase::TearDown(); |
| 97 | } |
| 98 | |
| 99 | protected: |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 100 | gfx::Point CalculateDragPoint(const WindowResizer& resizer, |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 101 | int delta_x, |
| 102 | int delta_y) const { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 103 | gfx::Point location = resizer.GetInitialLocation(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 104 | location.set_x(location.x() + delta_x); |
| 105 | location.set_y(location.y() + delta_y); |
| 106 | return location; |
| 107 | } |
| 108 | |
Ben Murdoch | c5cede9 | 2014-04-10 11:22:14 +0100 | [diff] [blame] | 109 | ShelfLayoutManager* shelf_layout_manager() { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 110 | return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager(); |
| 111 | } |
| 112 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 113 | static WindowResizer* CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 114 | aura::Window* window, |
| 115 | const gfx::Point& point_in_parent, |
| 116 | int window_component) { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 117 | return CreateWindowResizer( |
| 118 | window, |
| 119 | point_in_parent, |
| 120 | window_component, |
| 121 | aura::client::WINDOW_MOVE_SOURCE_MOUSE).release(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 122 | } |
| 123 | |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 124 | bool WarpMouseCursorIfNecessary(aura::Window* target_root, |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 125 | const gfx::Point& point_in_screen) { |
| 126 | MouseCursorEventFilter* event_filter = |
| 127 | Shell::GetInstance()->mouse_cursor_filter(); |
Torne (Richard Coles) | cedac22 | 2014-06-03 10:58:34 +0100 | [diff] [blame] | 128 | bool is_warped = event_filter->WarpMouseCursorIfNecessaryForTest( |
| 129 | target_root, point_in_screen); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 130 | event_filter->reset_was_mouse_warped_for_test(); |
| 131 | return is_warped; |
| 132 | } |
| 133 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 134 | aura::test::TestWindowDelegate delegate_; |
| 135 | aura::test::TestWindowDelegate delegate2_; |
| 136 | aura::test::TestWindowDelegate delegate3_; |
| 137 | aura::test::TestWindowDelegate delegate4_; |
| 138 | aura::test::TestWindowDelegate delegate5_; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 139 | aura::test::TestWindowDelegate delegate6_; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 140 | |
| 141 | scoped_ptr<aura::Window> window_; |
| 142 | scoped_ptr<aura::Window> always_on_top_window_; |
| 143 | scoped_ptr<aura::Window> system_modal_window_; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 144 | scoped_ptr<aura::Window> panel_window_; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 145 | aura::Window* transient_child_; |
| 146 | scoped_ptr<aura::Window> transient_parent_; |
| 147 | |
| 148 | private: |
| 149 | DISALLOW_COPY_AND_ASSIGN(DragWindowResizerTest); |
| 150 | }; |
| 151 | |
| 152 | // Verifies a window can be moved from the primary display to another. |
| 153 | TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplays) { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 154 | if (!SupportsMultipleDisplays()) |
| 155 | return; |
| 156 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 157 | // The secondary display is logically on the right, but on the system (e.g. X) |
| 158 | // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc. |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 159 | UpdateDisplay("800x600,400x300"); |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 160 | aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 161 | ASSERT_EQ(2U, root_windows.size()); |
| 162 | |
| 163 | window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 164 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 165 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 166 | { |
| 167 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 168 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 169 | window_.get(), gfx::Point(), HTCAPTION)); |
| 170 | ASSERT_TRUE(resizer.get()); |
| 171 | // Drag the pointer to the right. Once it reaches the right edge of the |
| 172 | // primary display, it warps to the secondary. |
| 173 | resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 174 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 175 | // The whole window is on the secondary display now. The parent should be |
| 176 | // changed. |
| 177 | EXPECT_EQ(root_windows[1], window_->GetRootWindow()); |
| 178 | EXPECT_EQ("0,10 50x60", window_->bounds().ToString()); |
| 179 | } |
| 180 | |
| 181 | window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 182 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 183 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 184 | { |
| 185 | // Grab (0, 0) of the window and move the pointer to (790, 10). |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 186 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 187 | window_.get(), gfx::Point(), HTCAPTION)); |
| 188 | ASSERT_TRUE(resizer.get()); |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 189 | resizer->Drag(CalculateDragPoint(*resizer, 795, 10), 0); |
| 190 | // Window should be adjusted for minimum visibility (10px) during the drag. |
| 191 | EXPECT_EQ("790,10 50x60", window_->bounds().ToString()); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 192 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 193 | // Since the pointer is still on the primary root window, the parent should |
| 194 | // not be changed. |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 195 | // Window origin should be adjusted for minimum visibility (10px). |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 196 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 197 | EXPECT_EQ("790,10 50x60", window_->bounds().ToString()); |
| 198 | } |
| 199 | |
| 200 | window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 201 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 202 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 203 | { |
| 204 | // Grab the top-right edge of the window and move the pointer to (0, 10) |
| 205 | // in the secondary root window's coordinates. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 206 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 207 | window_.get(), gfx::Point(49, 0), HTCAPTION)); |
| 208 | ASSERT_TRUE(resizer.get()); |
| 209 | resizer->Drag(CalculateDragPoint(*resizer, 751, 10), ui::EF_CONTROL_DOWN); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 210 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 211 | // Since the pointer is on the secondary, the parent should be changed |
| 212 | // even though only small fraction of the window is within the secondary |
| 213 | // root window's bounds. |
| 214 | EXPECT_EQ(root_windows[1], window_->GetRootWindow()); |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 215 | // Window origin should be adjusted for minimum visibility (10px). |
| 216 | int expected_x = -50 + 10; |
| 217 | EXPECT_EQ(base::IntToString(expected_x) + ",10 50x60", |
| 218 | window_->bounds().ToString()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 219 | } |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 220 | // Dropping a window that is larger than the destination work area |
| 221 | // will shrink to fit to the work area. |
| 222 | window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500), |
| 223 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 224 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 225 | { |
| 226 | // Grab the top-right edge of the window and move the pointer to (0, 10) |
| 227 | // in the secondary root window's coordinates. |
| 228 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
| 229 | window_.get(), gfx::Point(699, 0), HTCAPTION)); |
| 230 | ASSERT_TRUE(resizer.get()); |
| 231 | resizer->Drag(CalculateDragPoint(*resizer, 101, 10), ui::EF_CONTROL_DOWN); |
| 232 | resizer->CompleteDrag(); |
| 233 | EXPECT_EQ(root_windows[1], window_->GetRootWindow()); |
| 234 | // Window size should be adjusted to fit to the work area |
| 235 | EXPECT_EQ("400x253", window_->bounds().size().ToString()); |
| 236 | gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen(); |
| 237 | gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen()); |
| 238 | intersect.Intersect(window_bounds_in_screen); |
| 239 | |
| 240 | EXPECT_LE(10, intersect.width()); |
| 241 | EXPECT_LE(10, intersect.height()); |
| 242 | EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(800, 10))); |
| 243 | } |
| 244 | |
| 245 | // Dropping a window that is larger than the destination work area |
| 246 | // will shrink to fit to the work area. |
| 247 | window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500), |
| 248 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 249 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 250 | { |
| 251 | // Grab the top-left edge of the window and move the pointer to (150, 10) |
| 252 | // in the secondary root window's coordinates. Make sure the window is |
| 253 | // shrink in such a way that it keeps the cursor within. |
| 254 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
| 255 | window_.get(), gfx::Point(0, 0), HTCAPTION)); |
| 256 | ASSERT_TRUE(resizer.get()); |
| 257 | resizer->Drag(CalculateDragPoint(*resizer, 799, 10), ui::EF_CONTROL_DOWN); |
| 258 | resizer->Drag(CalculateDragPoint(*resizer, 850, 10), ui::EF_CONTROL_DOWN); |
| 259 | resizer->CompleteDrag(); |
| 260 | EXPECT_EQ(root_windows[1], window_->GetRootWindow()); |
| 261 | // Window size should be adjusted to fit to the work area |
| 262 | EXPECT_EQ("400x253", window_->bounds().size().ToString()); |
| 263 | gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen(); |
| 264 | gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen()); |
| 265 | intersect.Intersect(window_bounds_in_screen); |
| 266 | EXPECT_LE(10, intersect.width()); |
| 267 | EXPECT_LE(10, intersect.height()); |
| 268 | EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(850, 10))); |
| 269 | } |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 270 | } |
| 271 | |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame] | 272 | // Verifies that dragging the active window to another display makes the new |
| 273 | // root window the active root window. |
| 274 | TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysActiveRoot) { |
| 275 | if (!SupportsMultipleDisplays()) |
| 276 | return; |
| 277 | |
| 278 | // The secondary display is logically on the right, but on the system (e.g. X) |
| 279 | // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc. |
| 280 | UpdateDisplay("800x600,800x600"); |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 281 | aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame] | 282 | ASSERT_EQ(2U, root_windows.size()); |
| 283 | |
| 284 | aura::test::TestWindowDelegate delegate; |
| 285 | scoped_ptr<aura::Window> window(new aura::Window(&delegate)); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 286 | window->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
| 287 | window->Init(aura::WINDOW_LAYER_TEXTURED); |
Torne (Richard Coles) | 1e9bf3e | 2013-10-31 11:16:26 +0000 | [diff] [blame] | 288 | ParentWindowInPrimaryRootWindow(window.get()); |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame] | 289 | window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 290 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 291 | window->Show(); |
| 292 | EXPECT_TRUE(ash::wm::CanActivateWindow(window.get())); |
| 293 | ash::wm::ActivateWindow(window.get()); |
| 294 | EXPECT_EQ(root_windows[0], window->GetRootWindow()); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 295 | EXPECT_EQ(root_windows[0], ash::Shell::GetTargetRootWindow()); |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame] | 296 | { |
| 297 | // Grab (0, 0) of the window. |
| 298 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
| 299 | window.get(), gfx::Point(), HTCAPTION)); |
| 300 | ASSERT_TRUE(resizer.get()); |
| 301 | // Drag the pointer to the right. Once it reaches the right edge of the |
| 302 | // primary display, it warps to the secondary. |
| 303 | resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 304 | resizer->CompleteDrag(); |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame] | 305 | // The whole window is on the secondary display now. The parent should be |
| 306 | // changed. |
| 307 | EXPECT_EQ(root_windows[1], window->GetRootWindow()); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 308 | EXPECT_EQ(root_windows[1], ash::Shell::GetTargetRootWindow()); |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame] | 309 | } |
| 310 | } |
| 311 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 312 | // Verifies a window can be moved from the secondary display to primary. |
| 313 | TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysRightToLeft) { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 314 | if (!SupportsMultipleDisplays()) |
| 315 | return; |
| 316 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 317 | UpdateDisplay("800x600,800x600"); |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 318 | aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 319 | ASSERT_EQ(2U, root_windows.size()); |
| 320 | |
| 321 | window_->SetBoundsInScreen( |
| 322 | gfx::Rect(800, 00, 50, 60), |
| 323 | Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1])); |
| 324 | EXPECT_EQ(root_windows[1], window_->GetRootWindow()); |
| 325 | { |
| 326 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 327 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 328 | window_.get(), gfx::Point(), HTCAPTION)); |
| 329 | ASSERT_TRUE(resizer.get()); |
| 330 | // Move the mouse near the right edge, (798, 0), of the primary display. |
| 331 | resizer->Drag(CalculateDragPoint(*resizer, -2, 0), ui::EF_CONTROL_DOWN); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 332 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 333 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 334 | // Window origin should be adjusted for minimum visibility (10px). |
| 335 | int expected_x = 800 - 10; |
| 336 | EXPECT_EQ(base::IntToString(expected_x) + ",0 50x60", |
| 337 | window_->bounds().ToString()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 338 | } |
| 339 | } |
| 340 | |
| 341 | // Verifies the drag window is shown correctly. |
| 342 | TEST_F(DragWindowResizerTest, DragWindowController) { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 343 | if (!SupportsMultipleDisplays()) |
| 344 | return; |
| 345 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 346 | UpdateDisplay("800x600,800x600"); |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 347 | aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 348 | ASSERT_EQ(2U, root_windows.size()); |
| 349 | |
| 350 | window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 351 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 352 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 353 | EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); |
| 354 | { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 355 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 356 | window_.get(), gfx::Point(), HTCAPTION)); |
| 357 | ASSERT_TRUE(resizer.get()); |
Ben Murdoch | c5cede9 | 2014-04-10 11:22:14 +0100 | [diff] [blame] | 358 | DragWindowResizer* drag_resizer = DragWindowResizer::instance_; |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 359 | ASSERT_TRUE(drag_resizer); |
| 360 | EXPECT_FALSE(drag_resizer->drag_window_controller_.get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 361 | |
| 362 | // The pointer is inside the primary root. The drag window controller |
| 363 | // should be NULL. |
| 364 | resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0); |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 365 | EXPECT_FALSE(drag_resizer->drag_window_controller_.get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 366 | |
| 367 | // The window spans both root windows. |
| 368 | resizer->Drag(CalculateDragPoint(*resizer, 798, 10), 0); |
| 369 | DragWindowController* controller = |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 370 | drag_resizer->drag_window_controller_.get(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 371 | ASSERT_TRUE(controller); |
| 372 | |
| 373 | ASSERT_TRUE(controller->drag_widget_); |
| 374 | ui::Layer* drag_layer = |
| 375 | controller->drag_widget_->GetNativeWindow()->layer(); |
| 376 | ASSERT_TRUE(drag_layer); |
| 377 | // Check if |resizer->layer_| is properly set to the drag widget. |
| 378 | const std::vector<ui::Layer*>& layers = drag_layer->children(); |
| 379 | EXPECT_FALSE(layers.empty()); |
Torne (Richard Coles) | a140131 | 2014-03-18 10:20:56 +0000 | [diff] [blame] | 380 | EXPECT_EQ(controller->layer_owner_->root(), layers.back()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 381 | |
| 382 | // |window_| should be opaque since the pointer is still on the primary |
| 383 | // root window. The drag window should be semi-transparent. |
| 384 | EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); |
| 385 | ASSERT_TRUE(controller->drag_widget_); |
| 386 | EXPECT_GT(1.0f, drag_layer->opacity()); |
| 387 | |
| 388 | // Enter the pointer to the secondary display. |
| 389 | resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0); |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 390 | controller = drag_resizer->drag_window_controller_.get(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 391 | ASSERT_TRUE(controller); |
| 392 | // |window_| should be transparent, and the drag window should be opaque. |
| 393 | EXPECT_GT(1.0f, window_->layer()->opacity()); |
| 394 | EXPECT_FLOAT_EQ(1.0f, drag_layer->opacity()); |
| 395 | |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 396 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 397 | EXPECT_EQ(root_windows[1], window_->GetRootWindow()); |
| 398 | EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); |
| 399 | } |
| 400 | |
| 401 | // Do the same test with RevertDrag(). |
| 402 | window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 403 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 404 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 405 | EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); |
| 406 | { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 407 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 408 | window_.get(), gfx::Point(), HTCAPTION)); |
| 409 | ASSERT_TRUE(resizer.get()); |
Ben Murdoch | c5cede9 | 2014-04-10 11:22:14 +0100 | [diff] [blame] | 410 | DragWindowResizer* drag_resizer = DragWindowResizer::instance_; |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 411 | ASSERT_TRUE(drag_resizer); |
| 412 | EXPECT_FALSE(drag_resizer->drag_window_controller_.get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 413 | |
| 414 | resizer->Drag(CalculateDragPoint(*resizer, 0, 610), 0); |
| 415 | resizer->RevertDrag(); |
| 416 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 417 | EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | // Verifies if the resizer sets and resets |
| 422 | // MouseCursorEventFilter::mouse_warp_mode_ as expected. |
| 423 | TEST_F(DragWindowResizerTest, WarpMousePointer) { |
| 424 | MouseCursorEventFilter* event_filter = |
| 425 | Shell::GetInstance()->mouse_cursor_filter(); |
| 426 | ASSERT_TRUE(event_filter); |
| 427 | window_->SetBounds(gfx::Rect(0, 0, 50, 60)); |
| 428 | |
| 429 | EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, |
| 430 | event_filter->mouse_warp_mode_); |
| 431 | { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 432 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 433 | window_.get(), gfx::Point(), HTCAPTION)); |
| 434 | // While dragging a window, warp should be allowed. |
| 435 | EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG, |
| 436 | event_filter->mouse_warp_mode_); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 437 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 438 | } |
| 439 | EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, |
| 440 | event_filter->mouse_warp_mode_); |
| 441 | |
| 442 | { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 443 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 444 | window_.get(), gfx::Point(), HTCAPTION)); |
| 445 | EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG, |
| 446 | event_filter->mouse_warp_mode_); |
| 447 | resizer->RevertDrag(); |
| 448 | } |
| 449 | EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, |
| 450 | event_filter->mouse_warp_mode_); |
| 451 | |
| 452 | { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 453 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 454 | window_.get(), gfx::Point(), HTRIGHT)); |
| 455 | // While resizing a window, warp should NOT be allowed. |
| 456 | EXPECT_EQ(MouseCursorEventFilter::WARP_NONE, |
| 457 | event_filter->mouse_warp_mode_); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 458 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 459 | } |
| 460 | EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, |
| 461 | event_filter->mouse_warp_mode_); |
| 462 | |
| 463 | { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 464 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 465 | window_.get(), gfx::Point(), HTRIGHT)); |
| 466 | EXPECT_EQ(MouseCursorEventFilter::WARP_NONE, |
| 467 | event_filter->mouse_warp_mode_); |
| 468 | resizer->RevertDrag(); |
| 469 | } |
| 470 | EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, |
| 471 | event_filter->mouse_warp_mode_); |
| 472 | } |
| 473 | |
| 474 | // Verifies cursor's device scale factor is updated whe a window is moved across |
| 475 | // root windows with different device scale factors (http://crbug.com/154183). |
| 476 | TEST_F(DragWindowResizerTest, CursorDeviceScaleFactor) { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 477 | if (!SupportsMultipleDisplays()) |
| 478 | return; |
| 479 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 480 | // The secondary display is logically on the right, but on the system (e.g. X) |
| 481 | // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc. |
| 482 | UpdateDisplay("400x400,800x800*2"); |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 483 | aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 484 | ASSERT_EQ(2U, root_windows.size()); |
| 485 | |
| 486 | test::CursorManagerTestApi cursor_test_api( |
| 487 | Shell::GetInstance()->cursor_manager()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 488 | // Move window from the root window with 1.0 device scale factor to the root |
| 489 | // window with 2.0 device scale factor. |
| 490 | { |
| 491 | window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 492 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 493 | EXPECT_EQ(root_windows[0], window_->GetRootWindow()); |
| 494 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 495 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 496 | window_.get(), gfx::Point(), HTCAPTION)); |
Ben Murdoch | 0529e5d | 2014-04-24 10:50:13 +0100 | [diff] [blame] | 497 | EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 498 | ASSERT_TRUE(resizer.get()); |
| 499 | resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 500 | WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(399, 200)); |
Ben Murdoch | 0529e5d | 2014-04-24 10:50:13 +0100 | [diff] [blame] | 501 | EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 502 | resizer->CompleteDrag(); |
Ben Murdoch | 0529e5d | 2014-04-24 10:50:13 +0100 | [diff] [blame] | 503 | EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 504 | } |
| 505 | |
| 506 | // Move window from the root window with 2.0 device scale factor to the root |
| 507 | // window with 1.0 device scale factor. |
| 508 | { |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 509 | // Make sure the window is on the default container first. |
| 510 | aura::Window* default_container = |
Ben Murdoch | c5cede9 | 2014-04-10 11:22:14 +0100 | [diff] [blame] | 511 | GetRootWindowController(root_windows[1]) |
| 512 | ->GetContainer(kShellWindowId_DefaultContainer); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 513 | default_container->AddChild(window_.get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 514 | window_->SetBoundsInScreen( |
| 515 | gfx::Rect(600, 0, 50, 60), |
| 516 | Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1])); |
| 517 | EXPECT_EQ(root_windows[1], window_->GetRootWindow()); |
| 518 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 519 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 520 | window_.get(), gfx::Point(), HTCAPTION)); |
Ben Murdoch | 0529e5d | 2014-04-24 10:50:13 +0100 | [diff] [blame] | 521 | EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 522 | ASSERT_TRUE(resizer.get()); |
| 523 | resizer->Drag(CalculateDragPoint(*resizer, -200, 200), 0); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 524 | WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(400, 200)); |
Ben Murdoch | 0529e5d | 2014-04-24 10:50:13 +0100 | [diff] [blame] | 525 | EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 526 | resizer->CompleteDrag(); |
Ben Murdoch | 0529e5d | 2014-04-24 10:50:13 +0100 | [diff] [blame] | 527 | EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 528 | } |
| 529 | } |
| 530 | |
| 531 | // Verifies several kinds of windows can be moved across displays. |
| 532 | TEST_F(DragWindowResizerTest, MoveWindowAcrossDisplays) { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 533 | if (!SupportsMultipleDisplays()) |
| 534 | return; |
| 535 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 536 | // The secondary display is logically on the right, but on the system (e.g. X) |
| 537 | // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc. |
| 538 | UpdateDisplay("400x400,400x400"); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 539 | |
Torne (Richard Coles) | f2477e0 | 2013-11-28 11:55:43 +0000 | [diff] [blame] | 540 | aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 541 | ASSERT_EQ(2U, root_windows.size()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 542 | |
| 543 | // Normal window can be moved across display. |
| 544 | { |
| 545 | aura::Window* window = window_.get(); |
| 546 | window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 547 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 548 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 549 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 550 | window, gfx::Point(), HTCAPTION)); |
| 551 | ASSERT_TRUE(resizer.get()); |
| 552 | resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 553 | EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], |
| 554 | gfx::Point(399, 200))); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 555 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 556 | } |
| 557 | |
| 558 | // Always on top window can be moved across display. |
| 559 | { |
| 560 | aura::Window* window = always_on_top_window_.get(); |
| 561 | window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 562 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 563 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 564 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 565 | window, gfx::Point(), HTCAPTION)); |
| 566 | ASSERT_TRUE(resizer.get()); |
| 567 | resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 568 | EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], |
| 569 | gfx::Point(399, 200))); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 570 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 571 | } |
| 572 | |
| 573 | // System modal window can be moved across display. |
| 574 | { |
| 575 | aura::Window* window = system_modal_window_.get(); |
| 576 | window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 577 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 578 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 579 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 580 | window, gfx::Point(), HTCAPTION)); |
| 581 | ASSERT_TRUE(resizer.get()); |
| 582 | resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 583 | EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], |
| 584 | gfx::Point(399, 200))); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 585 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 586 | } |
| 587 | |
| 588 | // Transient window cannot be moved across display. |
| 589 | { |
| 590 | aura::Window* window = transient_child_; |
| 591 | window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 592 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 593 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 594 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 595 | window, gfx::Point(), HTCAPTION)); |
| 596 | ASSERT_TRUE(resizer.get()); |
| 597 | resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 598 | EXPECT_FALSE(WarpMouseCursorIfNecessary( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 599 | root_windows[0], |
| 600 | gfx::Point(399, 200))); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 601 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 602 | } |
| 603 | |
| 604 | // The parent of transient window can be moved across display. |
| 605 | { |
| 606 | aura::Window* window = transient_parent_.get(); |
| 607 | window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 608 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 609 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 610 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 611 | window, gfx::Point(), HTCAPTION)); |
| 612 | ASSERT_TRUE(resizer.get()); |
| 613 | resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 614 | EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], |
| 615 | gfx::Point(399, 200))); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 616 | resizer->CompleteDrag(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 617 | } |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 618 | |
| 619 | // Panel window can be moved across display. |
| 620 | { |
| 621 | aura::Window* window = panel_window_.get(); |
| 622 | window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), |
| 623 | Shell::GetScreen()->GetPrimaryDisplay()); |
| 624 | // Grab (0, 0) of the window. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 625 | scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 626 | window, gfx::Point(), HTCAPTION)); |
| 627 | ASSERT_TRUE(resizer.get()); |
| 628 | resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); |
Torne (Richard Coles) | d0247b1 | 2013-09-19 22:36:51 +0100 | [diff] [blame] | 629 | EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], |
| 630 | gfx::Point(399, 200))); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 631 | resizer->CompleteDrag(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 632 | } |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 633 | } |
| 634 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 635 | } // namespace ash |