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.
5 #include "ash/display/display_controller.h"
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/screen_util.h"
12 #include "ash/shelf/shelf.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/ash_test_helper.h"
17 #include "ash/test/cursor_manager_test_api.h"
18 #include "ash/test/display_manager_test_api.h"
19 #include "ash/test/test_shell_delegate.h"
20 #include "ash/wm/window_state.h"
21 #include "ash/wm/wm_event.h"
22 #include "base/command_line.h"
23 #include "ui/aura/client/focus_change_observer.h"
24 #include "ui/aura/client/focus_client.h"
25 #include "ui/aura/env.h"
26 #include "ui/aura/window_tracker.h"
27 #include "ui/aura/window_tree_host.h"
28 #include "ui/events/event_handler.h"
29 #include "ui/events/test/event_generator.h"
30 #include "ui/gfx/display.h"
31 #include "ui/gfx/screen.h"
32 #include "ui/views/widget/widget.h"
33 #include "ui/wm/public/activation_change_observer.h"
34 #include "ui/wm/public/activation_client.h"
38 #include "ui/gfx/x/x11_types.h"
45 const char kDesktopBackgroundView[] = "DesktopBackgroundView";
50 explicit Resetter(T* value) : value_(*value) {
54 T value() { return value_; }
58 DISALLOW_COPY_AND_ASSIGN(Resetter);
61 class TestObserver : public DisplayController::Observer,
62 public gfx::DisplayObserver,
63 public aura::client::FocusChangeObserver,
64 public aura::client::ActivationChangeObserver {
69 bounds_changed_count_(0),
70 rotation_changed_count_(0),
71 workarea_changed_count_(0),
72 changed_display_id_(0),
73 focus_changed_count_(0),
74 activation_changed_count_(0) {
75 Shell::GetInstance()->display_controller()->AddObserver(this);
76 Shell::GetScreen()->AddObserver(this);
77 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
79 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
83 ~TestObserver() override {
84 Shell::GetInstance()->display_controller()->RemoveObserver(this);
85 Shell::GetScreen()->RemoveObserver(this);
86 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
88 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
92 // Overridden from DisplayController::Observer
93 void OnDisplayConfigurationChanging() override { ++changing_count_; }
94 void OnDisplayConfigurationChanged() override { ++changed_count_; }
96 // Overrideen from gfx::DisplayObserver
97 void OnDisplayMetricsChanged(const gfx::Display& display,
98 uint32_t metrics) override {
99 changed_display_id_ = display.id();
100 if (metrics & DISPLAY_METRIC_BOUNDS)
101 ++bounds_changed_count_;
102 if (metrics & DISPLAY_METRIC_ROTATION)
103 ++rotation_changed_count_;
104 if (metrics & DISPLAY_METRIC_WORK_AREA)
105 ++workarea_changed_count_;
107 void OnDisplayAdded(const gfx::Display& new_display) override {}
108 void OnDisplayRemoved(const gfx::Display& old_display) override {}
110 // Overridden from aura::client::FocusChangeObserver
111 void OnWindowFocused(aura::Window* gained_focus,
112 aura::Window* lost_focus) override {
113 focus_changed_count_++;
116 // Overridden from aura::client::ActivationChangeObserver
117 void OnWindowActivated(aura::Window* gained_active,
118 aura::Window* lost_active) override {
119 activation_changed_count_++;
121 void OnAttemptToReactivateWindow(aura::Window* request_active,
122 aura::Window* actual_active) override {}
124 int CountAndReset() {
125 EXPECT_EQ(changing_count_, changed_count_);
127 return Resetter<int>(&changing_count_).value();
130 int64 GetBoundsChangedCountAndReset() {
131 return Resetter<int>(&bounds_changed_count_).value();
134 int64 GetRotationChangedCountAndReset() {
135 return Resetter<int>(&rotation_changed_count_).value();
138 int64 GetWorkareaChangedCountAndReset() {
139 return Resetter<int>(&workarea_changed_count_).value();
142 int64 GetChangedDisplayIdAndReset() {
143 return Resetter<int64>(&changed_display_id_).value();
146 int GetFocusChangedCountAndReset() {
147 return Resetter<int>(&focus_changed_count_).value();
150 int GetActivationChangedCountAndReset() {
151 return Resetter<int>(&activation_changed_count_).value();
158 int bounds_changed_count_;
159 int rotation_changed_count_;
160 int workarea_changed_count_;
161 int64 changed_display_id_;
163 int focus_changed_count_;
164 int activation_changed_count_;
166 DISALLOW_COPY_AND_ASSIGN(TestObserver);
169 gfx::Display GetPrimaryDisplay() {
170 return Shell::GetScreen()->GetDisplayNearestWindow(
171 Shell::GetAllRootWindows()[0]);
174 gfx::Display GetSecondaryDisplay() {
175 return Shell::GetScreen()->GetDisplayNearestWindow(
176 Shell::GetAllRootWindows()[1]);
179 void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position,
181 DisplayLayout layout(position, offset);
182 ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1);
183 Shell::GetInstance()->display_manager()->
184 SetLayoutForCurrentDisplays(layout);
187 void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
188 SetSecondaryDisplayLayoutAndOffset(position, 0);
191 void SetDefaultDisplayLayout(DisplayLayout::Position position) {
192 Shell::GetInstance()->display_manager()->layout_store()->
193 SetDefaultDisplayLayout(DisplayLayout(position, 0));
196 class DisplayControllerShutdownTest : public test::AshTestBase {
198 DisplayControllerShutdownTest() {}
199 ~DisplayControllerShutdownTest() override {}
201 void TearDown() override {
202 test::AshTestBase::TearDown();
203 if (!SupportsMultipleDisplays())
206 // Make sure that primary display is accessible after shutdown.
207 gfx::Display primary = Shell::GetScreen()->GetPrimaryDisplay();
208 EXPECT_EQ("0,0 444x333", primary.bounds().ToString());
209 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
213 DISALLOW_COPY_AND_ASSIGN(DisplayControllerShutdownTest);
216 class StartupHelper : public test::TestShellDelegate,
217 public DisplayController::Observer {
219 StartupHelper() : displays_initialized_(false) {}
220 ~StartupHelper() override {}
222 // ash::ShellSelegate:
223 void PreInit() override {
224 Shell::GetInstance()->display_controller()->AddObserver(this);
227 // ash::DisplayController::Observer:
228 void OnDisplaysInitialized() override {
229 DCHECK(!displays_initialized_);
230 displays_initialized_ = true;
233 bool displays_initialized() const {
234 return displays_initialized_;
238 bool displays_initialized_;
240 DISALLOW_COPY_AND_ASSIGN(StartupHelper);
243 class DisplayControllerStartupTest : public test::AshTestBase {
245 DisplayControllerStartupTest() : startup_helper_(new StartupHelper) {}
246 ~DisplayControllerStartupTest() override {}
248 // ash::test::AshTestBase:
249 void SetUp() override {
250 ash_test_helper()->set_test_shell_delegate(startup_helper_);
251 test::AshTestBase::SetUp();
253 void TearDown() override {
254 Shell::GetInstance()->display_controller()->RemoveObserver(startup_helper_);
255 test::AshTestBase::TearDown();
258 const StartupHelper* startup_helper() const { return startup_helper_; }
261 StartupHelper* startup_helper_; // Owned by ash::Shell.
263 DISALLOW_COPY_AND_ASSIGN(DisplayControllerStartupTest);
266 class TestEventHandler : public ui::EventHandler {
268 TestEventHandler() : target_root_(NULL),
269 touch_radius_x_(0.0),
270 touch_radius_y_(0.0),
271 scroll_x_offset_(0.0),
272 scroll_y_offset_(0.0),
273 scroll_x_offset_ordinal_(0.0),
274 scroll_y_offset_ordinal_(0.0) {}
275 ~TestEventHandler() override {}
277 void OnMouseEvent(ui::MouseEvent* event) override {
278 if (event->flags() & ui::EF_IS_SYNTHESIZED &&
279 event->type() != ui::ET_MOUSE_EXITED &&
280 event->type() != ui::ET_MOUSE_ENTERED) {
283 aura::Window* target = static_cast<aura::Window*>(event->target());
284 mouse_location_ = event->root_location();
285 target_root_ = target->GetRootWindow();
286 event->StopPropagation();
289 void OnTouchEvent(ui::TouchEvent* event) override {
290 aura::Window* target = static_cast<aura::Window*>(event->target());
291 // Only record when the target is the background which covers
292 // entire root window.
293 if (target->name() != kDesktopBackgroundView)
295 touch_radius_x_ = event->radius_x();
296 touch_radius_y_ = event->radius_y();
297 event->StopPropagation();
300 void OnScrollEvent(ui::ScrollEvent* event) override {
301 aura::Window* target = static_cast<aura::Window*>(event->target());
302 // Only record when the target is the background which covers
303 // entire root window.
304 if (target->name() != kDesktopBackgroundView)
307 if (event->type() == ui::ET_SCROLL) {
308 scroll_x_offset_ = event->x_offset();
309 scroll_y_offset_ = event->y_offset();
310 scroll_x_offset_ordinal_ = event->x_offset_ordinal();
311 scroll_y_offset_ordinal_ = event->y_offset_ordinal();
313 event->StopPropagation();
316 std::string GetLocationAndReset() {
317 std::string result = mouse_location_.ToString();
318 mouse_location_.SetPoint(0, 0);
323 float touch_radius_x() { return touch_radius_x_; }
324 float touch_radius_y() { return touch_radius_y_; }
325 float scroll_x_offset() { return scroll_x_offset_; }
326 float scroll_y_offset() { return scroll_y_offset_; }
327 float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_; }
328 float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_; }
331 gfx::Point mouse_location_;
332 aura::Window* target_root_;
334 float touch_radius_x_;
335 float touch_radius_y_;
336 float scroll_x_offset_;
337 float scroll_y_offset_;
338 float scroll_x_offset_ordinal_;
339 float scroll_y_offset_ordinal_;
341 DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
344 gfx::Display::Rotation GetStoredRotation(int64 id) {
345 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation();
348 float GetStoredUIScale(int64 id) {
349 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).
350 GetEffectiveUIScale();
354 void GetPrimaryAndSeconary(aura::Window** primary,
355 aura::Window** secondary) {
356 *primary = Shell::GetPrimaryRootWindow();
357 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
358 *secondary = root_windows[0] == *primary ? root_windows[1] : root_windows[0];
361 std::string GetXWindowName(aura::WindowTreeHost* host) {
363 XFetchName(gfx::GetXDisplay(), host->GetAcceleratedWidget(), &name);
364 std::string ret(name);
372 typedef test::AshTestBase DisplayControllerTest;
374 TEST_F(DisplayControllerShutdownTest, Shutdown) {
375 if (!SupportsMultipleDisplays())
378 UpdateDisplay("444x333, 200x200");
381 TEST_F(DisplayControllerStartupTest, Startup) {
382 if (!SupportsMultipleDisplays())
385 EXPECT_TRUE(startup_helper()->displays_initialized());
388 TEST_F(DisplayControllerTest, SecondaryDisplayLayout) {
389 if (!SupportsMultipleDisplays())
392 // Creates windows to catch activation change event.
393 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
396 TestObserver observer;
397 UpdateDisplay("500x500,400x400");
398 EXPECT_EQ(1, observer.CountAndReset()); // resize and add
399 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
400 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
401 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
402 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
403 gfx::Insets insets(5, 5, 5, 5);
404 int64 secondary_display_id = ScreenUtil::GetSecondaryDisplay().id();
405 Shell::GetInstance()->display_manager()->UpdateWorkAreaOfDisplay(
406 secondary_display_id, insets);
408 // Default layout is RIGHT.
409 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
410 EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
411 EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());
412 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
413 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
415 // Layout the secondary display to the bottom of the primary.
416 SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
417 EXPECT_EQ(1, observer.CountAndReset());
418 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
419 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
420 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
421 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
422 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
423 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
424 EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
425 EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());
427 // Layout the secondary display to the left of the primary.
428 SetSecondaryDisplayLayout(DisplayLayout::LEFT);
429 EXPECT_EQ(1, observer.CountAndReset());
430 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
431 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
432 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
433 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
434 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
435 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
436 EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
437 EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());
439 // Layout the secondary display to the top of the primary.
440 SetSecondaryDisplayLayout(DisplayLayout::TOP);
441 EXPECT_EQ(1, observer.CountAndReset());
442 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
443 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
444 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
445 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
446 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
447 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
448 EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
449 EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
451 // Layout to the right with an offset.
452 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 300);
453 EXPECT_EQ(1, observer.CountAndReset()); // resize and add
454 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
455 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
456 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
457 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
458 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
459 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
460 EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString());
462 // Keep the minimum 100.
463 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 490);
464 EXPECT_EQ(1, observer.CountAndReset()); // resize and add
465 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
466 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
467 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
468 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
469 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
470 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
471 EXPECT_EQ("500,400 400x400", GetSecondaryDisplay().bounds().ToString());
473 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, -400);
474 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
475 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
476 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
477 EXPECT_EQ(1, observer.CountAndReset()); // resize and add
478 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
479 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
480 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
481 EXPECT_EQ("500,-300 400x400", GetSecondaryDisplay().bounds().ToString());
483 // Layout to the bottom with an offset.
484 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -200);
485 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
486 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
487 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
488 EXPECT_EQ(1, observer.CountAndReset()); // resize and add
489 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
490 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
491 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
492 EXPECT_EQ("-200,500 400x400", GetSecondaryDisplay().bounds().ToString());
494 // Keep the minimum 100.
495 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, 490);
496 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
497 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
498 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
499 EXPECT_EQ(1, observer.CountAndReset()); // resize and add
500 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
501 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
502 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
503 EXPECT_EQ("400,500 400x400", GetSecondaryDisplay().bounds().ToString());
505 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400);
506 EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
507 EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
508 EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
509 EXPECT_EQ(1, observer.CountAndReset()); // resize and add
510 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
511 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
512 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
513 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
515 // Setting the same layout shouldn't invoke observers.
516 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400);
517 EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset());
518 EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset());
519 EXPECT_EQ(0, observer.GetWorkareaChangedCountAndReset());
520 EXPECT_EQ(0, observer.CountAndReset()); // resize and add
521 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
522 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
523 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
524 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
526 UpdateDisplay("500x500");
527 EXPECT_LE(1, observer.GetFocusChangedCountAndReset());
528 EXPECT_LE(1, observer.GetActivationChangedCountAndReset());
533 DisplayInfo CreateDisplayInfo(int64 id,
534 const gfx::Rect& bounds,
535 float device_scale_factor) {
536 DisplayInfo info(id, "", false);
537 info.SetBounds(bounds);
538 info.set_device_scale_factor(device_scale_factor);
544 TEST_F(DisplayControllerTest, MirrorToDockedWithFullscreen) {
545 if (!SupportsMultipleDisplays())
548 // Creates windows to catch activation change event.
549 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
553 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
555 const DisplayInfo internal_display_info =
556 CreateDisplayInfo(1, gfx::Rect(0, 0, 500, 500), 2.0f);
557 const DisplayInfo external_display_info =
558 CreateDisplayInfo(2, gfx::Rect(0, 0, 500, 500), 1.0f);
560 std::vector<DisplayInfo> display_info_list;
562 display_info_list.push_back(internal_display_info);
563 display_info_list.push_back(external_display_info);
564 display_manager->OnNativeDisplaysChanged(display_info_list);
565 const int64 internal_display_id =
566 test::DisplayManagerTestApi(display_manager).
567 SetFirstDisplayAsInternalDisplay();
568 EXPECT_EQ(1, internal_display_id);
569 EXPECT_EQ(2U, display_manager->num_connected_displays());
570 EXPECT_EQ(1U, display_manager->GetNumDisplays());
572 wm::WindowState* window_state = wm::GetWindowState(w1.get());
573 const wm::WMEvent toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
574 window_state->OnWMEvent(&toggle_fullscreen_event);
575 EXPECT_TRUE(window_state->IsFullscreen());
576 EXPECT_EQ("0,0 250x250", w1->bounds().ToString());
578 TestObserver observer;
579 display_info_list.clear();
580 display_info_list.push_back(external_display_info);
581 display_manager->OnNativeDisplaysChanged(display_info_list);
582 EXPECT_EQ(1U, display_manager->GetNumDisplays());
583 EXPECT_EQ(1U, display_manager->num_connected_displays());
584 EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset());
585 EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset());
586 EXPECT_EQ(0, observer.GetWorkareaChangedCountAndReset());
587 EXPECT_EQ(1, observer.CountAndReset());
588 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
589 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
591 EXPECT_TRUE(window_state->IsFullscreen());
592 EXPECT_EQ("0,0 500x500", w1->bounds().ToString());
595 TEST_F(DisplayControllerTest, BoundsUpdated) {
596 if (!SupportsMultipleDisplays())
599 // Creates windows to catch activation change event.
600 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
603 TestObserver observer;
604 SetDefaultDisplayLayout(DisplayLayout::BOTTOM);
605 UpdateDisplay("200x200,300x300"); // layout, resize and add.
606 EXPECT_EQ(1, observer.CountAndReset());
607 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
608 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
610 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
611 gfx::Insets insets(5, 5, 5, 5);
612 display_manager->UpdateWorkAreaOfDisplay(
613 ScreenUtil::GetSecondaryDisplay().id(), insets);
615 EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
616 EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
617 EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
619 UpdateDisplay("400x400,200x200");
620 EXPECT_EQ(1, observer.CountAndReset()); // two resizes
621 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
622 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
623 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
624 EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
626 UpdateDisplay("400x400,300x300");
627 EXPECT_EQ(1, observer.CountAndReset());
628 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
629 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
630 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
631 EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
633 UpdateDisplay("400x400");
634 EXPECT_EQ(1, observer.CountAndReset());
635 EXPECT_LE(1, observer.GetFocusChangedCountAndReset());
636 EXPECT_LE(1, observer.GetActivationChangedCountAndReset());
637 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
638 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
640 UpdateDisplay("400x500*2,300x300");
641 EXPECT_EQ(1, observer.CountAndReset());
642 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
643 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
644 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
645 EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
646 EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
649 UpdateDisplay("400x500*2,300x300");
650 // We still call into Pre/PostDisplayConfigurationChange().
651 EXPECT_EQ(1, observer.CountAndReset());
652 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
653 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
656 observer.GetRotationChangedCountAndReset(); // we only want to reset.
657 int64 primary_id = GetPrimaryDisplay().id();
658 display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
659 EXPECT_EQ(1, observer.GetRotationChangedCountAndReset());
660 EXPECT_EQ(1, observer.CountAndReset());
661 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
662 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
663 display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
664 EXPECT_EQ(0, observer.GetRotationChangedCountAndReset());
665 EXPECT_EQ(0, observer.CountAndReset());
666 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
667 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
669 // UI scale is eanbled only on internal display.
670 int64 secondary_id = GetSecondaryDisplay().id();
671 gfx::Display::SetInternalDisplayId(secondary_id);
672 display_manager->SetDisplayUIScale(secondary_id, 1.125f);
673 EXPECT_EQ(1, observer.CountAndReset());
674 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
675 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
676 display_manager->SetDisplayUIScale(secondary_id, 1.125f);
677 EXPECT_EQ(0, observer.CountAndReset());
678 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
679 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
680 display_manager->SetDisplayUIScale(primary_id, 1.125f);
681 EXPECT_EQ(0, observer.CountAndReset());
682 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
683 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
684 display_manager->SetDisplayUIScale(primary_id, 1.125f);
685 EXPECT_EQ(0, observer.CountAndReset());
686 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
687 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
690 TEST_F(DisplayControllerTest, SwapPrimary) {
691 if (!SupportsMultipleDisplays())
694 DisplayController* display_controller =
695 Shell::GetInstance()->display_controller();
696 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
698 UpdateDisplay("200x200,300x300");
699 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
700 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
702 DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
703 display_manager->SetLayoutForCurrentDisplays(display_layout);
705 EXPECT_NE(primary_display.id(), secondary_display.id());
706 aura::Window* primary_root =
707 display_controller->GetRootWindowForDisplayId(primary_display.id());
708 aura::Window* secondary_root =
709 display_controller->GetRootWindowForDisplayId(secondary_display.id());
710 EXPECT_NE(primary_root, secondary_root);
711 aura::Window* shelf_window =
712 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
713 EXPECT_TRUE(primary_root->Contains(shelf_window));
714 EXPECT_FALSE(secondary_root->Contains(shelf_window));
715 EXPECT_EQ(primary_display.id(),
716 Shell::GetScreen()->GetDisplayNearestPoint(
717 gfx::Point(-100, -100)).id());
718 EXPECT_EQ(primary_display.id(),
719 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
721 EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
722 EXPECT_EQ("0,0 200x153", primary_display.work_area().ToString());
723 EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
724 EXPECT_EQ("200,0 300x253", secondary_display.work_area().ToString());
725 EXPECT_EQ("right, 50",
726 display_manager->GetCurrentDisplayLayout().ToString());
728 // Switch primary and secondary
729 display_controller->SetPrimaryDisplay(secondary_display);
730 const DisplayLayout& inverted_layout =
731 display_manager->GetCurrentDisplayLayout();
732 EXPECT_EQ("left, -50", inverted_layout.ToString());
734 EXPECT_EQ(secondary_display.id(),
735 Shell::GetScreen()->GetPrimaryDisplay().id());
736 EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
737 EXPECT_EQ(primary_display.id(),
738 Shell::GetScreen()->GetDisplayNearestPoint(
739 gfx::Point(-100, -100)).id());
740 EXPECT_EQ(secondary_display.id(),
741 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
745 display_controller->GetRootWindowForDisplayId(secondary_display.id()));
748 display_controller->GetRootWindowForDisplayId(primary_display.id()));
749 EXPECT_TRUE(primary_root->Contains(shelf_window));
750 EXPECT_FALSE(secondary_root->Contains(shelf_window));
752 // Test if the bounds are correctly swapped.
753 gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
754 gfx::Display swapped_secondary = ScreenUtil::GetSecondaryDisplay();
755 EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
756 EXPECT_EQ("0,0 300x253", swapped_primary.work_area().ToString());
757 EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
759 EXPECT_EQ("-200,-50 200x153", swapped_secondary.work_area().ToString());
761 aura::WindowTracker tracker;
762 tracker.Add(primary_root);
763 tracker.Add(secondary_root);
765 // Deleting 2nd display should move the primary to original primary display.
766 UpdateDisplay("200x200");
767 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
768 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
769 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
770 EXPECT_EQ(primary_display.id(),
771 Shell::GetScreen()->GetDisplayNearestPoint(
772 gfx::Point(-100, -100)).id());
773 EXPECT_EQ(primary_display.id(),
774 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
775 EXPECT_TRUE(tracker.Contains(primary_root));
776 EXPECT_FALSE(tracker.Contains(secondary_root));
777 EXPECT_TRUE(primary_root->Contains(shelf_window));
780 TEST_F(DisplayControllerTest, FindNearestDisplay) {
781 if (!SupportsMultipleDisplays())
784 DisplayController* display_controller =
785 Shell::GetInstance()->display_controller();
786 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
788 UpdateDisplay("200x200,300x300");
789 DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
790 display_manager->SetLayoutForCurrentDisplays(display_layout);
792 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
793 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
794 EXPECT_NE(primary_display.id(), secondary_display.id());
795 aura::Window* primary_root =
796 display_controller->GetRootWindowForDisplayId(primary_display.id());
797 aura::Window* secondary_root =
798 display_controller->GetRootWindowForDisplayId(secondary_display.id());
799 EXPECT_NE(primary_root, secondary_root);
801 // Test that points outside of any display return the nearest display.
802 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
803 gfx::Point(-100, 0)).id());
804 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
805 gfx::Point(0, -100)).id());
806 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
807 gfx::Point(100, 100)).id());
808 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
809 gfx::Point(224, 25)).id());
810 EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
811 gfx::Point(226, 25)).id());
812 EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
813 gfx::Point(600, 100)).id());
814 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
815 gfx::Point(174, 225)).id());
816 EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
817 gfx::Point(176, 225)).id());
818 EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
819 gfx::Point(300, 400)).id());
822 TEST_F(DisplayControllerTest, SwapPrimaryById) {
823 if (!SupportsMultipleDisplays())
826 DisplayController* display_controller =
827 Shell::GetInstance()->display_controller();
828 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
830 UpdateDisplay("200x200,300x300");
831 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
832 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
834 DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
835 display_manager->SetLayoutForCurrentDisplays(display_layout);
837 EXPECT_NE(primary_display.id(), secondary_display.id());
838 aura::Window* primary_root =
839 display_controller->GetRootWindowForDisplayId(primary_display.id());
840 aura::Window* secondary_root =
841 display_controller->GetRootWindowForDisplayId(secondary_display.id());
842 aura::Window* shelf_window =
843 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
844 EXPECT_TRUE(primary_root->Contains(shelf_window));
845 EXPECT_FALSE(secondary_root->Contains(shelf_window));
846 EXPECT_NE(primary_root, secondary_root);
847 EXPECT_EQ(primary_display.id(),
848 Shell::GetScreen()->GetDisplayNearestPoint(
849 gfx::Point(-100, -100)).id());
850 EXPECT_EQ(primary_display.id(),
851 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
853 // Switch primary and secondary by display ID.
854 TestObserver observer;
855 display_controller->SetPrimaryDisplayId(secondary_display.id());
856 EXPECT_EQ(secondary_display.id(),
857 Shell::GetScreen()->GetPrimaryDisplay().id());
858 EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
859 EXPECT_LT(0, observer.CountAndReset());
863 display_controller->GetRootWindowForDisplayId(secondary_display.id()));
866 display_controller->GetRootWindowForDisplayId(primary_display.id()));
867 EXPECT_TRUE(primary_root->Contains(shelf_window));
868 EXPECT_FALSE(secondary_root->Contains(shelf_window));
870 const DisplayLayout& inverted_layout =
871 display_manager->GetCurrentDisplayLayout();
873 EXPECT_EQ("left, -50", inverted_layout.ToString());
875 // Calling the same ID don't do anything.
876 display_controller->SetPrimaryDisplayId(secondary_display.id());
877 EXPECT_EQ(0, observer.CountAndReset());
879 aura::WindowTracker tracker;
880 tracker.Add(primary_root);
881 tracker.Add(secondary_root);
883 // Deleting 2nd display should move the primary to original primary display.
884 UpdateDisplay("200x200");
885 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
886 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
887 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
888 EXPECT_EQ(primary_display.id(),
889 Shell::GetScreen()->GetDisplayNearestPoint(
890 gfx::Point(-100, -100)).id());
891 EXPECT_EQ(primary_display.id(),
892 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
893 EXPECT_TRUE(tracker.Contains(primary_root));
894 EXPECT_FALSE(tracker.Contains(secondary_root));
895 EXPECT_TRUE(primary_root->Contains(shelf_window));
897 // Adding 2nd display with the same ID. The 2nd display should become primary
898 // since secondary id is still stored as desirable_primary_id.
899 std::vector<DisplayInfo> display_info_list;
900 display_info_list.push_back(
901 display_manager->GetDisplayInfo(primary_display.id()));
902 display_info_list.push_back(
903 display_manager->GetDisplayInfo(secondary_display.id()));
904 display_manager->OnNativeDisplaysChanged(display_info_list);
906 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
907 EXPECT_EQ(secondary_display.id(),
908 Shell::GetScreen()->GetPrimaryDisplay().id());
909 EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
912 display_controller->GetRootWindowForDisplayId(secondary_display.id()));
915 display_controller->GetRootWindowForDisplayId(primary_display.id()));
916 EXPECT_TRUE(primary_root->Contains(shelf_window));
918 // Deleting 2nd display and adding 2nd display with a different ID. The 2nd
919 // display shouldn't become primary.
920 UpdateDisplay("200x200");
921 DisplayInfo third_display_info(
922 secondary_display.id() + 1, std::string(), false);
923 third_display_info.SetBounds(secondary_display.bounds());
924 ASSERT_NE(primary_display.id(), third_display_info.id());
926 const DisplayInfo& primary_display_info =
927 display_manager->GetDisplayInfo(primary_display.id());
928 std::vector<DisplayInfo> display_info_list2;
929 display_info_list2.push_back(primary_display_info);
930 display_info_list2.push_back(third_display_info);
931 display_manager->OnNativeDisplaysChanged(display_info_list2);
932 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
933 EXPECT_EQ(primary_display.id(),
934 Shell::GetScreen()->GetPrimaryDisplay().id());
935 EXPECT_EQ(third_display_info.id(), ScreenUtil::GetSecondaryDisplay().id());
938 display_controller->GetRootWindowForDisplayId(primary_display.id()));
941 display_controller->GetRootWindowForDisplayId(third_display_info.id()));
942 EXPECT_TRUE(primary_root->Contains(shelf_window));
945 TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) {
946 if (!SupportsMultipleDisplays())
949 DisplayController* display_controller =
950 Shell::GetInstance()->display_controller();
952 UpdateDisplay("200x200,200x200*2");
953 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
954 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
956 aura::Window* primary_root =
957 display_controller->GetRootWindowForDisplayId(primary_display.id());
958 aura::Window* secondary_root =
959 display_controller->GetRootWindowForDisplayId(secondary_display.id());
960 EXPECT_NE(primary_root, secondary_root);
962 test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager());
964 EXPECT_EQ(1.0f, primary_root->GetHost()->compositor()->
965 device_scale_factor());
966 primary_root->MoveCursorTo(gfx::Point(50, 50));
967 EXPECT_EQ(1.0f, test_api.GetCurrentCursor().device_scale_factor());
968 EXPECT_EQ(2.0f, secondary_root->GetHost()->compositor()->
969 device_scale_factor());
970 secondary_root->MoveCursorTo(gfx::Point(50, 50));
971 EXPECT_EQ(2.0f, test_api.GetCurrentCursor().device_scale_factor());
973 // Switch primary and secondary
974 display_controller->SetPrimaryDisplay(secondary_display);
976 // Cursor's device scale factor should be updated accroding to the swap of
977 // primary and secondary.
978 EXPECT_EQ(1.0f, secondary_root->GetHost()->compositor()->
979 device_scale_factor());
980 secondary_root->MoveCursorTo(gfx::Point(50, 50));
981 EXPECT_EQ(1.0f, test_api.GetCurrentCursor().device_scale_factor());
982 primary_root->MoveCursorTo(gfx::Point(50, 50));
983 EXPECT_EQ(2.0f, primary_root->GetHost()->compositor()->
984 device_scale_factor());
985 EXPECT_EQ(2.0f, test_api.GetCurrentCursor().device_scale_factor());
987 // Deleting 2nd display.
988 UpdateDisplay("200x200");
989 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
991 // Cursor's device scale factor should be updated even without moving cursor.
992 EXPECT_EQ(1.0f, test_api.GetCurrentCursor().device_scale_factor());
994 primary_root->MoveCursorTo(gfx::Point(50, 50));
995 EXPECT_EQ(1.0f, primary_root->GetHost()->compositor()->
996 device_scale_factor());
997 EXPECT_EQ(1.0f, test_api.GetCurrentCursor().device_scale_factor());
1000 TEST_F(DisplayControllerTest, OverscanInsets) {
1001 if (!SupportsMultipleDisplays())
1004 DisplayController* display_controller =
1005 Shell::GetInstance()->display_controller();
1006 TestEventHandler event_handler;
1007 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1009 UpdateDisplay("120x200,300x400*2");
1010 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1011 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1013 display_controller->SetOverscanInsets(display1.id(),
1014 gfx::Insets(10, 15, 20, 25));
1015 EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString());
1016 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1017 EXPECT_EQ("80,0 150x200",
1018 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1020 ui::test::EventGenerator generator(root_windows[0]);
1021 generator.MoveMouseToInHost(20, 25);
1022 EXPECT_EQ("5,15", event_handler.GetLocationAndReset());
1024 display_controller->SetOverscanInsets(display1.id(), gfx::Insets());
1025 EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString());
1026 EXPECT_EQ("120,0 150x200",
1027 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1029 generator.MoveMouseToInHost(30, 20);
1030 EXPECT_EQ("30,20", event_handler.GetLocationAndReset());
1032 // Make sure the root window transformer uses correct scale
1033 // factor when swapping display. Test crbug.com/253690.
1034 UpdateDisplay("400x300*2,600x400/o");
1035 root_windows = Shell::GetAllRootWindows();
1037 Shell::GetAllRootWindows()[1]->GetHost()->
1038 GetRootTransform().TransformPoint(&point);
1039 EXPECT_EQ("15,10", point.ToString());
1041 display_controller->SwapPrimaryDisplay();
1042 point.SetPoint(0, 0);
1043 Shell::GetAllRootWindows()[1]->GetHost()->
1044 GetRootTransform().TransformPoint(&point);
1045 EXPECT_EQ("15,10", point.ToString());
1047 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1050 TEST_F(DisplayControllerTest, Rotate) {
1051 if (!SupportsMultipleDisplays())
1054 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1055 TestEventHandler event_handler;
1056 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1058 UpdateDisplay("120x200,300x400*2");
1059 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1060 int64 display2_id = ScreenUtil::GetSecondaryDisplay().id();
1061 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1062 ui::test::EventGenerator generator1(root_windows[0]);
1064 TestObserver observer;
1065 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
1066 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1067 EXPECT_EQ("120,0 150x200",
1068 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1069 generator1.MoveMouseToInHost(50, 40);
1070 EXPECT_EQ("50,40", event_handler.GetLocationAndReset());
1071 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
1072 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
1073 EXPECT_EQ(0, observer.GetRotationChangedCountAndReset());
1075 display_manager->SetDisplayRotation(display1.id(),
1076 gfx::Display::ROTATE_90);
1077 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
1078 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1079 EXPECT_EQ("200,0 150x200",
1080 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1081 generator1.MoveMouseToInHost(50, 40);
1082 EXPECT_EQ("40,69", event_handler.GetLocationAndReset());
1083 EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
1084 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
1085 EXPECT_EQ(1, observer.GetRotationChangedCountAndReset());
1087 DisplayLayout display_layout(DisplayLayout::BOTTOM, 50);
1088 display_manager->SetLayoutForCurrentDisplays(display_layout);
1089 EXPECT_EQ("50,120 150x200",
1090 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1092 display_manager->SetDisplayRotation(display2_id,
1093 gfx::Display::ROTATE_270);
1094 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
1095 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
1096 EXPECT_EQ("50,120 200x150",
1097 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1098 EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
1099 EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
1100 EXPECT_EQ(1, observer.GetRotationChangedCountAndReset());
1102 #if !defined(OS_WIN)
1103 ui::test::EventGenerator generator2(root_windows[1]);
1104 generator2.MoveMouseToInHost(50, 40);
1105 EXPECT_EQ("179,25", event_handler.GetLocationAndReset());
1106 display_manager->SetDisplayRotation(display1.id(),
1107 gfx::Display::ROTATE_180);
1109 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
1110 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
1111 // Dislay must share at least 100, so the x's offset becomes 20.
1112 EXPECT_EQ("20,200 200x150",
1113 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1114 EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
1115 EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
1116 EXPECT_EQ(1, observer.GetRotationChangedCountAndReset());
1118 generator1.MoveMouseToInHost(50, 40);
1119 EXPECT_EQ("69,159", event_handler.GetLocationAndReset());
1122 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1125 TEST_F(DisplayControllerTest, ScaleRootWindow) {
1126 if (!SupportsMultipleDisplays())
1129 TestEventHandler event_handler;
1130 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1132 UpdateDisplay("600x400*2@1.5,500x300");
1134 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1135 gfx::Display::SetInternalDisplayId(display1.id());
1137 gfx::Display display2 = ScreenUtil::GetSecondaryDisplay();
1138 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1139 EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
1140 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
1141 EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
1142 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1143 EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
1145 ui::test::EventGenerator generator(root_windows[0]);
1146 generator.MoveMouseToInHost(599, 200);
1147 EXPECT_EQ("449,150", event_handler.GetLocationAndReset());
1149 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1150 display_manager->SetDisplayUIScale(display1.id(), 1.25f);
1151 display1 = Shell::GetScreen()->GetPrimaryDisplay();
1152 display2 = ScreenUtil::GetSecondaryDisplay();
1153 EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
1154 EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
1155 EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
1156 EXPECT_EQ(1.25f, GetStoredUIScale(display1.id()));
1157 EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
1159 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1162 TEST_F(DisplayControllerTest, TouchScale) {
1163 if (!SupportsMultipleDisplays())
1166 TestEventHandler event_handler;
1167 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1169 UpdateDisplay("200x200*2");
1170 gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
1171 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1172 aura::Window* root_window = root_windows[0];
1173 ui::test::EventGenerator generator(root_window);
1175 generator.PressMoveAndReleaseTouchTo(50, 50);
1176 // Default test touches have radius_x/y = 1.0, with device scale
1177 // factor = 2, the scaled radius_x/y should be 0.5.
1178 EXPECT_EQ(0.5, event_handler.touch_radius_x());
1179 EXPECT_EQ(0.5, event_handler.touch_radius_y());
1181 generator.ScrollSequence(gfx::Point(0,0),
1182 base::TimeDelta::FromMilliseconds(100),
1185 // ordinal_offset is invariant to the device scale factor.
1186 EXPECT_EQ(event_handler.scroll_x_offset(),
1187 event_handler.scroll_x_offset_ordinal());
1188 EXPECT_EQ(event_handler.scroll_y_offset(),
1189 event_handler.scroll_y_offset_ordinal());
1191 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1194 TEST_F(DisplayControllerTest, ConvertHostToRootCoords) {
1195 if (!SupportsMultipleDisplays())
1198 TestEventHandler event_handler;
1199 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1201 UpdateDisplay("600x400*2/r@1.5");
1203 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1204 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1205 EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
1206 EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
1207 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1209 ui::test::EventGenerator generator(root_windows[0]);
1210 generator.MoveMouseToInHost(0, 0);
1211 EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
1212 generator.MoveMouseToInHost(599, 0);
1213 EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1214 generator.MoveMouseToInHost(599, 399);
1215 EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
1216 generator.MoveMouseToInHost(0, 399);
1217 EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
1219 UpdateDisplay("600x400*2/u@1.5");
1220 display1 = Shell::GetScreen()->GetPrimaryDisplay();
1221 root_windows = Shell::GetAllRootWindows();
1222 EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
1223 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
1224 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1226 generator.MoveMouseToInHost(0, 0);
1227 EXPECT_EQ("449,299", event_handler.GetLocationAndReset());
1228 generator.MoveMouseToInHost(599, 0);
1229 EXPECT_EQ("0,299", event_handler.GetLocationAndReset());
1230 generator.MoveMouseToInHost(599, 399);
1231 EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1232 generator.MoveMouseToInHost(0, 399);
1233 EXPECT_EQ("449,0", event_handler.GetLocationAndReset());
1235 UpdateDisplay("600x400*2/l@1.5");
1236 display1 = Shell::GetScreen()->GetPrimaryDisplay();
1237 root_windows = Shell::GetAllRootWindows();
1238 EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
1239 EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
1240 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1242 generator.MoveMouseToInHost(0, 0);
1243 EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
1244 generator.MoveMouseToInHost(599, 0);
1245 EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
1246 generator.MoveMouseToInHost(599, 399);
1247 EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
1248 generator.MoveMouseToInHost(0, 399);
1249 EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1251 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1256 DisplayInfo CreateDisplayInfo(int64 id,
1258 gfx::Display::Rotation rotation) {
1259 DisplayInfo info(id, "", false);
1260 info.SetBounds(gfx::Rect(0, y, 500, 500));
1261 info.set_rotation(rotation);
1267 // Make sure that the compositor based mirroring can switch
1268 // from/to dock mode.
1269 TEST_F(DisplayControllerTest, DockToSingle) {
1270 if (!SupportsMultipleDisplays())
1273 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1275 const int64 internal_id = 1;
1277 const DisplayInfo internal_display_info =
1278 CreateDisplayInfo(internal_id, 0, gfx::Display::ROTATE_0);
1279 const DisplayInfo external_display_info =
1280 CreateDisplayInfo(2, 1, gfx::Display::ROTATE_90);
1282 std::vector<DisplayInfo> display_info_list;
1284 display_info_list.push_back(internal_display_info);
1285 display_info_list.push_back(external_display_info);
1286 display_manager->OnNativeDisplaysChanged(display_info_list);
1287 const int64 internal_display_id =
1288 test::DisplayManagerTestApi(display_manager).
1289 SetFirstDisplayAsInternalDisplay();
1290 EXPECT_EQ(internal_id, internal_display_id);
1291 EXPECT_EQ(2U, display_manager->GetNumDisplays());
1294 display_info_list.clear();
1295 display_info_list.push_back(external_display_info);
1296 display_manager->OnNativeDisplaysChanged(display_info_list);
1297 EXPECT_EQ(1U, display_manager->GetNumDisplays());
1298 EXPECT_FALSE(Shell::GetPrimaryRootWindow()->GetHost()->
1299 GetRootTransform().IsIdentityOrIntegerTranslation());
1301 // Switch to single mode and make sure the transform is the one
1302 // for the internal display.
1303 display_info_list.clear();
1304 display_info_list.push_back(internal_display_info);
1305 display_manager->OnNativeDisplaysChanged(display_info_list);
1306 EXPECT_TRUE(Shell::GetPrimaryRootWindow()->GetHost()->
1307 GetRootTransform().IsIdentityOrIntegerTranslation());
1310 #if defined(USE_X11)
1311 TEST_F(DisplayControllerTest, XWidowNameForRootWindow) {
1312 EXPECT_EQ("aura_root_0", GetXWindowName(
1313 Shell::GetPrimaryRootWindow()->GetHost()));
1315 // Multiple display.
1316 UpdateDisplay("200x200,300x300");
1317 aura::Window* primary, *secondary;
1318 GetPrimaryAndSeconary(&primary, &secondary);
1319 EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetHost()));
1320 EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetHost()));
1323 primary = secondary = NULL;
1324 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
1325 GetPrimaryAndSeconary(&primary, &secondary);
1326 EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetHost()));
1327 EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetHost()));
1329 // Switching back to single display.
1330 UpdateDisplay("300x400");
1331 EXPECT_EQ("aura_root_0", GetXWindowName(
1332 Shell::GetPrimaryRootWindow()->GetHost()));