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

Side by Side Diff: ash/wm/dock/docked_window_layout_manager_unittest.cc

Issue 2700523004: Remove docked windows entirely in M59. (Closed)
Patch Set: Rebase Created 3 years, 9 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/common/wm/dock/docked_window_layout_manager.h"
6
7 #include "ash/common/ash_switches.h"
8 #include "ash/common/shelf/wm_shelf.h"
9 #include "ash/common/test/test_shelf_delegate.h"
10 #include "ash/common/wm/panels/panel_layout_manager.h"
11 #include "ash/common/wm/window_resizer.h"
12 #include "ash/common/wm/window_state.h"
13 #include "ash/common/wm_shell.h"
14 #include "ash/common/wm_window.h"
15 #include "ash/public/cpp/shell_window_ids.h"
16 #include "ash/root_window_controller.h"
17 #include "ash/shell.h"
18 #include "ash/test/ash_test_base.h"
19 #include "ash/test/shelf_view_test_api.h"
20 #include "ash/test/shell_test_api.h"
21 #include "ash/wm/window_state_aura.h"
22 #include "ash/wm/window_util.h"
23 #include "base/command_line.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
26 #include "ui/aura/client/aura_constants.h"
27 #include "ui/aura/test/test_window_delegate.h"
28 #include "ui/aura/window.h"
29 #include "ui/aura/window_event_dispatcher.h"
30 #include "ui/base/hit_test.h"
31 #include "ui/display/display_layout.h"
32 #include "ui/display/manager/display_manager.h"
33 #include "ui/display/screen.h"
34 #include "ui/display/test/display_manager_test_api.h"
35 #include "ui/views/widget/widget.h"
36 #include "ui/wm/core/coordinate_conversion.h"
37
38 namespace ash {
39
40 class DockedWindowLayoutManagerTest
41 : public test::AshTestBase,
42 public testing::WithParamInterface<ui::wm::WindowType> {
43 public:
44 DockedWindowLayoutManagerTest() : window_type_(GetParam()) {}
45 virtual ~DockedWindowLayoutManagerTest() {}
46
47 void SetUp() override {
48 base::CommandLine::ForCurrentProcess()->AppendSwitch(
49 ash::switches::kAshEnableDockedWindows);
50 AshTestBase::SetUp();
51 UpdateDisplay("600x600");
52
53 shelf_view_test_.reset(new test::ShelfViewTestAPI(
54 GetPrimaryShelf()->GetShelfViewForTesting()));
55 shelf_view_test_->SetAnimationDuration(1);
56 }
57
58 protected:
59 enum DockedEdge {
60 DOCKED_EDGE_NONE,
61 DOCKED_EDGE_LEFT,
62 DOCKED_EDGE_RIGHT,
63 };
64
65 int min_dock_gap() const { return DockedWindowLayoutManager::kMinDockGap; }
66 int ideal_width() const { return DockedWindowLayoutManager::kIdealWidth; }
67 int docked_width(const DockedWindowLayoutManager* layout_manager) const {
68 return layout_manager->docked_width_;
69 }
70
71 aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
72 return CreateTestWindowWithDelegate(bounds, nullptr);
73 }
74
75 aura::Window* CreateTestWindowWithDelegate(
76 const gfx::Rect& bounds,
77 aura::test::TestWindowDelegate* delegate) {
78 aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
79 delegate, window_type_, 0, bounds);
80 if (window_type_ == ui::wm::WINDOW_TYPE_PANEL) {
81 WmWindow* wm_window = WmWindow::Get(window);
82 test::TestShelfDelegate::instance()->AddShelfItem(wm_window);
83 PanelLayoutManager::Get(wm_window)->Relayout();
84 }
85 return window;
86 }
87
88 static WindowResizer* CreateSomeWindowResizer(
89 aura::Window* window,
90 const gfx::Point& point_in_parent,
91 int window_component) {
92 return CreateWindowResizer(WmWindow::Get(window), point_in_parent,
93 window_component,
94 aura::client::WINDOW_MOVE_SOURCE_MOUSE)
95 .release();
96 }
97
98 void DragStart(aura::Window* window) {
99 DragStartAtOffsetFromwindowOrigin(window, 0, 0);
100 }
101
102 void DragStartAtOffsetFromwindowOrigin(aura::Window* window, int dx, int dy) {
103 initial_location_in_parent_ =
104 window->bounds().origin() + gfx::Vector2d(dx, dy);
105 resizer_.reset(CreateSomeWindowResizer(window, initial_location_in_parent_,
106 HTCAPTION));
107 ASSERT_TRUE(resizer_.get());
108 }
109
110 void DragMove(int dx, int dy) {
111 resizer_->Drag(initial_location_in_parent_ + gfx::Vector2d(dx, dy), 0);
112 }
113
114 void DragEnd() {
115 resizer_->CompleteDrag();
116 resizer_.reset();
117 }
118
119 void DragRevert() {
120 resizer_->RevertDrag();
121 resizer_.reset();
122 }
123
124 // Panels are parented by panel container during drags.
125 // Docked windows are parented by dock container during drags.
126 // All other windows that we are testing here have default container as a
127 // parent.
128 int CorrectContainerIdDuringDrag() {
129 if (window_type_ == ui::wm::WINDOW_TYPE_PANEL)
130 return kShellWindowId_PanelContainer;
131 return kShellWindowId_DockedContainer;
132 }
133
134 // Test dragging the window vertically (to detach if it is a panel) and then
135 // horizontally to the edge with an added offset from the edge of |dx|.
136 void DragRelativeToEdge(DockedEdge edge, aura::Window* window, int dx) {
137 DragVerticallyAndRelativeToEdge(
138 edge, window, dx,
139 window_type_ == ui::wm::WINDOW_TYPE_PANEL ? -100 : 20);
140 }
141
142 void DragToVerticalPositionAndToEdge(DockedEdge edge,
143 aura::Window* window,
144 int y) {
145 DragToVerticalPositionRelativeToEdge(edge, window, 0, y);
146 }
147
148 void DragToVerticalPositionRelativeToEdge(DockedEdge edge,
149 aura::Window* window,
150 int dx,
151 int y) {
152 gfx::Rect initial_bounds = window->GetBoundsInScreen();
153 DragVerticallyAndRelativeToEdge(edge, window, dx, y - initial_bounds.y());
154 }
155
156 // Detach if our window is a panel, then drag it vertically by |dy| and
157 // horizontally to the edge with an added offset from the edge of |dx|.
158 void DragVerticallyAndRelativeToEdge(DockedEdge edge,
159 aura::Window* window,
160 int dx,
161 int dy) {
162 gfx::Rect initial_bounds = window->GetBoundsInScreen();
163 // avoid snap by clicking away from the border
164 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromwindowOrigin(window, 25, 5));
165
166 gfx::Rect work_area = display::Screen::GetScreen()
167 ->GetDisplayNearestWindow(window)
168 .work_area();
169 gfx::Point initial_location_in_screen = initial_location_in_parent_;
170 ::wm::ConvertPointToScreen(window->parent(), &initial_location_in_screen);
171 // Drag the window left or right to the edge (or almost to it).
172 if (edge == DOCKED_EDGE_LEFT)
173 dx += work_area.x() - initial_location_in_screen.x();
174 else if (edge == DOCKED_EDGE_RIGHT)
175 dx += work_area.right() - 1 - initial_location_in_screen.x();
176 DragMove(dx, dy);
177 EXPECT_EQ(CorrectContainerIdDuringDrag(), window->parent()->id());
178 // Release the mouse and the panel should be attached to the dock.
179 DragEnd();
180
181 // x-coordinate can get adjusted by snapping or sticking.
182 // y-coordinate could be changed by possible automatic layout if docked.
183 if (window->parent()->id() != kShellWindowId_DockedContainer &&
184 !wm::GetWindowState(window)->HasRestoreBounds()) {
185 EXPECT_EQ(initial_bounds.y() + dy, window->GetBoundsInScreen().y());
186 }
187 }
188
189 private:
190 std::unique_ptr<WindowResizer> resizer_;
191 std::unique_ptr<test::ShelfViewTestAPI> shelf_view_test_;
192 ui::wm::WindowType window_type_;
193
194 // Location at start of the drag in |window->parent()|'s coordinates.
195 gfx::Point initial_location_in_parent_;
196
197 DISALLOW_COPY_AND_ASSIGN(DockedWindowLayoutManagerTest);
198 };
199
200 // Tests that a created window is successfully added to the dock
201 // layout manager.
202 TEST_P(DockedWindowLayoutManagerTest, AddOneWindow) {
203 gfx::Rect bounds(0, 0, 201, 201);
204 std::unique_ptr<aura::Window> window(CreateTestWindow(bounds));
205 DragRelativeToEdge(DOCKED_EDGE_RIGHT, window.get(), 0);
206
207 // The window should be attached and docked at the right edge.
208 // Its width should shrink or grow to ideal width.
209 EXPECT_EQ(window->GetRootWindow()->bounds().right(),
210 window->GetBoundsInScreen().right());
211 EXPECT_EQ(ideal_width(), window->bounds().width());
212 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
213 }
214
215 // Tests that a docked window's bounds cannot be changed programmatically.
216 TEST_P(DockedWindowLayoutManagerTest, DockedWindowBoundsDontChange) {
217 gfx::Rect bounds(0, 0, 201, 201);
218 std::unique_ptr<aura::Window> window(CreateTestWindow(bounds));
219 DragRelativeToEdge(DOCKED_EDGE_RIGHT, window.get(), 0);
220
221 // The window should be attached and docked at the right edge.
222 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
223
224 bounds = window->GetBoundsInScreen();
225 window->SetBounds(gfx::Rect(210, 210, 210, 210));
226 EXPECT_EQ(bounds.ToString(), window->GetBoundsInScreen().ToString());
227 }
228
229 // Tests that with a window docked on the left the auto-placing logic in
230 // RearrangeVisibleWindowOnShow places windows flush with work area edges.
231 TEST_P(DockedWindowLayoutManagerTest, AutoPlacingLeft) {
232 gfx::Rect bounds(0, 0, 201, 201);
233 std::unique_ptr<aura::Window> window(CreateTestWindow(bounds));
234 DragRelativeToEdge(DOCKED_EDGE_LEFT, window.get(), 0);
235
236 // The window should be attached and snapped to the right side of the screen.
237 EXPECT_EQ(window->GetRootWindow()->bounds().x(),
238 window->GetBoundsInScreen().x());
239 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
240
241 DockedWindowLayoutManager* manager =
242 DockedWindowLayoutManager::Get(WmWindow::Get(window.get()));
243
244 // Create two additional windows and test their auto-placement
245 std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
246 gfx::Rect desktop_area = window1->parent()->bounds();
247 wm::GetWindowState(window1.get())->set_window_position_managed(true);
248 window1->Hide();
249 window1->SetBounds(gfx::Rect(250, 32, 231, 320));
250 window1->Show();
251 // |window1| should be centered in work area.
252 EXPECT_EQ(base::IntToString(docked_width(manager) + min_dock_gap() +
253 (desktop_area.width() - docked_width(manager) -
254 min_dock_gap() - window1->bounds().width()) /
255 2) +
256 ",32 231x320",
257 window1->bounds().ToString());
258
259 std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
260 wm::GetWindowState(window2.get())->set_window_position_managed(true);
261 // To avoid any auto window manager changes due to SetBounds, the window
262 // gets first hidden and then shown again.
263 window2->Hide();
264 window2->SetBounds(gfx::Rect(250, 48, 150, 300));
265 window2->Show();
266
267 // |window1| should be flush left and |window2| flush right.
268 EXPECT_EQ(
269 base::IntToString(docked_width(manager) + min_dock_gap()) + ",32 231x320",
270 window1->bounds().ToString());
271 EXPECT_EQ(
272 base::IntToString(desktop_area.width() - window2->bounds().width()) +
273 ",48 150x300",
274 window2->bounds().ToString());
275 }
276
277 // Tests that with a window docked on the right the auto-placing logic in
278 // RearrangeVisibleWindowOnShow places windows flush with work area edges.
279 TEST_P(DockedWindowLayoutManagerTest, AutoPlacingRight) {
280 gfx::Rect bounds(0, 0, 201, 201);
281 std::unique_ptr<aura::Window> window(CreateTestWindow(bounds));
282 DragRelativeToEdge(DOCKED_EDGE_RIGHT, window.get(), 0);
283
284 // The window should be attached and snapped to the right side of the screen.
285 EXPECT_EQ(window->GetRootWindow()->bounds().right(),
286 window->GetBoundsInScreen().right());
287 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
288
289 DockedWindowLayoutManager* manager =
290 DockedWindowLayoutManager::Get(WmWindow::Get(window.get()));
291
292 // Create two additional windows and test their auto-placement
293 std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
294 gfx::Rect desktop_area = window1->parent()->bounds();
295 wm::GetWindowState(window1.get())->set_window_position_managed(true);
296 window1->Hide();
297 window1->SetBounds(gfx::Rect(16, 32, 231, 320));
298 window1->Show();
299
300 // |window1| should be centered in work area.
301 EXPECT_EQ(base::IntToString((desktop_area.width() - docked_width(manager) -
302 min_dock_gap() - window1->bounds().width()) /
303 2) +
304 ",32 231x320",
305 window1->bounds().ToString());
306
307 std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
308 wm::GetWindowState(window2.get())->set_window_position_managed(true);
309 // To avoid any auto window manager changes due to SetBounds, the window
310 // gets first hidden and then shown again.
311 window2->Hide();
312 window2->SetBounds(gfx::Rect(32, 48, 256, 512));
313 window2->Show();
314
315 // |window1| should be flush left and |window2| flush right.
316 EXPECT_EQ("0,32 231x320", window1->bounds().ToString());
317 EXPECT_EQ(base::IntToString(desktop_area.width() - window2->bounds().width() -
318 docked_width(manager) - min_dock_gap()) +
319 ",48 256x512",
320 window2->bounds().ToString());
321 }
322
323 // Tests that with a window docked on the right the auto-placing logic in
324 // RearrangeVisibleWindowOnShow places windows flush with work area edges.
325 // Test case for the secondary screen.
326 TEST_P(DockedWindowLayoutManagerTest, AutoPlacingRightSecondScreen) {
327 // TODO: investigate failure in mash. http://crbug.com/698049.
328 if (WmShell::Get()->IsRunningInMash())
329 return;
330
331 // Create a dual screen layout.
332 UpdateDisplay("600x600,600x600");
333
334 gfx::Rect bounds(600, 0, 201, 201);
335 std::unique_ptr<aura::Window> window(CreateTestWindow(bounds));
336 // Drag pointer to the right edge of the second screen.
337 DragRelativeToEdge(DOCKED_EDGE_RIGHT, window.get(), 0);
338
339 // The window should be attached and snapped to the right side of the screen.
340 EXPECT_EQ(window->GetRootWindow()->GetBoundsInScreen().right(),
341 window->GetBoundsInScreen().right());
342 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
343
344 DockedWindowLayoutManager* manager =
345 DockedWindowLayoutManager::Get(WmWindow::Get(window.get()));
346
347 // Create two additional windows and test their auto-placement
348 bounds = gfx::Rect(616, 32, 231, 320);
349 std::unique_ptr<aura::Window> window1(
350 CreateTestWindowInShellWithDelegate(nullptr, 1, bounds));
351 gfx::Rect desktop_area = window1->parent()->bounds();
352 wm::GetWindowState(window1.get())->set_window_position_managed(true);
353 window1->Hide();
354 window1->Show();
355
356 // |window1| should be centered in work area.
357 EXPECT_EQ(base::IntToString(600 +
358 (desktop_area.width() - docked_width(manager) -
359 min_dock_gap() - window1->bounds().width()) /
360 2) +
361 ",32 231x320",
362 window1->GetBoundsInScreen().ToString());
363
364 bounds = gfx::Rect(632, 48, 256, 512);
365 std::unique_ptr<aura::Window> window2(
366 CreateTestWindowInShellWithDelegate(nullptr, 2, bounds));
367 wm::GetWindowState(window2.get())->set_window_position_managed(true);
368 // To avoid any auto window manager changes due to SetBounds, the window
369 // gets first hidden and then shown again.
370 window2->Hide();
371 window2->Show();
372
373 // |window1| should be flush left and |window2| flush right.
374 EXPECT_EQ("600,32 231x320", window1->GetBoundsInScreen().ToString());
375 EXPECT_EQ(
376 base::IntToString(600 + desktop_area.width() - window2->bounds().width() -
377 docked_width(manager) - min_dock_gap()) +
378 ",48 256x512",
379 window2->GetBoundsInScreen().ToString());
380 }
381
382 // Adds two windows and tests that the gaps are evenly distributed.
383 TEST_P(DockedWindowLayoutManagerTest, AddTwoWindows) {
384 std::unique_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
385 std::unique_ptr<aura::Window> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 202)));
386 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
387 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 300);
388
389 // The windows should be attached and snapped to the right side of the screen.
390 EXPECT_EQ(w1->GetRootWindow()->bounds().right(),
391 w1->GetBoundsInScreen().right());
392 EXPECT_EQ(kShellWindowId_DockedContainer, w1->parent()->id());
393 EXPECT_EQ(w2->GetRootWindow()->bounds().right(),
394 w2->GetBoundsInScreen().right());
395 EXPECT_EQ(kShellWindowId_DockedContainer, w2->parent()->id());
396
397 // Test that the gaps differ at most by a single pixel.
398 gfx::Rect work_area = display::Screen::GetScreen()
399 ->GetDisplayNearestWindow(w1.get())
400 .work_area();
401 int gap1 = w1->GetBoundsInScreen().y();
402 int gap2 = w2->GetBoundsInScreen().y() - w1->GetBoundsInScreen().bottom();
403 int gap3 = work_area.bottom() - w2->GetBoundsInScreen().bottom();
404 EXPECT_EQ(0, gap1);
405 EXPECT_NEAR(gap2, min_dock_gap(), 1);
406 EXPECT_EQ(0, gap3);
407 }
408
409 // Adds two non-overlapping windows and tests layout after a drag.
410 TEST_P(DockedWindowLayoutManagerTest, TwoWindowsDragging) {
411 std::unique_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
412 std::unique_ptr<aura::Window> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 202)));
413 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
414 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 300);
415
416 // The windows should be attached and snapped to the right side of the screen.
417 EXPECT_EQ(w1->GetRootWindow()->bounds().right(),
418 w1->GetBoundsInScreen().right());
419 EXPECT_EQ(kShellWindowId_DockedContainer, w1->parent()->id());
420 EXPECT_EQ(w2->GetRootWindow()->bounds().right(),
421 w2->GetBoundsInScreen().right());
422 EXPECT_EQ(kShellWindowId_DockedContainer, w2->parent()->id());
423
424 // Drag w2 above w1.
425 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromwindowOrigin(w2.get(), 0, 20));
426 DragMove(0, -w2->bounds().height() / 2 - min_dock_gap() - 1);
427 DragEnd();
428
429 // Test the new windows order and that the gaps differ at most by a pixel.
430 gfx::Rect work_area = display::Screen::GetScreen()
431 ->GetDisplayNearestWindow(w1.get())
432 .work_area();
433 int gap1 = w2->GetBoundsInScreen().y() - work_area.y();
434 int gap2 = w1->GetBoundsInScreen().y() - w2->GetBoundsInScreen().bottom();
435 int gap3 = work_area.bottom() - w1->GetBoundsInScreen().bottom();
436 EXPECT_EQ(0, gap1);
437 EXPECT_NEAR(gap2, min_dock_gap(), 1);
438 EXPECT_EQ(0, gap3);
439 }
440
441 // Adds three overlapping windows and tests layout after a drag.
442 TEST_P(DockedWindowLayoutManagerTest, ThreeWindowsDragging) {
443 UpdateDisplay("600x1000");
444
445 std::unique_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 310)));
446 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
447 std::unique_ptr<aura::Window> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 310)));
448 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 500);
449 std::unique_ptr<aura::Window> w3(CreateTestWindow(gfx::Rect(0, 0, 220, 310)));
450 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w3.get(), 600);
451
452 // All windows should be attached and snapped to the right side of the screen.
453 EXPECT_EQ(w1->GetRootWindow()->bounds().right(),
454 w1->GetBoundsInScreen().right());
455 EXPECT_EQ(kShellWindowId_DockedContainer, w1->parent()->id());
456 EXPECT_EQ(w2->GetRootWindow()->bounds().right(),
457 w2->GetBoundsInScreen().right());
458 EXPECT_EQ(kShellWindowId_DockedContainer, w2->parent()->id());
459 EXPECT_EQ(w3->GetRootWindow()->bounds().right(),
460 w3->GetBoundsInScreen().right());
461 EXPECT_EQ(kShellWindowId_DockedContainer, w3->parent()->id());
462
463 // Test that the top and bottom windows are clamped in work area and
464 // that the gaps between the windows differ at most by a pixel.
465 gfx::Rect work_area = display::Screen::GetScreen()
466 ->GetDisplayNearestWindow(w1.get())
467 .work_area();
468 int gap1 = w1->GetBoundsInScreen().y() - work_area.y();
469 int gap2 = w2->GetBoundsInScreen().y() - w1->GetBoundsInScreen().bottom();
470 int gap3 = w3->GetBoundsInScreen().y() - w2->GetBoundsInScreen().bottom();
471 int gap4 = work_area.bottom() - w3->GetBoundsInScreen().bottom();
472 EXPECT_EQ(0, gap1);
473 EXPECT_NEAR(gap2, min_dock_gap(), 1);
474 EXPECT_NEAR(gap3, min_dock_gap(), 1);
475 EXPECT_EQ(0, gap4);
476
477 // Drag w1 below the point where w1 and w2 would swap places. This point is
478 // half way between the tops of those two windows.
479 // A bit more vertical drag is needed to account for a window bounds changing
480 // to its restore bounds during the drag.
481 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromwindowOrigin(w1.get(), 0, 20));
482 DragMove(0, min_dock_gap() + w2->bounds().height() / 2 + 10);
483
484 // During the drag the windows get rearranged and the top and the bottom
485 // should be limited by the work area.
486 EXPECT_EQ(work_area.y(), w2->GetBoundsInScreen().y());
487 EXPECT_GT(w1->GetBoundsInScreen().y(), w2->GetBoundsInScreen().y());
488 EXPECT_EQ(work_area.bottom(), w3->GetBoundsInScreen().bottom());
489 DragEnd();
490
491 // Test the new windows order and that the gaps differ at most by a pixel.
492 gap1 = w2->GetBoundsInScreen().y() - work_area.y();
493 gap2 = w1->GetBoundsInScreen().y() - w2->GetBoundsInScreen().bottom();
494 gap3 = w3->GetBoundsInScreen().y() - w1->GetBoundsInScreen().bottom();
495 gap4 = work_area.bottom() - w3->GetBoundsInScreen().bottom();
496 EXPECT_EQ(0, gap1);
497 EXPECT_NEAR(gap2, min_dock_gap(), 1);
498 EXPECT_NEAR(gap3, min_dock_gap(), 1);
499 EXPECT_EQ(0, gap4);
500 }
501
502 // Adds three windows in bottom display and tests layout after a drag.
503 TEST_P(DockedWindowLayoutManagerTest, ThreeWindowsDraggingSecondScreen) {
504 // TODO: SetLayoutForCurrentDisplays() needs to ported to mash.
505 // http://crbug.com/698043.
506 if (WmShell::Get()->IsRunningInMash())
507 return;
508
509 // Create two screen vertical layout.
510 UpdateDisplay("600x1000,600x1000");
511 // Layout the secondary display to the bottom of the primary.
512 ASSERT_GT(display::Screen::GetScreen()->GetNumDisplays(), 1);
513 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
514 display::test::CreateDisplayLayout(display_manager(),
515 display::DisplayPlacement::BOTTOM, 0));
516
517 std::unique_ptr<aura::Window> w1(
518 CreateTestWindow(gfx::Rect(0, 1000, 201, 310)));
519 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 1000 + 20);
520 std::unique_ptr<aura::Window> w2(
521 CreateTestWindow(gfx::Rect(0, 1000, 210, 310)));
522 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 1000 + 500);
523 std::unique_ptr<aura::Window> w3(
524 CreateTestWindow(gfx::Rect(0, 1000, 220, 310)));
525 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w3.get(), 1000 + 600);
526
527 // All windows should be attached and snapped to the right side of the screen.
528 EXPECT_EQ(w1->GetRootWindow()->bounds().right(),
529 w1->GetBoundsInScreen().right());
530 EXPECT_EQ(kShellWindowId_DockedContainer, w1->parent()->id());
531 EXPECT_EQ(w2->GetRootWindow()->bounds().right(),
532 w2->GetBoundsInScreen().right());
533 EXPECT_EQ(kShellWindowId_DockedContainer, w2->parent()->id());
534 EXPECT_EQ(w3->GetRootWindow()->bounds().right(),
535 w3->GetBoundsInScreen().right());
536 EXPECT_EQ(kShellWindowId_DockedContainer, w3->parent()->id());
537
538 gfx::Rect work_area = display::Screen::GetScreen()
539 ->GetDisplayNearestWindow(w1.get())
540 .work_area();
541 // Test that the top and bottom windows are clamped in work area and
542 // that the overlaps between the windows differ at most by a pixel.
543 int gap1 = w1->GetBoundsInScreen().y() - work_area.y();
544 int gap2 = w2->GetBoundsInScreen().y() - w1->GetBoundsInScreen().bottom();
545 int gap3 = w3->GetBoundsInScreen().y() - w2->GetBoundsInScreen().bottom();
546 int gap4 = work_area.bottom() - w3->GetBoundsInScreen().bottom();
547 EXPECT_EQ(0, gap1);
548 EXPECT_NEAR(gap2, min_dock_gap(), 1);
549 EXPECT_NEAR(gap3, min_dock_gap(), 1);
550 EXPECT_EQ(0, gap4);
551
552 // Drag w1 below the point where w1 and w2 would swap places. This point is
553 // half way between the tops of those two windows.
554 // A bit more vertical drag is needed to account for a window bounds changing
555 // to its restore bounds during the drag.
556 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromwindowOrigin(w1.get(), 0, 20));
557 DragMove(0, min_dock_gap() + w2->bounds().height() / 2 + 10);
558
559 // During the drag the windows get rearranged and the top and the bottom
560 // should be limited by the work area.
561 EXPECT_EQ(work_area.y(), w2->GetBoundsInScreen().y());
562 EXPECT_GT(w1->GetBoundsInScreen().y(), w2->GetBoundsInScreen().y());
563 EXPECT_EQ(work_area.bottom(), w3->GetBoundsInScreen().bottom());
564 DragEnd();
565
566 // Test the new windows order and that the overlaps differ at most by a pixel.
567 gap1 = w2->GetBoundsInScreen().y() - work_area.y();
568 gap2 = w1->GetBoundsInScreen().y() - w2->GetBoundsInScreen().bottom();
569 gap3 = w3->GetBoundsInScreen().y() - w1->GetBoundsInScreen().bottom();
570 gap4 = work_area.bottom() - w3->GetBoundsInScreen().bottom();
571 EXPECT_EQ(0, gap1);
572 EXPECT_NEAR(gap2, min_dock_gap(), 1);
573 EXPECT_NEAR(gap3, min_dock_gap(), 1);
574 EXPECT_EQ(0, gap4);
575 }
576
577 // Tests that a second window added to the dock is resized to match.
578 TEST_P(DockedWindowLayoutManagerTest, TwoWindowsWidthNew) {
579 std::unique_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
580 std::unique_ptr<aura::Window> w2(CreateTestWindow(gfx::Rect(0, 0, 280, 202)));
581 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
582 // The first window should get resized to ideal width.
583 EXPECT_EQ(ideal_width(), w1->bounds().width());
584
585 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 300);
586 // The second window should get resized to the existing dock.
587 EXPECT_EQ(ideal_width(), w2->bounds().width());
588 }
589
590 // Tests that a first non-resizable window added to the dock is not resized.
591 TEST_P(DockedWindowLayoutManagerTest, TwoWindowsWidthNonResizableFirst) {
592 std::unique_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
593 w1->SetProperty(aura::client::kResizeBehaviorKey,
594 ui::mojom::kResizeBehaviorNone);
595 std::unique_ptr<aura::Window> w2(CreateTestWindow(gfx::Rect(0, 0, 280, 202)));
596 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
597 // The first window should not get resized.
598 EXPECT_EQ(201, w1->bounds().width());
599
600 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 300);
601 // The second window should get resized to the first window's width.
602 EXPECT_EQ(w1->bounds().width(), w2->bounds().width());
603 }
604
605 // Tests that a second non-resizable window added to the dock is not resized.
606 TEST_P(DockedWindowLayoutManagerTest, TwoWindowsWidthNonResizableSecond) {
607 std::unique_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
608 std::unique_ptr<aura::Window> w2(CreateTestWindow(gfx::Rect(0, 0, 280, 202)));
609 w2->SetProperty(aura::client::kResizeBehaviorKey,
610 ui::mojom::kResizeBehaviorNone);
611 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
612 // The first window should get resized to ideal width.
613 EXPECT_EQ(ideal_width(), w1->bounds().width());
614
615 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 300);
616 // The second window should not get resized.
617 EXPECT_EQ(280, w2->bounds().width());
618
619 // The first window should get resized again - to match the second window.
620 EXPECT_EQ(w1->bounds().width(), w2->bounds().width());
621 }
622
623 // Test that restrictions on minimum and maximum width of windows are honored.
624 TEST_P(DockedWindowLayoutManagerTest, TwoWindowsWidthRestrictions) {
625 aura::test::TestWindowDelegate delegate1;
626 delegate1.set_maximum_size(gfx::Size(240, 0));
627 std::unique_ptr<aura::Window> w1(
628 CreateTestWindowWithDelegate(gfx::Rect(0, 0, 201, 201), &delegate1));
629 aura::test::TestWindowDelegate delegate2;
630 delegate2.set_minimum_size(gfx::Size(260, 0));
631 std::unique_ptr<aura::Window> w2(
632 CreateTestWindowWithDelegate(gfx::Rect(0, 0, 280, 202), &delegate2));
633 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
634 // The first window should get resized to its maximum width.
635 EXPECT_EQ(240, w1->bounds().width());
636
637 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 300);
638 // The second window should get resized to its minimum width.
639 EXPECT_EQ(260, w2->bounds().width());
640
641 // The first window should be centered relative to the second.
642 EXPECT_EQ(w1->bounds().CenterPoint().x(), w2->bounds().CenterPoint().x());
643 }
644
645 // Test that restrictions on minimum width of windows are honored.
646 TEST_P(DockedWindowLayoutManagerTest, WidthMoreThanMax) {
647 aura::test::TestWindowDelegate delegate;
648 delegate.set_minimum_size(gfx::Size(400, 0));
649 std::unique_ptr<aura::Window> window(
650 CreateTestWindowWithDelegate(gfx::Rect(0, 0, 400, 201), &delegate));
651 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, window.get(), 20);
652
653 // Secondary drag ensures that we are testing the minimum size restriction
654 // and not just failure to get past the tiling step in SnapSizer.
655 ASSERT_NO_FATAL_FAILURE(
656 DragStartAtOffsetFromwindowOrigin(window.get(), 25, 5));
657 DragMove(150, 0);
658 DragEnd();
659
660 // The window should not get docked even though it is dragged past the edge.
661 EXPECT_NE(window->GetRootWindow()->bounds().right(),
662 window->GetBoundsInScreen().right());
663 EXPECT_NE(kShellWindowId_DockedContainer, window->parent()->id());
664 }
665
666 // Docks three windows and tests that the very first window gets minimized.
667 TEST_P(DockedWindowLayoutManagerTest, ThreeWindowsMinimize) {
668 std::unique_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
669 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
670 std::unique_ptr<aura::Window> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 202)));
671 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 200);
672 std::unique_ptr<aura::Window> w3(CreateTestWindow(gfx::Rect(0, 0, 220, 204)));
673 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w3.get(), 300);
674
675 // The last two windows should be attached and snapped to the right edge.
676 EXPECT_EQ(w2->GetRootWindow()->bounds().right(),
677 w2->GetBoundsInScreen().right());
678 EXPECT_EQ(kShellWindowId_DockedContainer, w2->parent()->id());
679 EXPECT_EQ(w3->GetRootWindow()->bounds().right(),
680 w3->GetBoundsInScreen().right());
681 EXPECT_EQ(kShellWindowId_DockedContainer, w3->parent()->id());
682
683 // The first window should get hidden but parented by the dock container.
684 EXPECT_TRUE(wm::GetWindowState(w1.get())->IsMinimized());
685 EXPECT_TRUE(wm::GetWindowState(w1.get())->IsDocked());
686 EXPECT_FALSE(w1->IsVisible());
687 EXPECT_EQ(ui::SHOW_STATE_MINIMIZED,
688 w1->GetProperty(aura::client::kShowStateKey));
689 EXPECT_EQ(ui::SHOW_STATE_DOCKED,
690 w1->GetProperty(aura::client::kPreMinimizedShowStateKey));
691 // The other two windows should be still docked.
692 EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMinimized());
693 EXPECT_TRUE(wm::GetWindowState(w2.get())->IsDocked());
694 EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMinimized());
695 EXPECT_TRUE(wm::GetWindowState(w3.get())->IsDocked());
696 EXPECT_EQ(kShellWindowId_DockedContainer, w1->parent()->id());
697 }
698
699 // Docks up to three windows and tests that they split vertical space.
700 TEST_P(DockedWindowLayoutManagerTest, ThreeWindowsSplitHeightEvenly) {
701 UpdateDisplay("600x1000");
702 std::unique_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
703 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
704 std::unique_ptr<aura::Window> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 202)));
705 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 200);
706
707 // The two windows should be attached and snapped to the right edge.
708 EXPECT_EQ(w1->GetRootWindow()->bounds().right(),
709 w1->GetBoundsInScreen().right());
710 EXPECT_EQ(kShellWindowId_DockedContainer, w1->parent()->id());
711 EXPECT_EQ(w2->GetRootWindow()->bounds().right(),
712 w2->GetBoundsInScreen().right());
713 EXPECT_EQ(kShellWindowId_DockedContainer, w2->parent()->id());
714
715 // The two windows should be same size vertically and almost 1/2 of work area.
716 gfx::Rect work_area = display::Screen::GetScreen()
717 ->GetDisplayNearestWindow(w1.get())
718 .work_area();
719 EXPECT_NEAR(w1->GetBoundsInScreen().height(),
720 w2->GetBoundsInScreen().height(), 1);
721 EXPECT_NEAR(work_area.height() / 2, w1->GetBoundsInScreen().height(),
722 min_dock_gap() * 2);
723
724 // Create and dock the third window.
725 std::unique_ptr<aura::Window> w3(CreateTestWindow(gfx::Rect(0, 0, 220, 204)));
726 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w3.get(), 300);
727
728 // All three windows should be docked and snapped to the right edge.
729 EXPECT_EQ(kShellWindowId_DockedContainer, w1->parent()->id());
730 EXPECT_EQ(kShellWindowId_DockedContainer, w2->parent()->id());
731 EXPECT_EQ(kShellWindowId_DockedContainer, w3->parent()->id());
732
733 // All windows should be near same size vertically and about 1/3 of work area.
734 EXPECT_NEAR(w1->GetBoundsInScreen().height(),
735 w2->GetBoundsInScreen().height(), 1);
736 EXPECT_NEAR(w2->GetBoundsInScreen().height(),
737 w3->GetBoundsInScreen().height(), 1);
738 EXPECT_NEAR(work_area.height() / 3, w1->GetBoundsInScreen().height(),
739 min_dock_gap() * 2);
740 }
741
742 // Docks two windows and tests that restrictions on vertical size are honored.
743 TEST_P(DockedWindowLayoutManagerTest, TwoWindowsHeightRestrictions) {
744 // The first window is fixed height.
745 aura::test::TestWindowDelegate delegate1;
746 delegate1.set_minimum_size(gfx::Size(0, 300));
747 delegate1.set_maximum_size(gfx::Size(0, 300));
748 std::unique_ptr<aura::Window> w1(
749 CreateTestWindowWithDelegate(gfx::Rect(0, 0, 201, 300), &delegate1));
750 // The second window has maximum height.
751 aura::test::TestWindowDelegate delegate2;
752 delegate2.set_maximum_size(gfx::Size(0, 100));
753 std::unique_ptr<aura::Window> w2(
754 CreateTestWindowWithDelegate(gfx::Rect(0, 0, 280, 90), &delegate2));
755
756 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20);
757 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w2.get(), 200);
758
759 // The two windows should be attached and snapped to the right edge.
760 EXPECT_EQ(w1->GetRootWindow()->bounds().right(),
761 w1->GetBoundsInScreen().right());
762 EXPECT_EQ(kShellWindowId_DockedContainer, w1->parent()->id());
763 EXPECT_EQ(w2->GetRootWindow()->bounds().right(),
764 w2->GetBoundsInScreen().right());
765 EXPECT_EQ(kShellWindowId_DockedContainer, w2->parent()->id());
766
767 // The two windows should have their heights restricted.
768 EXPECT_EQ(300, w1->GetBoundsInScreen().height());
769 EXPECT_EQ(100, w2->GetBoundsInScreen().height());
770
771 // w1 should be more than half of the work area height (even with a margin).
772 // w2 should be less than half of the work area height (even with a margin).
773 gfx::Rect work_area = display::Screen::GetScreen()
774 ->GetDisplayNearestWindow(w1.get())
775 .work_area();
776 EXPECT_GT(w1->GetBoundsInScreen().height(), work_area.height() / 2 + 10);
777 EXPECT_LT(w2->GetBoundsInScreen().height(), work_area.height() / 2 - 10);
778 }
779
780 // Tests that a docked window is moved to primary display when secondary display
781 // is disconnected and that it stays docked and properly positioned.
782 TEST_P(DockedWindowLayoutManagerTest, DisplayDisconnectionMovesDocked) {
783 // TODO: investigate failure in mash. http://crbug.com/698049.
784 if (WmShell::Get()->IsRunningInMash())
785 return;
786
787 // Create a dual screen layout.
788 UpdateDisplay("600x700,800x600");
789
790 gfx::Rect bounds(600, 0, 201, 201);
791 std::unique_ptr<aura::Window> window(CreateTestWindow(bounds));
792 // Drag pointer to the right edge of the second screen.
793 DragRelativeToEdge(DOCKED_EDGE_RIGHT, window.get(), 0);
794
795 // Simulate disconnection of the secondary display.
796 UpdateDisplay("600x700");
797
798 // The window should be still docked at the right edge.
799 // Its height should grow to match the new work area.
800 EXPECT_EQ(window->GetRootWindow()->bounds().right(),
801 window->GetBoundsInScreen().right());
802 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
803 EXPECT_EQ(ideal_width(), window->bounds().width());
804 gfx::Rect work_area = display::Screen::GetScreen()
805 ->GetDisplayNearestWindow(window.get())
806 .work_area();
807 EXPECT_EQ(work_area.height(), window->GetBoundsInScreen().height());
808 }
809
810 // Tests run twice - on both panels and normal windows
811 INSTANTIATE_TEST_CASE_P(NormalOrPanel,
812 DockedWindowLayoutManagerTest,
813 testing::Values(ui::wm::WINDOW_TYPE_NORMAL,
814 ui::wm::WINDOW_TYPE_PANEL));
815
816 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc ('k') | ash/wm/dock/docked_window_resizer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698