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/display/display_controller.h" 6 7 #include "ash/ash_switches.h" 8 #include "ash/display/display_info.h" 9 #include "ash/display/display_layout_store.h" 10 #include "ash/display/display_manager.h" 11 #include "ash/launcher/launcher.h" 12 #include "ash/screen_ash.h" 13 #include "ash/shelf/shelf_widget.h" 14 #include "ash/shell.h" 15 #include "ash/test/ash_test_base.h" 16 #include "ash/test/cursor_manager_test_api.h" 17 #include "ash/test/display_manager_test_api.h" 18 #include "ash/wm/window_state.h" 19 #include "base/command_line.h" 20 #include "ui/aura/client/activation_change_observer.h" 21 #include "ui/aura/client/activation_client.h" 22 #include "ui/aura/client/focus_change_observer.h" 23 #include "ui/aura/client/focus_client.h" 24 #include "ui/aura/env.h" 25 #include "ui/aura/root_window.h" 26 #include "ui/aura/test/event_generator.h" 27 #include "ui/aura/window_tracker.h" 28 #include "ui/events/event_handler.h" 29 #include "ui/gfx/display.h" 30 #include "ui/gfx/screen.h" 31 #include "ui/views/widget/widget.h" 32 33 #if defined(USE_X11) 34 #include "ui/gfx/x/x11_types.h" 35 #include <X11/Xlib.h> 36 #undef RootWindow 37 #endif 38 39 namespace ash { 40 namespace { 41 42 const char kDesktopBackgroundView[] = "DesktopBackgroundView"; 43 44 template<typename T> 45 class Resetter { 46 public: 47 explicit Resetter(T* value) : value_(*value) { 48 *value = 0; 49 } 50 ~Resetter() { } 51 T value() { return value_; } 52 53 private: 54 T value_; 55 DISALLOW_COPY_AND_ASSIGN(Resetter); 56 }; 57 58 class TestObserver : public DisplayController::Observer, 59 public gfx::DisplayObserver, 60 public aura::client::FocusChangeObserver, 61 public aura::client::ActivationChangeObserver { 62 public: 63 TestObserver() 64 : changing_count_(0), 65 changed_count_(0), 66 bounds_changed_count_(0), 67 changed_display_id_(0), 68 focus_changed_count_(0), 69 activation_changed_count_(0) { 70 Shell::GetInstance()->display_controller()->AddObserver(this); 71 Shell::GetScreen()->AddObserver(this); 72 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())-> 73 AddObserver(this); 74 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> 75 AddObserver(this); 76 } 77 78 virtual ~TestObserver() { 79 Shell::GetInstance()->display_controller()->RemoveObserver(this); 80 Shell::GetScreen()->RemoveObserver(this); 81 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())-> 82 RemoveObserver(this); 83 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> 84 RemoveObserver(this); 85 } 86 87 // Overridden from DisplayController::Observer 88 virtual void OnDisplayConfigurationChanging() OVERRIDE { 89 ++changing_count_; 90 } 91 virtual void OnDisplayConfigurationChanged() OVERRIDE { 92 ++changed_count_; 93 } 94 95 // Overrideen from gfx::DisplayObserver 96 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE { 97 changed_display_id_ = display.id(); 98 bounds_changed_count_ ++; 99 } 100 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { 101 } 102 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { 103 } 104 105 // Overridden from aura::client::FocusChangeObserver 106 virtual void OnWindowFocused(aura::Window* gained_focus, 107 aura::Window* lost_focus) OVERRIDE { 108 focus_changed_count_++; 109 } 110 111 // Overridden from aura::client::ActivationChangeObserver 112 virtual void OnWindowActivated(aura::Window* gained_active, 113 aura::Window* lost_active) OVERRIDE { 114 activation_changed_count_++; 115 } 116 virtual void OnAttemptToReactivateWindow( 117 aura::Window* request_active, 118 aura::Window* actual_active) OVERRIDE { 119 } 120 121 int CountAndReset() { 122 EXPECT_EQ(changing_count_, changed_count_); 123 changed_count_ = 0; 124 return Resetter<int>(&changing_count_).value(); 125 } 126 127 int64 GetBoundsChangedCountAndReset() { 128 return Resetter<int>(&bounds_changed_count_).value(); 129 } 130 131 int64 GetChangedDisplayIdAndReset() { 132 return Resetter<int64>(&changed_display_id_).value(); 133 } 134 135 int GetFocusChangedCountAndReset() { 136 return Resetter<int>(&focus_changed_count_).value(); 137 } 138 139 int GetActivationChangedCountAndReset() { 140 return Resetter<int>(&activation_changed_count_).value(); 141 } 142 143 private: 144 int changing_count_; 145 int changed_count_; 146 147 int bounds_changed_count_; 148 int64 changed_display_id_; 149 150 int focus_changed_count_; 151 int activation_changed_count_; 152 153 DISALLOW_COPY_AND_ASSIGN(TestObserver); 154 }; 155 156 gfx::Display GetPrimaryDisplay() { 157 return Shell::GetScreen()->GetDisplayNearestWindow( 158 Shell::GetAllRootWindows()[0]); 159 } 160 161 gfx::Display GetSecondaryDisplay() { 162 return Shell::GetScreen()->GetDisplayNearestWindow( 163 Shell::GetAllRootWindows()[1]); 164 } 165 166 void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position, 167 int offset) { 168 DisplayLayout layout(position, offset); 169 ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1); 170 Shell::GetInstance()->display_manager()-> 171 SetLayoutForCurrentDisplays(layout); 172 } 173 174 void SetSecondaryDisplayLayout(DisplayLayout::Position position) { 175 SetSecondaryDisplayLayoutAndOffset(position, 0); 176 } 177 178 void SetDefaultDisplayLayout(DisplayLayout::Position position) { 179 Shell::GetInstance()->display_manager()->layout_store()-> 180 SetDefaultDisplayLayout(DisplayLayout(position, 0)); 181 } 182 183 class DisplayControllerShutdownTest : public test::AshTestBase { 184 public: 185 virtual void TearDown() OVERRIDE { 186 test::AshTestBase::TearDown(); 187 if (!SupportsMultipleDisplays()) 188 return; 189 190 // Make sure that primary display is accessible after shutdown. 191 gfx::Display primary = Shell::GetScreen()->GetPrimaryDisplay(); 192 EXPECT_EQ("0,0 444x333", primary.bounds().ToString()); 193 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 194 } 195 }; 196 197 class TestEventHandler : public ui::EventHandler { 198 public: 199 TestEventHandler() : target_root_(NULL), 200 touch_radius_x_(0.0), 201 touch_radius_y_(0.0), 202 scroll_x_offset_(0.0), 203 scroll_y_offset_(0.0), 204 scroll_x_offset_ordinal_(0.0), 205 scroll_y_offset_ordinal_(0.0) {} 206 virtual ~TestEventHandler() {} 207 208 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { 209 if (event->flags() & ui::EF_IS_SYNTHESIZED && 210 event->type() != ui::ET_MOUSE_EXITED && 211 event->type() != ui::ET_MOUSE_ENTERED) { 212 return; 213 } 214 aura::Window* target = static_cast<aura::Window*>(event->target()); 215 mouse_location_ = event->root_location(); 216 target_root_ = target->GetRootWindow(); 217 event->StopPropagation(); 218 } 219 220 virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE { 221 aura::Window* target = static_cast<aura::Window*>(event->target()); 222 // Only record when the target is the background which covers 223 // entire root window. 224 if (target->name() != kDesktopBackgroundView) 225 return; 226 touch_radius_x_ = event->radius_x(); 227 touch_radius_y_ = event->radius_y(); 228 event->StopPropagation(); 229 } 230 231 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { 232 aura::Window* target = static_cast<aura::Window*>(event->target()); 233 // Only record when the target is the background which covers 234 // entire root window. 235 if (target->name() != kDesktopBackgroundView) 236 return; 237 238 if (event->type() == ui::ET_SCROLL) { 239 scroll_x_offset_ = event->x_offset(); 240 scroll_y_offset_ = event->y_offset(); 241 scroll_x_offset_ordinal_ = event->x_offset_ordinal(); 242 scroll_y_offset_ordinal_ = event->y_offset_ordinal(); 243 } 244 event->StopPropagation(); 245 } 246 247 std::string GetLocationAndReset() { 248 std::string result = mouse_location_.ToString(); 249 mouse_location_.SetPoint(0, 0); 250 target_root_ = NULL; 251 return result; 252 } 253 254 float touch_radius_x() { return touch_radius_x_; } 255 float touch_radius_y() { return touch_radius_y_; } 256 float scroll_x_offset() { return scroll_x_offset_; } 257 float scroll_y_offset() { return scroll_y_offset_; } 258 float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_; } 259 float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_; } 260 261 private: 262 gfx::Point mouse_location_; 263 aura::Window* target_root_; 264 265 float touch_radius_x_; 266 float touch_radius_y_; 267 float scroll_x_offset_; 268 float scroll_y_offset_; 269 float scroll_x_offset_ordinal_; 270 float scroll_y_offset_ordinal_; 271 272 DISALLOW_COPY_AND_ASSIGN(TestEventHandler); 273 }; 274 275 gfx::Display::Rotation GetStoredRotation(int64 id) { 276 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation(); 277 } 278 279 float GetStoredUIScale(int64 id) { 280 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id). 281 GetEffectiveUIScale(); 282 } 283 284 #if defined(USE_X11) 285 void GetPrimaryAndSeconary(aura::Window** primary, 286 aura::Window** secondary) { 287 *primary = Shell::GetPrimaryRootWindow(); 288 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 289 *secondary = root_windows[0] == *primary ? root_windows[1] : root_windows[0]; 290 } 291 292 std::string GetXWindowName(aura::RootWindow* window) { 293 char* name = NULL; 294 XFetchName(gfx::GetXDisplay(), window->host()->GetAcceleratedWidget(), &name); 295 std::string ret(name); 296 XFree(name); 297 return ret; 298 } 299 #endif 300 301 } // namespace 302 303 typedef test::AshTestBase DisplayControllerTest; 304 305 TEST_F(DisplayControllerShutdownTest, Shutdown) { 306 if (!SupportsMultipleDisplays()) 307 return; 308 309 UpdateDisplay("444x333, 200x200"); 310 } 311 312 TEST_F(DisplayControllerTest, SecondaryDisplayLayout) { 313 if (!SupportsMultipleDisplays()) 314 return; 315 316 // Creates windows to catch activation change event. 317 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1)); 318 w1->Focus(); 319 320 TestObserver observer; 321 UpdateDisplay("500x500,400x400"); 322 EXPECT_EQ(1, observer.CountAndReset()); // resize and add 323 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 324 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 325 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 326 gfx::Insets insets(5, 5, 5, 5); 327 int64 secondary_display_id = ScreenAsh::GetSecondaryDisplay().id(); 328 Shell::GetInstance()->display_manager()->UpdateWorkAreaOfDisplay( 329 secondary_display_id, insets); 330 331 // Default layout is RIGHT. 332 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 333 EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString()); 334 EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString()); 335 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 336 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 337 338 // Layout the secondary display to the bottom of the primary. 339 SetSecondaryDisplayLayout(DisplayLayout::BOTTOM); 340 EXPECT_EQ(1, observer.CountAndReset()); 341 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 342 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 343 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 344 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 345 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 346 EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString()); 347 EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString()); 348 349 // Layout the secondary display to the left of the primary. 350 SetSecondaryDisplayLayout(DisplayLayout::LEFT); 351 EXPECT_EQ(1, observer.CountAndReset()); 352 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 353 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 354 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 355 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 356 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 357 EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString()); 358 EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString()); 359 360 // Layout the secondary display to the top of the primary. 361 SetSecondaryDisplayLayout(DisplayLayout::TOP); 362 EXPECT_EQ(1, observer.CountAndReset()); 363 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 364 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 365 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 366 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 367 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 368 EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString()); 369 EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString()); 370 371 // Layout to the right with an offset. 372 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 300); 373 EXPECT_EQ(1, observer.CountAndReset()); // resize and add 374 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 375 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 376 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 377 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 378 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 379 EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString()); 380 381 // Keep the minimum 100. 382 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 490); 383 EXPECT_EQ(1, observer.CountAndReset()); // resize and add 384 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 385 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 386 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 387 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 388 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 389 EXPECT_EQ("500,400 400x400", GetSecondaryDisplay().bounds().ToString()); 390 391 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, -400); 392 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 393 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 394 EXPECT_EQ(1, observer.CountAndReset()); // resize and add 395 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 396 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 397 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 398 EXPECT_EQ("500,-300 400x400", GetSecondaryDisplay().bounds().ToString()); 399 400 // Layout to the bottom with an offset. 401 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -200); 402 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 403 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 404 EXPECT_EQ(1, observer.CountAndReset()); // resize and add 405 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 406 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 407 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 408 EXPECT_EQ("-200,500 400x400", GetSecondaryDisplay().bounds().ToString()); 409 410 // Keep the minimum 100. 411 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, 490); 412 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 413 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 414 EXPECT_EQ(1, observer.CountAndReset()); // resize and add 415 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 416 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 417 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 418 EXPECT_EQ("400,500 400x400", GetSecondaryDisplay().bounds().ToString()); 419 420 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400); 421 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset()); 422 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset()); 423 EXPECT_EQ(1, observer.CountAndReset()); // resize and add 424 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 425 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 426 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 427 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString()); 428 429 // Setting the same layout shouldn't invoke observers. 430 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400); 431 EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset()); 432 EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset()); 433 EXPECT_EQ(0, observer.CountAndReset()); // resize and add 434 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 435 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 436 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString()); 437 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString()); 438 439 UpdateDisplay("500x500"); 440 EXPECT_LE(1, observer.GetFocusChangedCountAndReset()); 441 EXPECT_LE(1, observer.GetActivationChangedCountAndReset()); 442 } 443 444 namespace { 445 446 internal::DisplayInfo CreateDisplayInfo(int64 id, 447 const gfx::Rect& bounds, 448 float device_scale_factor) { 449 internal::DisplayInfo info(id, "", false); 450 info.SetBounds(bounds); 451 info.set_device_scale_factor(device_scale_factor); 452 return info; 453 } 454 455 } // namespace 456 457 TEST_F(DisplayControllerTest, MirrorToDockedWithFullscreen) { 458 // Creates windows to catch activation change event. 459 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1)); 460 w1->Focus(); 461 462 // Docked mode. 463 internal::DisplayManager* display_manager = 464 Shell::GetInstance()->display_manager(); 465 466 const internal::DisplayInfo internal_display_info = 467 CreateDisplayInfo(1, gfx::Rect(0, 0, 500, 500), 2.0f); 468 const internal::DisplayInfo external_display_info = 469 CreateDisplayInfo(2, gfx::Rect(0, 0, 500, 500), 1.0f); 470 471 std::vector<internal::DisplayInfo> display_info_list; 472 // Mirror. 473 display_info_list.push_back(internal_display_info); 474 display_info_list.push_back(external_display_info); 475 display_manager->OnNativeDisplaysChanged(display_info_list); 476 const int64 internal_display_id = 477 test::DisplayManagerTestApi(display_manager). 478 SetFirstDisplayAsInternalDisplay(); 479 EXPECT_EQ(1, internal_display_id); 480 EXPECT_EQ(2U, display_manager->num_connected_displays()); 481 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 482 483 wm::WindowState* window_state = wm::GetWindowState(w1.get()); 484 window_state->ToggleFullscreen(); 485 EXPECT_TRUE(window_state->IsFullscreen()); 486 EXPECT_EQ("0,0 250x250", w1->bounds().ToString()); 487 // Dock mode. 488 TestObserver observer; 489 display_info_list.clear(); 490 display_info_list.push_back(external_display_info); 491 display_manager->OnNativeDisplaysChanged(display_info_list); 492 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 493 EXPECT_EQ(1U, display_manager->num_connected_displays()); 494 EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset()); 495 EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset()); 496 EXPECT_EQ(1, observer.CountAndReset()); 497 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 498 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 499 500 EXPECT_TRUE(window_state->IsFullscreen()); 501 EXPECT_EQ("0,0 500x500", w1->bounds().ToString()); 502 } 503 504 TEST_F(DisplayControllerTest, BoundsUpdated) { 505 if (!SupportsMultipleDisplays()) 506 return; 507 508 // Creates windows to catch activation change event. 509 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1)); 510 w1->Focus(); 511 512 TestObserver observer; 513 SetDefaultDisplayLayout(DisplayLayout::BOTTOM); 514 UpdateDisplay("200x200,300x300"); // layout, resize and add. 515 EXPECT_EQ(1, observer.CountAndReset()); 516 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 517 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 518 519 internal::DisplayManager* display_manager = 520 Shell::GetInstance()->display_manager(); 521 gfx::Insets insets(5, 5, 5, 5); 522 display_manager->UpdateWorkAreaOfDisplay( 523 ScreenAsh::GetSecondaryDisplay().id(), insets); 524 525 EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString()); 526 EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString()); 527 EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString()); 528 529 UpdateDisplay("400x400,200x200"); 530 EXPECT_EQ(1, observer.CountAndReset()); // two resizes 531 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 532 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 533 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString()); 534 EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString()); 535 536 UpdateDisplay("400x400,300x300"); 537 EXPECT_EQ(1, observer.CountAndReset()); 538 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 539 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 540 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString()); 541 EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString()); 542 543 UpdateDisplay("400x400"); 544 EXPECT_EQ(1, observer.CountAndReset()); 545 EXPECT_LE(1, observer.GetFocusChangedCountAndReset()); 546 EXPECT_LE(1, observer.GetActivationChangedCountAndReset()); 547 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString()); 548 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); 549 550 UpdateDisplay("400x500*2,300x300"); 551 EXPECT_EQ(1, observer.CountAndReset()); 552 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 553 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 554 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 555 EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString()); 556 EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString()); 557 558 // No change 559 UpdateDisplay("400x500*2,300x300"); 560 EXPECT_EQ(0, observer.CountAndReset()); 561 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 562 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 563 564 // Rotation 565 int64 primary_id = GetPrimaryDisplay().id(); 566 display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90); 567 EXPECT_EQ(1, observer.CountAndReset()); 568 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 569 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 570 display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90); 571 EXPECT_EQ(0, observer.CountAndReset()); 572 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 573 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 574 575 // UI scale is eanbled only on internal display. 576 int64 secondary_id = GetSecondaryDisplay().id(); 577 gfx::Display::SetInternalDisplayId(secondary_id); 578 display_manager->SetDisplayUIScale(secondary_id, 1.125f); 579 EXPECT_EQ(1, observer.CountAndReset()); 580 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 581 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 582 display_manager->SetDisplayUIScale(secondary_id, 1.125f); 583 EXPECT_EQ(0, observer.CountAndReset()); 584 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 585 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 586 display_manager->SetDisplayUIScale(primary_id, 1.125f); 587 EXPECT_EQ(0, observer.CountAndReset()); 588 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 589 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 590 display_manager->SetDisplayUIScale(primary_id, 1.125f); 591 EXPECT_EQ(0, observer.CountAndReset()); 592 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 593 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 594 } 595 596 TEST_F(DisplayControllerTest, SwapPrimary) { 597 if (!SupportsMultipleDisplays()) 598 return; 599 600 DisplayController* display_controller = 601 Shell::GetInstance()->display_controller(); 602 internal::DisplayManager* display_manager = 603 Shell::GetInstance()->display_manager(); 604 605 UpdateDisplay("200x200,300x300"); 606 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 607 gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); 608 609 DisplayLayout display_layout(DisplayLayout::RIGHT, 50); 610 display_manager->SetLayoutForCurrentDisplays(display_layout); 611 612 EXPECT_NE(primary_display.id(), secondary_display.id()); 613 aura::Window* primary_root = 614 display_controller->GetRootWindowForDisplayId(primary_display.id()); 615 aura::Window* secondary_root = 616 display_controller->GetRootWindowForDisplayId(secondary_display.id()); 617 EXPECT_NE(primary_root, secondary_root); 618 aura::Window* launcher_window = 619 Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView(); 620 EXPECT_TRUE(primary_root->Contains(launcher_window)); 621 EXPECT_FALSE(secondary_root->Contains(launcher_window)); 622 EXPECT_EQ(primary_display.id(), 623 Shell::GetScreen()->GetDisplayNearestPoint( 624 gfx::Point(-100, -100)).id()); 625 EXPECT_EQ(primary_display.id(), 626 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); 627 628 EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString()); 629 EXPECT_EQ("0,0 200x153", primary_display.work_area().ToString()); 630 EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString()); 631 EXPECT_EQ("200,0 300x253", secondary_display.work_area().ToString()); 632 EXPECT_EQ("right, 50", 633 display_manager->GetCurrentDisplayLayout().ToString()); 634 635 // Switch primary and secondary 636 display_controller->SetPrimaryDisplay(secondary_display); 637 const DisplayLayout& inverted_layout = 638 display_manager->GetCurrentDisplayLayout(); 639 EXPECT_EQ("left, -50", inverted_layout.ToString()); 640 641 EXPECT_EQ(secondary_display.id(), 642 Shell::GetScreen()->GetPrimaryDisplay().id()); 643 EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); 644 EXPECT_EQ(secondary_display.id(), 645 Shell::GetScreen()->GetDisplayNearestPoint( 646 gfx::Point(-100, -100)).id()); 647 EXPECT_EQ(secondary_display.id(), 648 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); 649 650 EXPECT_EQ( 651 primary_root, 652 display_controller->GetRootWindowForDisplayId(secondary_display.id())); 653 EXPECT_EQ( 654 secondary_root, 655 display_controller->GetRootWindowForDisplayId(primary_display.id())); 656 EXPECT_TRUE(primary_root->Contains(launcher_window)); 657 EXPECT_FALSE(secondary_root->Contains(launcher_window)); 658 659 // Test if the bounds are correctly swapped. 660 gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay(); 661 gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay(); 662 EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString()); 663 EXPECT_EQ("0,0 300x253", swapped_primary.work_area().ToString()); 664 EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString()); 665 666 EXPECT_EQ("-200,-50 200x153", swapped_secondary.work_area().ToString()); 667 668 aura::WindowTracker tracker; 669 tracker.Add(primary_root); 670 tracker.Add(secondary_root); 671 672 // Deleting 2nd display should move the primary to original primary display. 673 UpdateDisplay("200x200"); 674 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. 675 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); 676 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); 677 EXPECT_EQ(primary_display.id(), 678 Shell::GetScreen()->GetDisplayNearestPoint( 679 gfx::Point(-100, -100)).id()); 680 EXPECT_EQ(primary_display.id(), 681 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); 682 EXPECT_TRUE(tracker.Contains(primary_root)); 683 EXPECT_FALSE(tracker.Contains(secondary_root)); 684 EXPECT_TRUE(primary_root->Contains(launcher_window)); 685 } 686 687 TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) { 688 if (!SupportsMultipleDisplays()) 689 return; 690 691 CommandLine::ForCurrentProcess()->AppendSwitch( 692 ash::switches::kAshDisableAlternateShelfLayout); 693 694 DisplayController* display_controller = 695 Shell::GetInstance()->display_controller(); 696 internal::DisplayManager* display_manager = 697 Shell::GetInstance()->display_manager(); 698 699 UpdateDisplay("200x200,300x300"); 700 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 701 gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); 702 703 DisplayLayout display_layout(DisplayLayout::RIGHT, 50); 704 display_manager->SetLayoutForCurrentDisplays(display_layout); 705 706 EXPECT_NE(primary_display.id(), secondary_display.id()); 707 aura::Window* primary_root = 708 display_controller->GetRootWindowForDisplayId(primary_display.id()); 709 aura::Window* secondary_root = 710 display_controller->GetRootWindowForDisplayId(secondary_display.id()); 711 EXPECT_NE(primary_root, secondary_root); 712 aura::Window* launcher_window = 713 Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView(); 714 EXPECT_TRUE(primary_root->Contains(launcher_window)); 715 EXPECT_FALSE(secondary_root->Contains(launcher_window)); 716 EXPECT_EQ(primary_display.id(), 717 Shell::GetScreen()->GetDisplayNearestPoint( 718 gfx::Point(-100, -100)).id()); 719 EXPECT_EQ(primary_display.id(), 720 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); 721 722 EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString()); 723 EXPECT_EQ("0,0 200x152", primary_display.work_area().ToString()); 724 EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString()); 725 EXPECT_EQ("200,0 300x252", secondary_display.work_area().ToString()); 726 EXPECT_EQ("right, 50", 727 display_manager->GetCurrentDisplayLayout().ToString()); 728 729 // Switch primary and secondary 730 display_controller->SetPrimaryDisplay(secondary_display); 731 const DisplayLayout& inverted_layout = 732 display_manager->GetCurrentDisplayLayout(); 733 EXPECT_EQ("left, -50", inverted_layout.ToString()); 734 735 EXPECT_EQ(secondary_display.id(), 736 Shell::GetScreen()->GetPrimaryDisplay().id()); 737 EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); 738 EXPECT_EQ(secondary_display.id(), 739 Shell::GetScreen()->GetDisplayNearestPoint( 740 gfx::Point(-100, -100)).id()); 741 EXPECT_EQ(secondary_display.id(), 742 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); 743 744 EXPECT_EQ( 745 primary_root, 746 display_controller->GetRootWindowForDisplayId(secondary_display.id())); 747 EXPECT_EQ( 748 secondary_root, 749 display_controller->GetRootWindowForDisplayId(primary_display.id())); 750 EXPECT_TRUE(primary_root->Contains(launcher_window)); 751 EXPECT_FALSE(secondary_root->Contains(launcher_window)); 752 753 // Test if the bounds are correctly swapped. 754 gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay(); 755 gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay(); 756 EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString()); 757 EXPECT_EQ("0,0 300x252", swapped_primary.work_area().ToString()); 758 EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString()); 759 760 EXPECT_EQ("-200,-50 200x152", swapped_secondary.work_area().ToString()); 761 762 aura::WindowTracker tracker; 763 tracker.Add(primary_root); 764 tracker.Add(secondary_root); 765 766 // Deleting 2nd display should move the primary to original primary display. 767 UpdateDisplay("200x200"); 768 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. 769 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); 770 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); 771 EXPECT_EQ(primary_display.id(), 772 Shell::GetScreen()->GetDisplayNearestPoint( 773 gfx::Point(-100, -100)).id()); 774 EXPECT_EQ(primary_display.id(), 775 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); 776 EXPECT_TRUE(tracker.Contains(primary_root)); 777 EXPECT_FALSE(tracker.Contains(secondary_root)); 778 EXPECT_TRUE(primary_root->Contains(launcher_window)); 779 } 780 781 TEST_F(DisplayControllerTest, SwapPrimaryById) { 782 if (!SupportsMultipleDisplays()) 783 return; 784 785 DisplayController* display_controller = 786 Shell::GetInstance()->display_controller(); 787 internal::DisplayManager* display_manager = 788 Shell::GetInstance()->display_manager(); 789 790 UpdateDisplay("200x200,300x300"); 791 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 792 gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); 793 794 DisplayLayout display_layout(DisplayLayout::RIGHT, 50); 795 display_manager->SetLayoutForCurrentDisplays(display_layout); 796 797 EXPECT_NE(primary_display.id(), secondary_display.id()); 798 aura::Window* primary_root = 799 display_controller->GetRootWindowForDisplayId(primary_display.id()); 800 aura::Window* secondary_root = 801 display_controller->GetRootWindowForDisplayId(secondary_display.id()); 802 aura::Window* launcher_window = 803 Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView(); 804 EXPECT_TRUE(primary_root->Contains(launcher_window)); 805 EXPECT_FALSE(secondary_root->Contains(launcher_window)); 806 EXPECT_NE(primary_root, secondary_root); 807 EXPECT_EQ(primary_display.id(), 808 Shell::GetScreen()->GetDisplayNearestPoint( 809 gfx::Point(-100, -100)).id()); 810 EXPECT_EQ(primary_display.id(), 811 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); 812 813 // Switch primary and secondary by display ID. 814 TestObserver observer; 815 display_controller->SetPrimaryDisplayId(secondary_display.id()); 816 EXPECT_EQ(secondary_display.id(), 817 Shell::GetScreen()->GetPrimaryDisplay().id()); 818 EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); 819 EXPECT_LT(0, observer.CountAndReset()); 820 821 EXPECT_EQ( 822 primary_root, 823 display_controller->GetRootWindowForDisplayId(secondary_display.id())); 824 EXPECT_EQ( 825 secondary_root, 826 display_controller->GetRootWindowForDisplayId(primary_display.id())); 827 EXPECT_TRUE(primary_root->Contains(launcher_window)); 828 EXPECT_FALSE(secondary_root->Contains(launcher_window)); 829 830 const DisplayLayout& inverted_layout = 831 display_manager->GetCurrentDisplayLayout(); 832 833 EXPECT_EQ("left, -50", inverted_layout.ToString()); 834 835 // Calling the same ID don't do anything. 836 display_controller->SetPrimaryDisplayId(secondary_display.id()); 837 EXPECT_EQ(0, observer.CountAndReset()); 838 839 aura::WindowTracker tracker; 840 tracker.Add(primary_root); 841 tracker.Add(secondary_root); 842 843 // Deleting 2nd display should move the primary to original primary display. 844 UpdateDisplay("200x200"); 845 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. 846 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); 847 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); 848 EXPECT_EQ(primary_display.id(), 849 Shell::GetScreen()->GetDisplayNearestPoint( 850 gfx::Point(-100, -100)).id()); 851 EXPECT_EQ(primary_display.id(), 852 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id()); 853 EXPECT_TRUE(tracker.Contains(primary_root)); 854 EXPECT_FALSE(tracker.Contains(secondary_root)); 855 EXPECT_TRUE(primary_root->Contains(launcher_window)); 856 857 // Adding 2nd display with the same ID. The 2nd display should become primary 858 // since secondary id is still stored as desirable_primary_id. 859 std::vector<internal::DisplayInfo> display_info_list; 860 display_info_list.push_back( 861 display_manager->GetDisplayInfo(primary_display.id())); 862 display_info_list.push_back( 863 display_manager->GetDisplayInfo(secondary_display.id())); 864 display_manager->OnNativeDisplaysChanged(display_info_list); 865 866 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 867 EXPECT_EQ(secondary_display.id(), 868 Shell::GetScreen()->GetPrimaryDisplay().id()); 869 EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); 870 EXPECT_EQ( 871 primary_root, 872 display_controller->GetRootWindowForDisplayId(secondary_display.id())); 873 EXPECT_NE( 874 primary_root, 875 display_controller->GetRootWindowForDisplayId(primary_display.id())); 876 EXPECT_TRUE(primary_root->Contains(launcher_window)); 877 878 // Deleting 2nd display and adding 2nd display with a different ID. The 2nd 879 // display shouldn't become primary. 880 UpdateDisplay("200x200"); 881 internal::DisplayInfo third_display_info( 882 secondary_display.id() + 1, std::string(), false); 883 third_display_info.SetBounds(secondary_display.bounds()); 884 ASSERT_NE(primary_display.id(), third_display_info.id()); 885 886 const internal::DisplayInfo& primary_display_info = 887 display_manager->GetDisplayInfo(primary_display.id()); 888 std::vector<internal::DisplayInfo> display_info_list2; 889 display_info_list2.push_back(primary_display_info); 890 display_info_list2.push_back(third_display_info); 891 display_manager->OnNativeDisplaysChanged(display_info_list2); 892 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 893 EXPECT_EQ(primary_display.id(), 894 Shell::GetScreen()->GetPrimaryDisplay().id()); 895 EXPECT_EQ(third_display_info.id(), ScreenAsh::GetSecondaryDisplay().id()); 896 EXPECT_EQ( 897 primary_root, 898 display_controller->GetRootWindowForDisplayId(primary_display.id())); 899 EXPECT_NE( 900 primary_root, 901 display_controller->GetRootWindowForDisplayId(third_display_info.id())); 902 EXPECT_TRUE(primary_root->Contains(launcher_window)); 903 } 904 905 TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) { 906 if (!SupportsMultipleDisplays()) 907 return; 908 909 DisplayController* display_controller = 910 Shell::GetInstance()->display_controller(); 911 912 UpdateDisplay("200x200,200x200*2"); 913 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 914 gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); 915 916 aura::Window* primary_root = 917 display_controller->GetRootWindowForDisplayId(primary_display.id()); 918 aura::Window* secondary_root = 919 display_controller->GetRootWindowForDisplayId(secondary_display.id()); 920 EXPECT_NE(primary_root, secondary_root); 921 922 test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager()); 923 924 EXPECT_EQ(1.0f, primary_root->GetDispatcher()->AsRootWindowHostDelegate()-> 925 GetDeviceScaleFactor()); 926 primary_root->MoveCursorTo(gfx::Point(50, 50)); 927 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); 928 EXPECT_EQ(2.0f, secondary_root->GetDispatcher()->AsRootWindowHostDelegate()-> 929 GetDeviceScaleFactor()); 930 secondary_root->MoveCursorTo(gfx::Point(50, 50)); 931 EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor()); 932 933 // Switch primary and secondary 934 display_controller->SetPrimaryDisplay(secondary_display); 935 936 // Cursor's device scale factor should be updated accroding to the swap of 937 // primary and secondary. 938 EXPECT_EQ(1.0f, secondary_root->GetDispatcher()->AsRootWindowHostDelegate()-> 939 GetDeviceScaleFactor()); 940 secondary_root->MoveCursorTo(gfx::Point(50, 50)); 941 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); 942 primary_root->MoveCursorTo(gfx::Point(50, 50)); 943 EXPECT_EQ(2.0f, primary_root->GetDispatcher()->AsRootWindowHostDelegate()-> 944 GetDeviceScaleFactor()); 945 EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor()); 946 947 // Deleting 2nd display. 948 UpdateDisplay("200x200"); 949 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. 950 951 // Cursor's device scale factor should be updated even without moving cursor. 952 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); 953 954 primary_root->MoveCursorTo(gfx::Point(50, 50)); 955 EXPECT_EQ(1.0f, primary_root->GetDispatcher()->AsRootWindowHostDelegate()-> 956 GetDeviceScaleFactor()); 957 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); 958 } 959 960 TEST_F(DisplayControllerTest, OverscanInsets) { 961 if (!SupportsMultipleDisplays()) 962 return; 963 964 DisplayController* display_controller = 965 Shell::GetInstance()->display_controller(); 966 TestEventHandler event_handler; 967 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 968 969 UpdateDisplay("120x200,300x400*2"); 970 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 971 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 972 973 display_controller->SetOverscanInsets(display1.id(), 974 gfx::Insets(10, 15, 20, 25)); 975 EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString()); 976 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); 977 EXPECT_EQ("80,0 150x200", 978 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 979 980 aura::test::EventGenerator generator(root_windows[0]); 981 generator.MoveMouseToInHost(20, 25); 982 EXPECT_EQ("5,15", event_handler.GetLocationAndReset()); 983 984 display_controller->SetOverscanInsets(display1.id(), gfx::Insets()); 985 EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString()); 986 EXPECT_EQ("120,0 150x200", 987 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 988 989 generator.MoveMouseToInHost(30, 20); 990 EXPECT_EQ("30,20", event_handler.GetLocationAndReset()); 991 992 // Make sure the root window transformer uses correct scale 993 // factor when swapping display. Test crbug.com/253690. 994 UpdateDisplay("400x300*2,600x400/o"); 995 root_windows = Shell::GetAllRootWindows(); 996 gfx::Point point; 997 Shell::GetAllRootWindows()[1]->GetDispatcher()-> 998 GetRootTransform().TransformPoint(&point); 999 EXPECT_EQ("15,10", point.ToString()); 1000 1001 display_controller->SwapPrimaryDisplay(); 1002 point.SetPoint(0, 0); 1003 Shell::GetAllRootWindows()[1]->GetDispatcher()-> 1004 GetRootTransform().TransformPoint(&point); 1005 EXPECT_EQ("15,10", point.ToString()); 1006 1007 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1008 } 1009 1010 TEST_F(DisplayControllerTest, Rotate) { 1011 if (!SupportsMultipleDisplays()) 1012 return; 1013 1014 internal::DisplayManager* display_manager = 1015 Shell::GetInstance()->display_manager(); 1016 TestEventHandler event_handler; 1017 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1018 1019 UpdateDisplay("120x200,300x400*2"); 1020 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 1021 int64 display2_id = ScreenAsh::GetSecondaryDisplay().id(); 1022 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 1023 aura::test::EventGenerator generator1(root_windows[0]); 1024 1025 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); 1026 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); 1027 EXPECT_EQ("120,0 150x200", 1028 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 1029 generator1.MoveMouseToInHost(50, 40); 1030 EXPECT_EQ("50,40", event_handler.GetLocationAndReset()); 1031 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id())); 1032 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); 1033 1034 display_manager->SetDisplayRotation(display1.id(), 1035 gfx::Display::ROTATE_90); 1036 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); 1037 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); 1038 EXPECT_EQ("200,0 150x200", 1039 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 1040 generator1.MoveMouseToInHost(50, 40); 1041 EXPECT_EQ("40,69", event_handler.GetLocationAndReset()); 1042 EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); 1043 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); 1044 1045 DisplayLayout display_layout(DisplayLayout::BOTTOM, 50); 1046 display_manager->SetLayoutForCurrentDisplays(display_layout); 1047 EXPECT_EQ("50,120 150x200", 1048 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 1049 1050 display_manager->SetDisplayRotation(display2_id, 1051 gfx::Display::ROTATE_270); 1052 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); 1053 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); 1054 EXPECT_EQ("50,120 200x150", 1055 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 1056 EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); 1057 EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); 1058 1059 #if !defined(OS_WIN) 1060 aura::test::EventGenerator generator2(root_windows[1]); 1061 generator2.MoveMouseToInHost(50, 40); 1062 EXPECT_EQ("179,25", event_handler.GetLocationAndReset()); 1063 display_manager->SetDisplayRotation(display1.id(), 1064 gfx::Display::ROTATE_180); 1065 1066 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); 1067 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); 1068 // Dislay must share at least 100, so the x's offset becomes 20. 1069 EXPECT_EQ("20,200 200x150", 1070 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 1071 EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id())); 1072 EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); 1073 1074 generator1.MoveMouseToInHost(50, 40); 1075 EXPECT_EQ("69,159", event_handler.GetLocationAndReset()); 1076 #endif 1077 1078 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1079 } 1080 1081 TEST_F(DisplayControllerTest, ScaleRootWindow) { 1082 if (!SupportsMultipleDisplays()) 1083 return; 1084 1085 TestEventHandler event_handler; 1086 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1087 1088 UpdateDisplay("600x400*2 (at) 1.5,500x300"); 1089 1090 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 1091 gfx::Display::SetInternalDisplayId(display1.id()); 1092 1093 gfx::Display display2 = ScreenAsh::GetSecondaryDisplay(); 1094 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 1095 EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); 1096 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); 1097 EXPECT_EQ("450,0 500x300", display2.bounds().ToString()); 1098 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); 1099 EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); 1100 1101 aura::test::EventGenerator generator(root_windows[0]); 1102 generator.MoveMouseToInHost(599, 200); 1103 EXPECT_EQ("449,150", event_handler.GetLocationAndReset()); 1104 1105 internal::DisplayManager* display_manager = 1106 Shell::GetInstance()->display_manager(); 1107 display_manager->SetDisplayUIScale(display1.id(), 1.25f); 1108 display1 = Shell::GetScreen()->GetPrimaryDisplay(); 1109 display2 = ScreenAsh::GetSecondaryDisplay(); 1110 EXPECT_EQ("0,0 375x250", display1.bounds().ToString()); 1111 EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString()); 1112 EXPECT_EQ("375,0 500x300", display2.bounds().ToString()); 1113 EXPECT_EQ(1.25f, GetStoredUIScale(display1.id())); 1114 EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); 1115 1116 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1117 } 1118 1119 TEST_F(DisplayControllerTest, TouchScale) { 1120 if (!SupportsMultipleDisplays()) 1121 return; 1122 1123 TestEventHandler event_handler; 1124 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1125 1126 UpdateDisplay("200x200*2"); 1127 gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay(); 1128 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 1129 aura::Window* root_window = root_windows[0]; 1130 aura::test::EventGenerator generator(root_window); 1131 1132 generator.PressMoveAndReleaseTouchTo(50, 50); 1133 // Default test touches have radius_x/y = 1.0, with device scale 1134 // factor = 2, the scaled radius_x/y should be 0.5. 1135 EXPECT_EQ(0.5, event_handler.touch_radius_x()); 1136 EXPECT_EQ(0.5, event_handler.touch_radius_y()); 1137 1138 generator.ScrollSequence(gfx::Point(0,0), 1139 base::TimeDelta::FromMilliseconds(100), 1140 10.0, 1.0, 5, 1); 1141 1142 // ordinal_offset is invariant to the device scale factor. 1143 EXPECT_EQ(event_handler.scroll_x_offset(), 1144 event_handler.scroll_x_offset_ordinal()); 1145 EXPECT_EQ(event_handler.scroll_y_offset(), 1146 event_handler.scroll_y_offset_ordinal()); 1147 1148 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1149 } 1150 1151 TEST_F(DisplayControllerTest, ConvertHostToRootCoords) { 1152 if (!SupportsMultipleDisplays()) 1153 return; 1154 1155 TestEventHandler event_handler; 1156 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1157 1158 UpdateDisplay("600x400*2/r (at) 1.5"); 1159 1160 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 1161 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 1162 EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); 1163 EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); 1164 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); 1165 1166 aura::test::EventGenerator generator(root_windows[0]); 1167 generator.MoveMouseToInHost(0, 0); 1168 EXPECT_EQ("0,449", event_handler.GetLocationAndReset()); 1169 generator.MoveMouseToInHost(599, 0); 1170 EXPECT_EQ("0,0", event_handler.GetLocationAndReset()); 1171 generator.MoveMouseToInHost(599, 399); 1172 EXPECT_EQ("299,0", event_handler.GetLocationAndReset()); 1173 generator.MoveMouseToInHost(0, 399); 1174 EXPECT_EQ("299,449", event_handler.GetLocationAndReset()); 1175 1176 UpdateDisplay("600x400*2/u (at) 1.5"); 1177 display1 = Shell::GetScreen()->GetPrimaryDisplay(); 1178 root_windows = Shell::GetAllRootWindows(); 1179 EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); 1180 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); 1181 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); 1182 1183 generator.MoveMouseToInHost(0, 0); 1184 EXPECT_EQ("449,299", event_handler.GetLocationAndReset()); 1185 generator.MoveMouseToInHost(599, 0); 1186 EXPECT_EQ("0,299", event_handler.GetLocationAndReset()); 1187 generator.MoveMouseToInHost(599, 399); 1188 EXPECT_EQ("0,0", event_handler.GetLocationAndReset()); 1189 generator.MoveMouseToInHost(0, 399); 1190 EXPECT_EQ("449,0", event_handler.GetLocationAndReset()); 1191 1192 UpdateDisplay("600x400*2/l (at) 1.5"); 1193 display1 = Shell::GetScreen()->GetPrimaryDisplay(); 1194 root_windows = Shell::GetAllRootWindows(); 1195 EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); 1196 EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); 1197 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); 1198 1199 generator.MoveMouseToInHost(0, 0); 1200 EXPECT_EQ("299,0", event_handler.GetLocationAndReset()); 1201 generator.MoveMouseToInHost(599, 0); 1202 EXPECT_EQ("299,449", event_handler.GetLocationAndReset()); 1203 generator.MoveMouseToInHost(599, 399); 1204 EXPECT_EQ("0,449", event_handler.GetLocationAndReset()); 1205 generator.MoveMouseToInHost(0, 399); 1206 EXPECT_EQ("0,0", event_handler.GetLocationAndReset()); 1207 1208 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1209 } 1210 1211 namespace { 1212 1213 internal::DisplayInfo CreateDisplayInfo(int64 id, 1214 int y, 1215 gfx::Display::Rotation rotation) { 1216 internal::DisplayInfo info(id, "", false); 1217 info.SetBounds(gfx::Rect(0, y, 500, 500)); 1218 info.set_rotation(rotation); 1219 return info; 1220 } 1221 1222 } // namespace 1223 1224 // Make sure that the compositor based mirroring can switch 1225 // from/to dock mode. 1226 TEST_F(DisplayControllerTest, DockToSingle) { 1227 if (!SupportsMultipleDisplays()) 1228 return; 1229 1230 internal::DisplayManager* display_manager = 1231 Shell::GetInstance()->display_manager(); 1232 1233 const int64 internal_id = 1; 1234 1235 const internal::DisplayInfo internal_display_info = 1236 CreateDisplayInfo(internal_id, 0, gfx::Display::ROTATE_0); 1237 const internal::DisplayInfo external_display_info = 1238 CreateDisplayInfo(2, 1, gfx::Display::ROTATE_90); 1239 1240 std::vector<internal::DisplayInfo> display_info_list; 1241 // Extended 1242 display_info_list.push_back(internal_display_info); 1243 display_info_list.push_back(external_display_info); 1244 display_manager->OnNativeDisplaysChanged(display_info_list); 1245 const int64 internal_display_id = 1246 test::DisplayManagerTestApi(display_manager). 1247 SetFirstDisplayAsInternalDisplay(); 1248 EXPECT_EQ(internal_id, internal_display_id); 1249 EXPECT_EQ(2U, display_manager->GetNumDisplays()); 1250 1251 // Dock mode. 1252 display_info_list.clear(); 1253 display_info_list.push_back(external_display_info); 1254 display_manager->OnNativeDisplaysChanged(display_info_list); 1255 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 1256 EXPECT_FALSE(Shell::GetPrimaryRootWindow()->GetDispatcher()-> 1257 GetRootTransform().IsIdentityOrIntegerTranslation()); 1258 1259 // Switch to single mode and make sure the transform is the one 1260 // for the internal display. 1261 display_info_list.clear(); 1262 display_info_list.push_back(internal_display_info); 1263 display_manager->OnNativeDisplaysChanged(display_info_list); 1264 EXPECT_TRUE(Shell::GetPrimaryRootWindow()->GetDispatcher()-> 1265 GetRootTransform().IsIdentityOrIntegerTranslation()); 1266 } 1267 1268 #if defined(USE_X11) 1269 TEST_F(DisplayControllerTest, XWidowNameForRootWindow) { 1270 EXPECT_EQ("aura_root_0", GetXWindowName( 1271 Shell::GetPrimaryRootWindow()->GetDispatcher())); 1272 1273 // Multiple display. 1274 UpdateDisplay("200x200,300x300"); 1275 aura::Window* primary, *secondary; 1276 GetPrimaryAndSeconary(&primary, &secondary); 1277 EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetDispatcher())); 1278 EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetDispatcher())); 1279 1280 // Swap primary. 1281 primary = secondary = NULL; 1282 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay(); 1283 GetPrimaryAndSeconary(&primary, &secondary); 1284 EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetDispatcher())); 1285 EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetDispatcher())); 1286 1287 // Switching back to single display. 1288 UpdateDisplay("300x400"); 1289 EXPECT_EQ("aura_root_0", GetXWindowName( 1290 Shell::GetPrimaryRootWindow()->GetDispatcher())); 1291 } 1292 #endif 1293 1294 } // namespace ash 1295