| OLD | NEW |
| (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 | |
| OLD | NEW |