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