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

Side by Side Diff: ash/wm/workspace/workspace_manager2_unittest.cc

Issue 11293014: Renames Workspace*2 -> Workspace*. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « ash/wm/workspace/workspace_manager2.cc ('k') | ash/wm/workspace/workspace_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/workspace/workspace_manager2.h"
6
7 #include "ash/ash_switches.h"
8 #include "ash/root_window_controller.h"
9 #include "ash/screen_ash.h"
10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h"
12 #include "ash/system/status_area_widget.h"
13 #include "ash/test/ash_test_base.h"
14 #include "ash/wm/activation_controller.h"
15 #include "ash/wm/property_util.h"
16 #include "ash/wm/shelf_layout_manager.h"
17 #include "ash/wm/window_properties.h"
18 #include "ash/wm/window_util.h"
19 #include "ash/wm/workspace/workspace2.h"
20 #include "ash/wm/workspace_controller_test_helper.h"
21 #include "base/command_line.h"
22 #include "base/string_number_conversions.h"
23 #include "ui/aura/client/aura_constants.h"
24 #include "ui/aura/root_window.h"
25 #include "ui/aura/test/event_generator.h"
26 #include "ui/aura/test/test_window_delegate.h"
27 #include "ui/aura/test/test_windows.h"
28 #include "ui/aura/window.h"
29 #include "ui/base/ui_base_types.h"
30 #include "ui/compositor/layer.h"
31 #include "ui/gfx/screen.h"
32 #include "ui/views/widget/widget.h"
33
34 using aura::Window;
35
36 namespace ash {
37 namespace internal {
38
39 class WorkspaceManager2Test : public test::AshTestBase {
40 public:
41 WorkspaceManager2Test() : manager_(NULL) {}
42 virtual ~WorkspaceManager2Test() {}
43
44 aura::Window* CreateTestWindowUnparented() {
45 aura::Window* window = new aura::Window(NULL);
46 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
47 window->SetType(aura::client::WINDOW_TYPE_NORMAL);
48 window->Init(ui::LAYER_TEXTURED);
49 return window;
50 }
51
52 aura::Window* CreateTestWindow() {
53 aura::Window* window = new aura::Window(NULL);
54 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
55 window->SetType(aura::client::WINDOW_TYPE_NORMAL);
56 window->Init(ui::LAYER_TEXTURED);
57 window->SetParent(NULL);
58 return window;
59 }
60
61 aura::Window* GetViewport() {
62 return Shell::GetContainer(Shell::GetPrimaryRootWindow(),
63 kShellWindowId_DefaultContainer);
64 }
65
66 const std::vector<Workspace2*>& workspaces() const {
67 return manager_->workspaces_;
68 }
69
70 gfx::Rect GetFullscreenBounds(aura::Window* window) {
71 return Shell::GetScreen()->GetDisplayNearestWindow(window).bounds();
72 }
73
74 Workspace2* active_workspace() {
75 return manager_->active_workspace_;
76 }
77
78 ShelfLayoutManager* shelf_layout_manager() {
79 return Shell::GetPrimaryRootWindowController()->shelf();
80 }
81
82 bool GetWindowOverlapsShelf() {
83 return shelf_layout_manager()->window_overlaps_shelf();
84 }
85
86 Workspace2* FindBy(aura::Window* window) const {
87 return manager_->FindBy(window);
88 }
89
90 std::string WorkspaceStateString(Workspace2* workspace) {
91 return (workspace->is_maximized() ? "M" : "") +
92 base::IntToString(static_cast<int>(
93 workspace->window()->children().size()));
94 }
95
96 int active_index() {
97 return static_cast<int>(
98 manager_->FindWorkspace(manager_->active_workspace_) -
99 manager_->workspaces_.begin());
100 }
101
102 std::string StateString() {
103 std::string result;
104 for (size_t i = 0; i < manager_->workspaces_.size(); ++i) {
105 if (i > 0)
106 result += " ";
107 result += WorkspaceStateString(manager_->workspaces_[i]);
108 }
109
110 if (!manager_->pending_workspaces_.empty()) {
111 result += " P=";
112 for (std::set<Workspace2*>::const_iterator i =
113 manager_->pending_workspaces_.begin();
114 i != manager_->pending_workspaces_.end(); ++i) {
115 if (i != manager_->pending_workspaces_.begin())
116 result += " ";
117 result += WorkspaceStateString(*i);
118 }
119 }
120
121 result += " active=" + base::IntToString(active_index());
122 return result;
123 }
124
125 // Overridden from AshTestBase:
126 virtual void SetUp() OVERRIDE {
127 test::AshTestBase::SetUp();
128 WorkspaceControllerTestHelper workspace_helper(
129 Shell::TestApi(Shell::GetInstance()).workspace_controller());
130 manager_ = workspace_helper.workspace_manager2();
131 }
132
133 virtual void TearDown() OVERRIDE {
134 manager_ = NULL;
135 test::AshTestBase::TearDown();
136 }
137
138 protected:
139 WorkspaceManager2* manager_;
140
141 private:
142 scoped_ptr<ActivationController> activation_controller_;
143
144 DISALLOW_COPY_AND_ASSIGN(WorkspaceManager2Test);
145 };
146
147 // Assertions around adding a normal window.
148 TEST_F(WorkspaceManager2Test, AddNormalWindowWhenEmpty) {
149 scoped_ptr<Window> w1(CreateTestWindow());
150 w1->SetBounds(gfx::Rect(0, 0, 250, 251));
151
152 EXPECT_TRUE(GetRestoreBoundsInScreen(w1.get()) == NULL);
153
154 w1->Show();
155
156 EXPECT_TRUE(GetRestoreBoundsInScreen(w1.get()) == NULL);
157
158 ASSERT_TRUE(w1->layer() != NULL);
159 EXPECT_TRUE(w1->layer()->visible());
160
161 EXPECT_EQ("0,0 250x251", w1->bounds().ToString());
162
163 // Should be 1 workspace for the desktop, not maximized.
164 ASSERT_EQ("1 active=0", StateString());
165 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
166 }
167
168 // Assertions around maximizing/unmaximizing.
169 TEST_F(WorkspaceManager2Test, SingleMaximizeWindow) {
170 scoped_ptr<Window> w1(CreateTestWindow());
171 w1->SetBounds(gfx::Rect(0, 0, 250, 251));
172
173 w1->Show();
174 wm::ActivateWindow(w1.get());
175
176 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
177
178 ASSERT_TRUE(w1->layer() != NULL);
179 EXPECT_TRUE(w1->layer()->visible());
180
181 EXPECT_EQ("0,0 250x251", w1->bounds().ToString());
182
183 // Maximize the window.
184 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
185
186 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
187
188 // Should be 2 workspaces, the second maximized with w1.
189 ASSERT_EQ("0 M1 active=1", StateString());
190 EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
191 EXPECT_EQ(ScreenAsh::GetMaximizedWindowBoundsInParent(w1.get()).width(),
192 w1->bounds().width());
193 EXPECT_EQ(ScreenAsh::GetMaximizedWindowBoundsInParent(w1.get()).height(),
194 w1->bounds().height());
195
196 // Restore the window.
197 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
198
199 // Should be 1 workspace for the desktop.
200 ASSERT_EQ("1 active=0", StateString());
201 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
202 EXPECT_EQ("0,0 250x251", w1->bounds().ToString());
203 }
204
205 // Assertions around closing the last window in a workspace.
206 TEST_F(WorkspaceManager2Test, CloseLastWindowInWorkspace) {
207 scoped_ptr<Window> w1(CreateTestWindow());
208 scoped_ptr<Window> w2(CreateTestWindow());
209 w1->SetBounds(gfx::Rect(0, 0, 250, 251));
210 w1->Show();
211 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
212 w2->Show();
213 wm::ActivateWindow(w1.get());
214
215 // Should be 1 workspace and 1 pending, !maximized and maximized. The second
216 // workspace is pending since the window wasn't active.
217 ASSERT_EQ("1 P=M1 active=0", StateString());
218 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
219
220 // Close w2.
221 w2.reset();
222
223 // Should have one workspace.
224 ASSERT_EQ("1 active=0", StateString());
225 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
226 EXPECT_TRUE(w1->IsVisible());
227 }
228
229 // Assertions around adding a maximized window when empty.
230 TEST_F(WorkspaceManager2Test, AddMaximizedWindowWhenEmpty) {
231 scoped_ptr<Window> w1(CreateTestWindow());
232 w1->SetBounds(gfx::Rect(0, 0, 250, 251));
233 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
234 w1->Show();
235 wm::ActivateWindow(w1.get());
236
237 ASSERT_TRUE(w1->layer() != NULL);
238 EXPECT_TRUE(w1->layer()->visible());
239 gfx::Rect work_area(
240 ScreenAsh::GetMaximizedWindowBoundsInParent(w1.get()));
241 EXPECT_EQ(work_area.width(), w1->bounds().width());
242 EXPECT_EQ(work_area.height(), w1->bounds().height());
243
244 // Should be 2 workspaces (since we always keep the desktop).
245 ASSERT_EQ("0 M1 active=1", StateString());
246 EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
247 }
248
249 // Assertions around two windows and toggling one to be maximized.
250 TEST_F(WorkspaceManager2Test, MaximizeWithNormalWindow) {
251 scoped_ptr<Window> w1(CreateTestWindow());
252 scoped_ptr<Window> w2(CreateTestWindow());
253 w1->SetBounds(gfx::Rect(0, 0, 250, 251));
254 w1->Show();
255
256 ASSERT_TRUE(w1->layer() != NULL);
257 EXPECT_TRUE(w1->layer()->visible());
258
259 w2->SetBounds(gfx::Rect(0, 0, 50, 51));
260 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
261 w2->Show();
262 wm::ActivateWindow(w2.get());
263
264 // Should now be two workspaces.
265 ASSERT_EQ("1 M1 active=1", StateString());
266 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
267 EXPECT_EQ(w2.get(), workspaces()[1]->window()->children()[0]);
268
269 gfx::Rect work_area(ScreenAsh::GetMaximizedWindowBoundsInParent(w1.get()));
270 EXPECT_EQ(work_area.width(), w2->bounds().width());
271 EXPECT_EQ(work_area.height(), w2->bounds().height());
272
273 // Restore w2, which should then go back to one workspace.
274 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
275 ASSERT_EQ("2 active=0", StateString());
276 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
277 EXPECT_EQ(w2.get(), workspaces()[0]->window()->children()[1]);
278 EXPECT_EQ(50, w2->bounds().width());
279 EXPECT_EQ(51, w2->bounds().height());
280 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
281 }
282
283 // Assertions around two maximized windows.
284 TEST_F(WorkspaceManager2Test, TwoMaximized) {
285 scoped_ptr<Window> w1(CreateTestWindow());
286 scoped_ptr<Window> w2(CreateTestWindow());
287 w1->SetBounds(gfx::Rect(0, 0, 250, 251));
288 w1->Show();
289 wm::ActivateWindow(w1.get());
290 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
291 ASSERT_EQ("1 M1 active=1", StateString());
292
293 w2->SetBounds(gfx::Rect(0, 0, 50, 51));
294 w2->Show();
295 wm::ActivateWindow(w2.get());
296 ASSERT_EQ("1 M1 active=0", StateString());
297
298 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
299 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
300 ASSERT_EQ("0 M1 M1 active=2", StateString());
301
302 // The last stacked window (|w2|) should be last since it was maximized last.
303 EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
304 EXPECT_EQ(w2.get(), workspaces()[2]->window()->children()[0]);
305 }
306
307 // Makes sure requests to change the bounds of a normal window go through.
308 TEST_F(WorkspaceManager2Test, ChangeBoundsOfNormalWindow) {
309 scoped_ptr<Window> w1(CreateTestWindow());
310 w1->Show();
311
312 // Setting the bounds should go through since the window is in the normal
313 // workspace.
314 w1->SetBounds(gfx::Rect(0, 0, 200, 500));
315 EXPECT_EQ(200, w1->bounds().width());
316 EXPECT_EQ(500, w1->bounds().height());
317 }
318
319 // Verifies the bounds is not altered when showing and grid is enabled.
320 TEST_F(WorkspaceManager2Test, SnapToGrid) {
321 scoped_ptr<Window> w1(CreateTestWindowUnparented());
322 w1->SetBounds(gfx::Rect(1, 6, 25, 30));
323 w1->SetParent(NULL);
324 // We are not aligning this anymore this way. When the window gets shown
325 // the window is expected to be handled differently, but this cannot be
326 // tested with this test. So the result of this test should be that the
327 // bounds are exactly as passed in.
328 EXPECT_EQ("1,6 25x30", w1->bounds().ToString());
329 }
330
331 // Assertions around a fullscreen window.
332 TEST_F(WorkspaceManager2Test, SingleFullscreenWindow) {
333 scoped_ptr<Window> w1(CreateTestWindow());
334 w1->SetBounds(gfx::Rect(0, 0, 250, 251));
335 // Make the window fullscreen.
336 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
337 w1->Show();
338 wm::ActivateWindow(w1.get());
339
340 // Should be 2 workspaces, normal and maximized.
341 ASSERT_EQ("0 M1 active=1", StateString());
342 EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
343 EXPECT_EQ(GetFullscreenBounds(w1.get()).width(), w1->bounds().width());
344 EXPECT_EQ(GetFullscreenBounds(w1.get()).height(), w1->bounds().height());
345
346 // Restore the window. Use SHOW_STATE_DEFAULT as that is what we'll end up
347 // with when using views::Widget.
348 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_DEFAULT);
349 EXPECT_EQ("0,0 250x251", w1->bounds().ToString());
350
351 // Should be 1 workspace for the desktop.
352 ASSERT_EQ("1 active=0", StateString());
353 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
354 EXPECT_EQ(250, w1->bounds().width());
355 EXPECT_EQ(251, w1->bounds().height());
356
357 // Back to fullscreen.
358 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
359 ASSERT_EQ("0 M1 active=1", StateString());
360 EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
361 EXPECT_EQ(GetFullscreenBounds(w1.get()).width(), w1->bounds().width());
362 EXPECT_EQ(GetFullscreenBounds(w1.get()).height(), w1->bounds().height());
363 ASSERT_TRUE(GetRestoreBoundsInScreen(w1.get()));
364 EXPECT_EQ("0,0 250x251", GetRestoreBoundsInScreen(w1.get())->ToString());
365 }
366
367 // Makes sure switching workspaces doesn't show transient windows.
368 TEST_F(WorkspaceManager2Test, DontShowTransientsOnSwitch) {
369 scoped_ptr<Window> w1(CreateTestWindow());
370 scoped_ptr<Window> w2(CreateTestWindow());
371
372 w1->SetBounds(gfx::Rect(0, 0, 250, 251));
373 w2->SetBounds(gfx::Rect(0, 0, 250, 251));
374 w1->AddTransientChild(w2.get());
375
376 w1->Show();
377
378 scoped_ptr<Window> w3(CreateTestWindow());
379 w3->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
380 w3->Show();
381 wm::ActivateWindow(w3.get());
382
383 EXPECT_FALSE(w1->layer()->IsDrawn());
384 EXPECT_FALSE(w2->layer()->IsDrawn());
385 EXPECT_TRUE(w3->layer()->IsDrawn());
386
387 wm::ActivateWindow(w1.get());
388 EXPECT_TRUE(w1->layer()->IsDrawn());
389 EXPECT_FALSE(w2->layer()->IsDrawn());
390 EXPECT_FALSE(w3->layer()->IsDrawn());
391 }
392
393 // Assertions around minimizing a single window.
394 TEST_F(WorkspaceManager2Test, MinimizeSingleWindow) {
395 scoped_ptr<Window> w1(CreateTestWindow());
396
397 w1->Show();
398 ASSERT_EQ("1 active=0", StateString());
399
400 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
401 ASSERT_EQ("1 active=0", StateString());
402 EXPECT_FALSE(w1->layer()->IsDrawn());
403
404 // Show the window.
405 w1->Show();
406 EXPECT_TRUE(wm::IsWindowNormal(w1.get()));
407 ASSERT_EQ("1 active=0", StateString());
408 EXPECT_TRUE(w1->layer()->IsDrawn());
409 }
410
411 // Assertions around minimizing a maximized window.
412 TEST_F(WorkspaceManager2Test, MinimizeMaximizedWindow) {
413 // Two windows, w1 normal, w2 maximized.
414 scoped_ptr<Window> w1(CreateTestWindow());
415 scoped_ptr<Window> w2(CreateTestWindow());
416 w1->Show();
417 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
418 w2->Show();
419 wm::ActivateWindow(w2.get());
420 ASSERT_EQ("1 M1 active=1", StateString());
421
422 // Minimize w2.
423 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
424 ASSERT_EQ("1 P=M1 active=0", StateString());
425 EXPECT_TRUE(w1->layer()->IsDrawn());
426 EXPECT_FALSE(w2->layer()->IsDrawn());
427
428 // Show the window, which should trigger unminimizing.
429 w2->Show();
430 ASSERT_EQ("1 P=M1 active=0", StateString());
431
432 wm::ActivateWindow(w2.get());
433 ASSERT_EQ("1 M1 active=1", StateString());
434
435 EXPECT_TRUE(wm::IsWindowMaximized(w2.get()));
436 EXPECT_FALSE(w1->layer()->IsDrawn());
437 EXPECT_TRUE(w2->layer()->IsDrawn());
438
439 // Minimize the window, which should hide the window and activate another.
440 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
441 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
442 EXPECT_FALSE(wm::IsActiveWindow(w2.get()));
443 EXPECT_FALSE(w2->layer()->IsDrawn());
444 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
445
446 // Make the window normal.
447 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
448 ASSERT_EQ("2 active=0", StateString());
449 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
450 EXPECT_EQ(w2.get(), workspaces()[0]->window()->children()[1]);
451 EXPECT_TRUE(w2->layer()->IsDrawn());
452 }
453
454 // Verifies ShelfLayoutManager's visibility/auto-hide state is correctly
455 // updated.
456 TEST_F(WorkspaceManager2Test, ShelfStateUpdated) {
457 // Since ShelfLayoutManager queries for mouse location, move the mouse so
458 // it isn't over the shelf.
459 aura::test::EventGenerator generator(
460 Shell::GetPrimaryRootWindow(), gfx::Point());
461 generator.MoveMouseTo(0, 0);
462
463 scoped_ptr<Window> w1(CreateTestWindow());
464 const gfx::Rect w1_bounds(0, 1, 101, 102);
465 ShelfLayoutManager* shelf = shelf_layout_manager();
466 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
467 const gfx::Rect touches_shelf_bounds(
468 0, shelf->GetIdealBounds().y() - 10, 101, 102);
469 // Move |w1| to overlap the shelf.
470 w1->SetBounds(touches_shelf_bounds);
471 EXPECT_FALSE(GetWindowOverlapsShelf());
472
473 // A visible ignored window should not trigger the overlap.
474 scoped_ptr<Window> w_ignored(CreateTestWindow());
475 w_ignored->SetBounds(touches_shelf_bounds);
476 SetIgnoredByShelf(&(*w_ignored), true);
477 w_ignored->Show();
478 EXPECT_FALSE(GetWindowOverlapsShelf());
479
480 // Make it visible, since visible shelf overlaps should be true.
481 w1->Show();
482 EXPECT_TRUE(GetWindowOverlapsShelf());
483
484 wm::ActivateWindow(w1.get());
485 w1->SetBounds(w1_bounds);
486 w1->Show();
487 wm::ActivateWindow(w1.get());
488
489 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
490
491 // Maximize the window.
492 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
493 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
494 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
495
496 // Restore.
497 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
498 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
499 EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
500
501 // Fullscreen.
502 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
503 EXPECT_EQ(ShelfLayoutManager::HIDDEN, shelf->visibility_state());
504
505 // Normal.
506 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
507 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
508 EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
509 EXPECT_FALSE(GetWindowOverlapsShelf());
510
511 // Move window so it obscures shelf.
512 w1->SetBounds(touches_shelf_bounds);
513 EXPECT_TRUE(GetWindowOverlapsShelf());
514
515 // Move it back.
516 w1->SetBounds(w1_bounds);
517 EXPECT_FALSE(GetWindowOverlapsShelf());
518
519 // Maximize again.
520 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
521 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
522 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
523
524 // Minimize.
525 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
526 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
527
528 // Since the restore from minimize will restore to the pre-minimize
529 // state (tested elsewhere), we abandon the current size and restore
530 // rect and set them to the window.
531 gfx::Rect restore = *GetRestoreBoundsInScreen(w1.get());
532 EXPECT_EQ("0,0 800x597", w1->bounds().ToString());
533 EXPECT_EQ("0,1 101x102", restore.ToString());
534 ClearRestoreBounds(w1.get());
535 w1->SetBounds(restore);
536
537 // Restore.
538 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
539 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
540 EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
541
542 // Create another window, maximized.
543 scoped_ptr<Window> w2(CreateTestWindow());
544 w2->SetBounds(gfx::Rect(10, 11, 250, 251));
545 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
546 w2->Show();
547 wm::ActivateWindow(w2.get());
548 EXPECT_EQ(1, active_index());
549 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
550 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
551 EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
552
553 // Switch to w1.
554 wm::ActivateWindow(w1.get());
555 EXPECT_EQ(0, active_index());
556 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
557 EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
558 EXPECT_EQ(ScreenAsh::GetMaximizedWindowBoundsInParent(
559 w2->parent()).ToString(),
560 w2->bounds().ToString());
561
562 // Switch to w2.
563 wm::ActivateWindow(w2.get());
564 EXPECT_EQ(1, active_index());
565 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE, shelf->visibility_state());
566 EXPECT_EQ(ShelfLayoutManager::AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
567 EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
568 EXPECT_EQ(ScreenAsh::GetMaximizedWindowBoundsInParent(w2.get()).ToString(),
569 w2->bounds().ToString());
570
571 // Turn off auto-hide, switch back to w2 (maximized) and verify overlap.
572 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
573 wm::ActivateWindow(w2.get());
574 EXPECT_FALSE(GetWindowOverlapsShelf());
575
576 // Move w1 to overlap shelf, it shouldn't change window overlaps shelf since
577 // the window isn't in the visible workspace.
578 w1->SetBounds(touches_shelf_bounds);
579 EXPECT_FALSE(GetWindowOverlapsShelf());
580
581 // Activate w1. Since w1 is visible the overlap state should be true.
582 wm::ActivateWindow(w1.get());
583 EXPECT_TRUE(GetWindowOverlapsShelf());
584 }
585
586 // Verifies persist across all workspaces.
587 TEST_F(WorkspaceManager2Test, PersistAcrossAllWorkspaces) {
588 // Create a maximized window.
589 scoped_ptr<Window> w1(CreateTestWindow());
590 w1->Show();
591 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
592 wm::ActivateWindow(w1.get());
593 ASSERT_EQ("0 M1 active=1", StateString());
594
595 // Create a window that persists across all workspaces. It should be placed in
596 // the current maximized workspace.
597 scoped_ptr<Window> w2(CreateTestWindow());
598 SetPersistsAcrossAllWorkspaces(
599 w2.get(),
600 WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
601 w2->Show();
602 ASSERT_EQ("1 M1 active=1", StateString());
603
604 // Activate w2, which should move it to the 2nd workspace.
605 wm::ActivateWindow(w2.get());
606 ASSERT_EQ("0 M2 active=1", StateString());
607
608 // Restoring w2 should drop the persists window back to the desktop, and drop
609 // it to the bottom of the stack.
610 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
611 ASSERT_EQ("2 active=0", StateString());
612 EXPECT_EQ(w2.get(), workspaces()[0]->window()->children()[0]);
613 EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[1]);
614
615 // Repeat, but this time minimize. The minimized window should end up in
616 // pending.
617 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
618 ASSERT_EQ("1 P=M1 active=0", StateString());
619 w2.reset(CreateTestWindow());
620 SetPersistsAcrossAllWorkspaces(
621 w2.get(),
622 WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
623 w2->Show();
624 ASSERT_EQ("1 P=M1 active=0", StateString());
625 wm::ActivateWindow(w2.get());
626 ASSERT_EQ("1 P=M1 active=0", StateString());
627 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
628 ASSERT_EQ("1 P=M1 active=0", StateString());
629 EXPECT_EQ(w2.get(), workspaces()[0]->window()->children()[0]);
630 }
631
632 // Verifies that when a window persists across all workpaces is activated that
633 // it moves to the current workspace.
634 TEST_F(WorkspaceManager2Test, ActivatePersistAcrossAllWorkspacesWhenNotActive) {
635 // Create a window that persists across all workspaces.
636 scoped_ptr<Window> w2(CreateTestWindow());
637 SetPersistsAcrossAllWorkspaces(
638 w2.get(),
639 WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
640 w2->Show();
641 ASSERT_EQ("1 active=0", StateString());
642
643 // Create a maximized window.
644 scoped_ptr<Window> w1(CreateTestWindow());
645 w1->Show();
646 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
647 wm::ActivateWindow(w1.get());
648 ASSERT_EQ("1 M1 active=1", StateString());
649
650 // Activate the persists across all workspace window. It should move to the
651 // current workspace.
652 wm::ActivateWindow(w2.get());
653 ASSERT_EQ("0 M2 active=1", StateString());
654 // The window that persists across all workspaces should be moved to the top
655 // of the stacking order.
656 EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
657 EXPECT_EQ(w2.get(), workspaces()[1]->window()->children()[1]);
658 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
659 }
660
661 // Verifies Show()ing a minimized window that persists across all workspaces
662 // unminimizes the window.
663 TEST_F(WorkspaceManager2Test, ShowMinimizedPersistWindow) {
664 // Create a window that persists across all workspaces.
665 scoped_ptr<Window> w1(CreateTestWindow());
666 SetPersistsAcrossAllWorkspaces(
667 w1.get(),
668 WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
669 w1->Show();
670 wm::ActivateWindow(w1.get());
671 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
672 EXPECT_FALSE(w1->IsVisible());
673 w1->Show();
674 EXPECT_TRUE(w1->IsVisible());
675 }
676
677 // Test that we report we're in the fullscreen state even if the fullscreen
678 // window isn't being managed by us (http://crbug.com/123931).
679 TEST_F(WorkspaceManager2Test, GetWindowStateWithUnmanagedFullscreenWindow) {
680 ShelfLayoutManager* shelf = shelf_layout_manager();
681
682 // We need to create a regular window first so there's an active workspace.
683 scoped_ptr<Window> w1(CreateTestWindow());
684 w1->Show();
685
686 scoped_ptr<Window> w2(CreateTestWindow());
687 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
688 SetPersistsAcrossAllWorkspaces(
689 w2.get(),
690 WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
691 w2->Show();
692 wm::ActivateWindow(w2.get());
693
694 ASSERT_EQ("1 M1 active=1", StateString());
695
696 EXPECT_EQ(ShelfLayoutManager::HIDDEN, shelf->visibility_state());
697 EXPECT_EQ(WORKSPACE_WINDOW_STATE_FULL_SCREEN, manager_->GetWindowState());
698
699 w2->Hide();
700 ASSERT_EQ("1 P=M1 active=0", StateString());
701 EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state());
702
703 w2->Show();
704 ASSERT_EQ("1 P=M1 active=0", StateString());
705 EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state());
706 EXPECT_EQ(WORKSPACE_WINDOW_STATE_DEFAULT, manager_->GetWindowState());
707
708 wm::ActivateWindow(w2.get());
709 ASSERT_EQ("1 M1 active=1", StateString());
710 EXPECT_EQ(ShelfLayoutManager::HIDDEN, shelf->visibility_state());
711 EXPECT_EQ(WORKSPACE_WINDOW_STATE_FULL_SCREEN, manager_->GetWindowState());
712
713 w2.reset();
714 ASSERT_EQ("1 active=0", StateString());
715 EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state());
716 EXPECT_EQ(WORKSPACE_WINDOW_STATE_DEFAULT, manager_->GetWindowState());
717 }
718
719 // Variant of GetWindowStateWithUnmanagedFullscreenWindow that uses a maximized
720 // window rather than a normal window.
721 TEST_F(WorkspaceManager2Test,
722 GetWindowStateWithUnmanagedFullscreenWindowWithMaximized) {
723 ShelfLayoutManager* shelf = shelf_layout_manager();
724 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
725
726 // Make the first window maximized.
727 scoped_ptr<Window> w1(CreateTestWindow());
728 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
729 w1->Show();
730
731 scoped_ptr<Window> w2(CreateTestWindow());
732 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
733 SetPersistsAcrossAllWorkspaces(
734 w2.get(),
735 WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
736 w2->Show();
737 wm::ActivateWindow(w2.get());
738
739 // Even though auto-hide behavior is NEVER full-screen windows cause the shelf
740 // to hide.
741 EXPECT_EQ(ShelfLayoutManager::HIDDEN, shelf->visibility_state());
742 EXPECT_EQ(WORKSPACE_WINDOW_STATE_FULL_SCREEN,
743 manager_->GetWindowState());
744
745 w2->Hide();
746 EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state());
747
748 w2->Show();
749 wm::ActivateWindow(w2.get());
750 EXPECT_EQ(ShelfLayoutManager::HIDDEN, shelf->visibility_state());
751 EXPECT_EQ(WORKSPACE_WINDOW_STATE_FULL_SCREEN,
752 manager_->GetWindowState());
753
754 w2.reset();
755 EXPECT_EQ(ShelfLayoutManager::VISIBLE, shelf->visibility_state());
756 }
757
758 // Verifies a window marked as persisting across all workspaces ends up in its
759 // own workspace when maximized.
760 TEST_F(WorkspaceManager2Test, MaximizeDontPersistEndsUpInOwnWorkspace) {
761 scoped_ptr<Window> w1(CreateTestWindow());
762
763 SetPersistsAcrossAllWorkspaces(
764 w1.get(),
765 WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
766 w1->Show();
767
768 ASSERT_EQ("1 active=0", StateString());
769
770 // Maximize should trigger containing the window.
771 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
772 ASSERT_EQ("0 P=M1 active=0", StateString());
773
774 // And resetting to normal should remove it.
775 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
776 ASSERT_EQ("1 active=0", StateString());
777 }
778
779 // Verifies going from maximized to minimized sets the right state for painting
780 // the background of the launcher.
781 TEST_F(WorkspaceManager2Test, MinimizeResetsVisibility) {
782 scoped_ptr<Window> w1(CreateTestWindow());
783 w1->Show();
784 wm::ActivateWindow(w1.get());
785 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
786 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
787 EXPECT_EQ(ShelfLayoutManager::VISIBLE,
788 shelf_layout_manager()->visibility_state());
789 EXPECT_FALSE(Launcher::ForPrimaryDisplay()->paints_background());
790 }
791
792 // Verifies transients are moved when maximizing.
793 TEST_F(WorkspaceManager2Test, MoveTransientOnMaximize) {
794 scoped_ptr<Window> w1(CreateTestWindow());
795 w1->Show();
796 scoped_ptr<Window> w2(CreateTestWindow());
797 w1->AddTransientChild(w2.get());
798 w2->Show();
799 wm::ActivateWindow(w1.get());
800 ASSERT_EQ("2 active=0", StateString());
801
802 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
803 ASSERT_EQ("0 M2 active=1", StateString());
804 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
805
806 // Create another transient child of |w1|. We do this unparented, set up the
807 // transient parent then set parent. This is how NativeWidgetAura does things
808 // too.
809 scoped_ptr<Window> w3(CreateTestWindowUnparented());
810 w1->AddTransientChild(w3.get());
811 w3->SetParent(NULL);
812 w3->Show();
813 ASSERT_EQ("0 M3 active=1", StateString());
814
815 // Minimize the window. All the transients are hidden as a result, so it ends
816 // up in pending.
817 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
818 ASSERT_EQ("0 P=M3 active=0", StateString());
819
820 // Restore and everything should go back to the first workspace.
821 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
822 ASSERT_EQ("3 active=0", StateString());
823 }
824
825 // Verifies window visibility during various workspace changes.
826 TEST_F(WorkspaceManager2Test, VisibilityTests) {
827 scoped_ptr<Window> w1(CreateTestWindow());
828 w1->Show();
829 EXPECT_TRUE(w1->IsVisible());
830 EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
831
832 // Create another window, activate it and maximized it.
833 scoped_ptr<Window> w2(CreateTestWindow());
834 w2->Show();
835 wm::ActivateWindow(w2.get());
836 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
837 EXPECT_TRUE(w2->IsVisible());
838 EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
839 EXPECT_FALSE(w1->IsVisible());
840
841 // Switch to w1. |w1| should be visible and |w2| hidden.
842 wm::ActivateWindow(w1.get());
843 EXPECT_TRUE(w1->IsVisible());
844 EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
845 EXPECT_FALSE(w2->IsVisible());
846
847 // Switch back to |w2|.
848 wm::ActivateWindow(w2.get());
849 EXPECT_TRUE(w2->IsVisible());
850 EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
851 EXPECT_FALSE(w1->IsVisible());
852
853 // Restore |w2|, both windows should be visible.
854 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
855 EXPECT_TRUE(w1->IsVisible());
856 EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
857 EXPECT_TRUE(w2->IsVisible());
858 EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
859
860 // Maximize |w2| again, then close it.
861 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
862 w2->Hide();
863 EXPECT_FALSE(w2->IsVisible());
864 EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
865 EXPECT_TRUE(w1->IsVisible());
866
867 // Create |w2| and make it fullscreen.
868 w2.reset(CreateTestWindow());
869 w2->Show();
870 wm::ActivateWindow(w2.get());
871 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
872 EXPECT_TRUE(w2->IsVisible());
873 EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
874 EXPECT_FALSE(w1->IsVisible());
875
876 // Close |w2|.
877 w2.reset();
878 EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
879 EXPECT_TRUE(w1->IsVisible());
880 }
881
882 // Verifies windows that are offscreen don't move when switching workspaces.
883 TEST_F(WorkspaceManager2Test, DontMoveOnSwitch) {
884 aura::test::EventGenerator generator(
885 Shell::GetPrimaryRootWindow(), gfx::Point());
886 generator.MoveMouseTo(0, 0);
887
888 scoped_ptr<Window> w1(CreateTestWindow());
889 ShelfLayoutManager* shelf = shelf_layout_manager();
890 const gfx::Rect touches_shelf_bounds(
891 0, shelf->GetIdealBounds().y() - 10, 101, 102);
892 // Move |w1| to overlap the shelf.
893 w1->SetBounds(touches_shelf_bounds);
894 w1->Show();
895 wm::ActivateWindow(w1.get());
896
897 // Create another window and maximize it.
898 scoped_ptr<Window> w2(CreateTestWindow());
899 w2->SetBounds(gfx::Rect(10, 11, 250, 251));
900 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
901 w2->Show();
902 wm::ActivateWindow(w2.get());
903
904 // Switch to w1.
905 wm::ActivateWindow(w1.get());
906 EXPECT_EQ(touches_shelf_bounds.ToString(), w1->bounds().ToString());
907 }
908
909 // Verifies that windows that are completely offscreen move when switching
910 // workspaces.
911 TEST_F(WorkspaceManager2Test, MoveOnSwitch) {
912 aura::test::EventGenerator generator(
913 Shell::GetPrimaryRootWindow(), gfx::Point());
914 generator.MoveMouseTo(0, 0);
915
916 scoped_ptr<Window> w1(CreateTestWindow());
917 ShelfLayoutManager* shelf = shelf_layout_manager();
918 const gfx::Rect w1_bounds(0, shelf->GetIdealBounds().y(), 100, 200);
919 // Move |w1| so that the top edge is the same as the top edge of the shelf.
920 w1->SetBounds(w1_bounds);
921 w1->Show();
922 wm::ActivateWindow(w1.get());
923 EXPECT_EQ(w1_bounds.ToString(), w1->bounds().ToString());
924
925 // Create another window and maximize it.
926 scoped_ptr<Window> w2(CreateTestWindow());
927 w2->SetBounds(gfx::Rect(10, 11, 250, 251));
928 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
929 w2->Show();
930 wm::ActivateWindow(w2.get());
931
932 // Increase the size of the shelf. This would make |w1| fall completely out of
933 // the display work area.
934 gfx::Size size(shelf->status_area_widget()->GetWindowBoundsInScreen().size());
935 size.Enlarge(0, 30);
936 shelf->status_area_widget()->SetSize(size);
937
938 // Switch to w1. The window should have moved.
939 wm::ActivateWindow(w1.get());
940 EXPECT_NE(w1_bounds.ToString(), w1->bounds().ToString());
941 }
942
943 // Verifies Focus() works in a window that isn't in the active workspace.
944 TEST_F(WorkspaceManager2Test, FocusOnFullscreenInSeparateWorkspace) {
945 scoped_ptr<Window> w1(CreateTestWindow());
946 w1->SetBounds(gfx::Rect(10, 11, 250, 251));
947 w1->Show();
948 wm::ActivateWindow(w1.get());
949
950 scoped_ptr<Window> w2(CreateTestWindow());
951 w2->SetBounds(gfx::Rect(10, 11, 250, 251));
952 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
953 w2->Show();
954 EXPECT_FALSE(w2->IsVisible());
955 EXPECT_FALSE(wm::IsActiveWindow(w2.get()));
956
957 w2->Focus();
958 EXPECT_TRUE(w2->IsVisible());
959 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
960 EXPECT_FALSE(w1->IsVisible());
961 }
962
963 namespace {
964
965 // WindowDelegate used by DontCrashOnChangeAndActivate.
966 class DontCrashOnChangeAndActivateDelegate
967 : public aura::test::TestWindowDelegate {
968 public:
969 DontCrashOnChangeAndActivateDelegate() : window_(NULL) {}
970
971 void set_window(aura::Window* window) { window_ = window; }
972
973 // WindowDelegate overrides:
974 virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
975 const gfx::Rect& new_bounds) OVERRIDE {
976 if (window_) {
977 wm::ActivateWindow(window_);
978 window_ = NULL;
979 }
980 }
981
982 private:
983 aura::Window* window_;
984
985 DISALLOW_COPY_AND_ASSIGN(DontCrashOnChangeAndActivateDelegate);
986 };
987
988 } // namespace
989
990 // Exercises possible crash in W2. Here's the sequence:
991 // . minimize a maximized window.
992 // . remove the window (which happens when switching displays).
993 // . add the window back.
994 // . show the window and during the bounds change activate it.
995 TEST_F(WorkspaceManager2Test, DontCrashOnChangeAndActivate) {
996 // Force the shelf
997 ShelfLayoutManager* shelf = shelf_layout_manager();
998 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
999
1000 DontCrashOnChangeAndActivateDelegate delegate;
1001 scoped_ptr<Window> w1(
1002 CreateTestWindowWithDelegate(&delegate, 1000, gfx::Rect(10, 11, 250, 251),
1003 NULL));
1004 w1->Show();
1005 wm::ActivateWindow(w1.get());
1006 wm::MaximizeWindow(w1.get());
1007 wm::MinimizeWindow(w1.get());
1008
1009 w1->parent()->RemoveChild(w1.get());
1010
1011 // Do this so that when we Show() the window a resize occurs and we make the
1012 // window active.
1013 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1014
1015 w1->SetParent(NULL);
1016 delegate.set_window(w1.get());
1017 w1->Show();
1018 }
1019
1020 // Verifies a window with a transient parent not managed by workspace works.
1021 TEST_F(WorkspaceManager2Test, TransientParent) {
1022 // Normal window with no transient parent.
1023 scoped_ptr<Window> w2(CreateTestWindow());
1024 w2->SetBounds(gfx::Rect(10, 11, 250, 251));
1025 w2->Show();
1026 wm::ActivateWindow(w2.get());
1027
1028 // Window with a transient parent. We set the transient parent to the root,
1029 // which would never happen but is enough to exercise the bug.
1030 scoped_ptr<Window> w1(CreateTestWindowUnparented());
1031 Shell::GetInstance()->GetPrimaryRootWindow()->AddTransientChild(w1.get());
1032 w1->SetBounds(gfx::Rect(10, 11, 250, 251));
1033 w1->SetParent(NULL);
1034 w1->Show();
1035 wm::ActivateWindow(w1.get());
1036
1037 // The window with the transient parent should get added to the same parent as
1038 // the normal window.
1039 EXPECT_EQ(w2->parent(), w1->parent());
1040 }
1041
1042 // Verifies changing TrackedByWorkspace works.
1043 TEST_F(WorkspaceManager2Test, TrackedByWorkspace) {
1044 // Create a window maximized.
1045 scoped_ptr<Window> w1(CreateTestWindow());
1046 w1->Show();
1047 wm::ActivateWindow(w1.get());
1048 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1049 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
1050 EXPECT_TRUE(w1->IsVisible());
1051
1052 // Create a second window maximized and mark it not tracked by workspace
1053 // manager.
1054 scoped_ptr<Window> w2(CreateTestWindowUnparented());
1055 w2->SetBounds(gfx::Rect(1, 6, 25, 30));
1056 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1057 w2->SetParent(NULL);
1058 w2->Show();
1059 SetTrackedByWorkspace(w2.get(), false);
1060 wm::ActivateWindow(w2.get());
1061
1062 // Activating |w2| should force it to have the same parent as |w1|.
1063 EXPECT_EQ(w1->parent(), w2->parent());
1064 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
1065 EXPECT_TRUE(w1->IsVisible());
1066 EXPECT_TRUE(w2->IsVisible());
1067
1068 // Because |w2| isn't tracked we should be able to set the bounds of it.
1069 gfx::Rect bounds(w2->bounds());
1070 bounds.Offset(4, 5);
1071 w2->SetBounds(bounds);
1072 EXPECT_EQ(bounds.ToString(), w2->bounds().ToString());
1073
1074 // Transition it to tracked by worskpace. It should end up in its own
1075 // workspace.
1076 SetTrackedByWorkspace(w2.get(), true);
1077 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
1078 EXPECT_FALSE(w1->IsVisible());
1079 EXPECT_TRUE(w2->IsVisible());
1080 EXPECT_NE(w1->parent(), w2->parent());
1081 }
1082
1083 // Verifies a window marked as persisting across all workspaces ends up in its
1084 // own workspace when maximized.
1085 TEST_F(WorkspaceManager2Test, DeactivateDropsToDesktop) {
1086 // Create a window maximized.
1087 scoped_ptr<Window> w1(CreateTestWindow());
1088 w1->Show();
1089 wm::ActivateWindow(w1.get());
1090 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1091 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
1092 EXPECT_TRUE(w1->IsVisible());
1093
1094 // Create another window that persists across all workspaces. It should end
1095 // up with the same parent as |w1|.
1096 scoped_ptr<Window> w2(CreateTestWindow());
1097 SetPersistsAcrossAllWorkspaces(
1098 w2.get(),
1099 WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
1100 w2->Show();
1101 wm::ActivateWindow(w2.get());
1102 EXPECT_EQ(w1->parent(), w2->parent());
1103 ASSERT_EQ("0 M2 active=1", StateString());
1104
1105 // Activate |w1|, should result in dropping |w2| to the desktop.
1106 wm::ActivateWindow(w1.get());
1107 ASSERT_EQ("1 M1 active=1", StateString());
1108 }
1109
1110 // Test the basic auto placement of one and or two windows in a "simulated
1111 // session" of sequential window operations.
1112 TEST_F(WorkspaceManager2Test, BasicAutoPlacing) {
1113 // Test 1: In case there is no manageable window, no window should shift.
1114
1115 scoped_ptr<aura::Window> window1(
1116 aura::test::CreateTestWindowWithId(0, NULL));
1117 window1->SetBounds(gfx::Rect(16, 32, 640, 320));
1118 gfx::Rect desktop_area = window1->parent()->bounds();
1119
1120 scoped_ptr<aura::Window> window2(
1121 aura::test::CreateTestWindowWithId(1, NULL));
1122 // Trigger the auto window placement function by making it visible.
1123 // Note that the bounds are getting changed while it is invisible.
1124 window2->Hide();
1125 window2->SetBounds(gfx::Rect(32, 48, 256, 512));
1126 window2->Show();
1127
1128 // Check the initial position of the windows is unchanged.
1129 EXPECT_EQ("16,32 640x320", window1->bounds().ToString());
1130 EXPECT_EQ("32,48 256x512", window2->bounds().ToString());
1131
1132 // Remove the second window and make sure that the first window
1133 // does NOT get centered.
1134 window2.reset();
1135 EXPECT_EQ("16,32 640x320", window1->bounds().ToString());
1136
1137 // Test 2: Set up two managed windows and check their auto positioning.
1138 ash::wm::SetWindowPositionManaged(window1.get(), true);
1139 scoped_ptr<aura::Window> window3(
1140 aura::test::CreateTestWindowWithId(2, NULL));
1141 ash::wm::SetWindowPositionManaged(window3.get(), true);
1142 // To avoid any auto window manager changes due to SetBounds, the window
1143 // gets first hidden and then shown again.
1144 window3->Hide();
1145 window3->SetBounds(gfx::Rect(32, 48, 256, 512));
1146 window3->Show();
1147 // |window1| should be flush right and |window3| flush left.
1148 EXPECT_EQ("0,32 640x320", window1->bounds().ToString());
1149 EXPECT_EQ(base::IntToString(
1150 desktop_area.width() - window3->bounds().width()) +
1151 ",48 256x512", window3->bounds().ToString());
1152
1153 // After removing |window3|, |window1| should be centered again.
1154 window3.reset();
1155 EXPECT_EQ(
1156 base::IntToString(
1157 (desktop_area.width() - window1->bounds().width()) / 2) +
1158 ",32 640x320", window1->bounds().ToString());
1159
1160 // Test 3: Set up a manageable and a non manageable window and check
1161 // positioning.
1162 scoped_ptr<aura::Window> window4(
1163 aura::test::CreateTestWindowWithId(3, NULL));
1164 // To avoid any auto window manager changes due to SetBounds, the window
1165 // gets first hidden and then shown again.
1166 window1->Hide();
1167 window1->SetBounds(gfx::Rect(16, 32, 640, 320));
1168 window4->SetBounds(gfx::Rect(32, 48, 256, 512));
1169 window1->Show();
1170 // |window1| should be centered and |window4| untouched.
1171 EXPECT_EQ(
1172 base::IntToString(
1173 (desktop_area.width() - window1->bounds().width()) / 2) +
1174 ",32 640x320", window1->bounds().ToString());
1175 EXPECT_EQ("32,48 256x512", window4->bounds().ToString());
1176
1177 // Test4: A single manageable window should get centered.
1178 window4.reset();
1179 ash::wm::SetUserHasChangedWindowPositionOrSize(window1.get(), false);
1180 // Trigger the auto window placement function by showing (and hiding) it.
1181 window1->Hide();
1182 window1->Show();
1183 // |window1| should be centered.
1184 EXPECT_EQ(
1185 base::IntToString(
1186 (desktop_area.width() - window1->bounds().width()) / 2) +
1187 ",32 640x320", window1->bounds().ToString());
1188 }
1189
1190 // Test the proper usage of user window movement interaction.
1191 TEST_F(WorkspaceManager2Test, TestUserMovedWindowRepositioning) {
1192 scoped_ptr<aura::Window> window1(
1193 aura::test::CreateTestWindowWithId(0, NULL));
1194 window1->SetBounds(gfx::Rect(16, 32, 640, 320));
1195 gfx::Rect desktop_area = window1->parent()->bounds();
1196 scoped_ptr<aura::Window> window2(
1197 aura::test::CreateTestWindowWithId(1, NULL));
1198 window2->SetBounds(gfx::Rect(32, 48, 256, 512));
1199 window1->Hide();
1200 window2->Hide();
1201 ash::wm::SetWindowPositionManaged(window1.get(), true);
1202 ash::wm::SetWindowPositionManaged(window2.get(), true);
1203 EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
1204 EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window2.get()));
1205
1206 // Check that the current location gets preserved if the user has
1207 // positioned it previously.
1208 ash::wm::SetUserHasChangedWindowPositionOrSize(window1.get(), true);
1209 window1->Show();
1210 EXPECT_EQ("16,32 640x320", window1->bounds().ToString());
1211 // Flag should be still set.
1212 EXPECT_TRUE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
1213 EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window2.get()));
1214
1215 // Turn on the second window and make sure that both windows are now
1216 // positionable again (user movement cleared).
1217 window2->Show();
1218
1219 // |window1| should be flush right and |window3| flush left.
1220 EXPECT_EQ(base::IntToString(
1221 desktop_area.width() - window1->bounds().width()) +
1222 ",32 640x320", window1->bounds().ToString());
1223 EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
1224 // FLag should now be reset.
1225 EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
1226 EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
1227
1228 // Going back to one shown window should keep the state.
1229 ash::wm::SetUserHasChangedWindowPositionOrSize(window1.get(), true);
1230 window2->Hide();
1231 EXPECT_EQ(base::IntToString(
1232 desktop_area.width() - window1->bounds().width()) +
1233 ",32 640x320", window1->bounds().ToString());
1234 EXPECT_TRUE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
1235 }
1236
1237 // Test that a window from normal to minimize will repos the remaining.
1238 TEST_F(WorkspaceManager2Test, ToMinimizeRepositionsRemaining) {
1239 scoped_ptr<aura::Window> window1(
1240 aura::test::CreateTestWindowWithId(0, NULL));
1241 ash::wm::SetWindowPositionManaged(window1.get(), true);
1242 window1->SetBounds(gfx::Rect(16, 32, 640, 320));
1243 gfx::Rect desktop_area = window1->parent()->bounds();
1244
1245 scoped_ptr<aura::Window> window2(
1246 aura::test::CreateTestWindowWithId(1, NULL));
1247 ash::wm::SetWindowPositionManaged(window2.get(), true);
1248 window2->SetBounds(gfx::Rect(32, 48, 256, 512));
1249
1250 ash::wm::MinimizeWindow(window1.get());
1251
1252 // |window2| should be centered now.
1253 EXPECT_TRUE(window2->IsVisible());
1254 EXPECT_TRUE(ash::wm::IsWindowNormal(window2.get()));
1255 EXPECT_EQ(base::IntToString(
1256 (desktop_area.width() - window2->bounds().width()) / 2) +
1257 ",48 256x512", window2->bounds().ToString());
1258
1259 ash::wm::RestoreWindow(window1.get());
1260 // |window1| should be flush right and |window3| flush left.
1261 EXPECT_EQ(base::IntToString(
1262 desktop_area.width() - window1->bounds().width()) +
1263 ",32 640x320", window1->bounds().ToString());
1264 EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
1265 }
1266
1267 // Test that minimizing an initially maximized window will repos the remaining.
1268 TEST_F(WorkspaceManager2Test, MaxToMinRepositionsRemaining) {
1269 scoped_ptr<aura::Window> window1(
1270 aura::test::CreateTestWindowWithId(0, NULL));
1271 ash::wm::SetWindowPositionManaged(window1.get(), true);
1272 gfx::Rect desktop_area = window1->parent()->bounds();
1273
1274 scoped_ptr<aura::Window> window2(
1275 aura::test::CreateTestWindowWithId(1, NULL));
1276 ash::wm::SetWindowPositionManaged(window2.get(), true);
1277 window2->SetBounds(gfx::Rect(32, 48, 256, 512));
1278
1279 ash::wm::MaximizeWindow(window1.get());
1280 ash::wm::MinimizeWindow(window1.get());
1281
1282 // |window2| should be centered now.
1283 EXPECT_TRUE(window2->IsVisible());
1284 EXPECT_TRUE(ash::wm::IsWindowNormal(window2.get()));
1285 EXPECT_EQ(base::IntToString(
1286 (desktop_area.width() - window2->bounds().width()) / 2) +
1287 ",48 256x512", window2->bounds().ToString());
1288 }
1289
1290 // Test that nomral, maximize, minimizing will repos the remaining.
1291 TEST_F(WorkspaceManager2Test, NormToMaxToMinRepositionsRemaining) {
1292 scoped_ptr<aura::Window> window1(
1293 aura::test::CreateTestWindowWithId(0, NULL));
1294 window1->SetBounds(gfx::Rect(16, 32, 640, 320));
1295 ash::wm::SetWindowPositionManaged(window1.get(), true);
1296 gfx::Rect desktop_area = window1->parent()->bounds();
1297
1298 scoped_ptr<aura::Window> window2(
1299 aura::test::CreateTestWindowWithId(1, NULL));
1300 ash::wm::SetWindowPositionManaged(window2.get(), true);
1301 window2->SetBounds(gfx::Rect(32, 48, 256, 512));
1302
1303 // Trigger the auto window placement function by showing (and hiding) it.
1304 window1->Hide();
1305 window1->Show();
1306
1307 // |window1| should be flush right and |window3| flush left.
1308 EXPECT_EQ(base::IntToString(
1309 desktop_area.width() - window1->bounds().width()) +
1310 ",32 640x320", window1->bounds().ToString());
1311 EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
1312
1313 ash::wm::MaximizeWindow(window1.get());
1314 ash::wm::MinimizeWindow(window1.get());
1315
1316 // |window2| should be centered now.
1317 EXPECT_TRUE(window2->IsVisible());
1318 EXPECT_TRUE(ash::wm::IsWindowNormal(window2.get()));
1319 EXPECT_EQ(base::IntToString(
1320 (desktop_area.width() - window2->bounds().width()) / 2) +
1321 ",48 256x512", window2->bounds().ToString());
1322 }
1323
1324 // Test that nomral, maximize, normal will repos the remaining.
1325 TEST_F(WorkspaceManager2Test, NormToMaxToNormRepositionsRemaining) {
1326 scoped_ptr<aura::Window> window1(
1327 aura::test::CreateTestWindowWithId(0, NULL));
1328 window1->SetBounds(gfx::Rect(16, 32, 640, 320));
1329 ash::wm::SetWindowPositionManaged(window1.get(), true);
1330 gfx::Rect desktop_area = window1->parent()->bounds();
1331
1332 scoped_ptr<aura::Window> window2(
1333 aura::test::CreateTestWindowWithId(1, NULL));
1334 ash::wm::SetWindowPositionManaged(window2.get(), true);
1335 window2->SetBounds(gfx::Rect(32, 48, 256, 512));
1336
1337 // Trigger the auto window placement function by showing (and hiding) it.
1338 window1->Hide();
1339 window1->Show();
1340
1341 // |window1| should be flush right and |window3| flush left.
1342 EXPECT_EQ(base::IntToString(
1343 desktop_area.width() - window1->bounds().width()) +
1344 ",32 640x320", window1->bounds().ToString());
1345 EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
1346
1347 ash::wm::MaximizeWindow(window1.get());
1348 ash::wm::RestoreWindow(window1.get());
1349
1350 // |window1| should be flush right and |window2| flush left.
1351 EXPECT_EQ(base::IntToString(
1352 desktop_area.width() - window1->bounds().width()) +
1353 ",32 640x320", window1->bounds().ToString());
1354 EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
1355 }
1356
1357 // Test that animations are triggered.
1358 TEST_F(WorkspaceManager2Test, AnimatedNormToMaxToNormRepositionsRemaining) {
1359 ui::LayerAnimator::set_disable_animations_for_test(false);
1360 scoped_ptr<aura::Window> window1(
1361 aura::test::CreateTestWindowWithId(0, NULL));
1362 window1->Hide();
1363 window1->SetBounds(gfx::Rect(16, 32, 640, 320));
1364 gfx::Rect desktop_area = window1->parent()->bounds();
1365 scoped_ptr<aura::Window> window2(
1366 aura::test::CreateTestWindowWithId(1, NULL));
1367 window2->Hide();
1368 window2->SetBounds(gfx::Rect(32, 48, 256, 512));
1369
1370 ash::wm::SetWindowPositionManaged(window1.get(), true);
1371 ash::wm::SetWindowPositionManaged(window2.get(), true);
1372 // Make sure nothing is animating.
1373 window1->layer()->GetAnimator()->StopAnimating();
1374 window2->layer()->GetAnimator()->StopAnimating();
1375 window2->Show();
1376
1377 // The second window should now animate.
1378 EXPECT_FALSE(window1->layer()->GetAnimator()->is_animating());
1379 EXPECT_TRUE(window2->layer()->GetAnimator()->is_animating());
1380 window2->layer()->GetAnimator()->StopAnimating();
1381
1382 window1->Show();
1383 EXPECT_TRUE(window1->layer()->GetAnimator()->is_animating());
1384 EXPECT_TRUE(window2->layer()->GetAnimator()->is_animating());
1385
1386 window1->layer()->GetAnimator()->StopAnimating();
1387 window2->layer()->GetAnimator()->StopAnimating();
1388 // |window1| should be flush right and |window2| flush left.
1389 EXPECT_EQ(base::IntToString(
1390 desktop_area.width() - window1->bounds().width()) +
1391 ",32 640x320", window1->bounds().ToString());
1392 EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
1393 }
1394
1395 } // namespace internal
1396 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/workspace/workspace_manager2.cc ('k') | ash/wm/workspace/workspace_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698