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

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

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

Powered by Google App Engine
This is Rietveld 408576698