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 primary_changed_count_(0),
73 changed_display_id_(0),
74 focus_changed_count_(0),
75 activation_changed_count_(0) {
76 Shell::GetInstance()->display_controller()->AddObserver(this);
77 Shell::GetScreen()->AddObserver(this);
78 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
80 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
84 ~TestObserver() override
{
85 Shell::GetInstance()->display_controller()->RemoveObserver(this);
86 Shell::GetScreen()->RemoveObserver(this);
87 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
89 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
93 // Overridden from DisplayController::Observer
94 void OnDisplayConfigurationChanging() override
{ ++changing_count_
; }
95 void OnDisplayConfigurationChanged() override
{ ++changed_count_
; }
97 // Overrideen from gfx::DisplayObserver
98 void OnDisplayMetricsChanged(const gfx::Display
& display
,
99 uint32_t metrics
) override
{
100 changed_display_id_
= display
.id();
101 if (metrics
& DISPLAY_METRIC_BOUNDS
)
102 ++bounds_changed_count_
;
103 if (metrics
& DISPLAY_METRIC_ROTATION
)
104 ++rotation_changed_count_
;
105 if (metrics
& DISPLAY_METRIC_WORK_AREA
)
106 ++workarea_changed_count_
;
107 if (metrics
& DISPLAY_METRIC_PRIMARY
)
108 ++primary_changed_count_
;
110 void OnDisplayAdded(const gfx::Display
& new_display
) override
{}
111 void OnDisplayRemoved(const gfx::Display
& old_display
) override
{}
113 // Overridden from aura::client::FocusChangeObserver
114 void OnWindowFocused(aura::Window
* gained_focus
,
115 aura::Window
* lost_focus
) override
{
116 focus_changed_count_
++;
119 // Overridden from aura::client::ActivationChangeObserver
120 void OnWindowActivated(aura::Window
* gained_active
,
121 aura::Window
* lost_active
) override
{
122 activation_changed_count_
++;
124 void OnAttemptToReactivateWindow(aura::Window
* request_active
,
125 aura::Window
* actual_active
) override
{}
127 int CountAndReset() {
128 EXPECT_EQ(changing_count_
, changed_count_
);
130 return Resetter
<int>(&changing_count_
).value();
133 int64
GetBoundsChangedCountAndReset() {
134 return Resetter
<int>(&bounds_changed_count_
).value();
137 int64
GetRotationChangedCountAndReset() {
138 return Resetter
<int>(&rotation_changed_count_
).value();
141 int64
GetWorkareaChangedCountAndReset() {
142 return Resetter
<int>(&workarea_changed_count_
).value();
145 int64
GetPrimaryChangedCountAndReset() {
146 return Resetter
<int>(&primary_changed_count_
).value();
149 int64
GetChangedDisplayIdAndReset() {
150 return Resetter
<int64
>(&changed_display_id_
).value();
153 int GetFocusChangedCountAndReset() {
154 return Resetter
<int>(&focus_changed_count_
).value();
157 int GetActivationChangedCountAndReset() {
158 return Resetter
<int>(&activation_changed_count_
).value();
165 int bounds_changed_count_
;
166 int rotation_changed_count_
;
167 int workarea_changed_count_
;
168 int primary_changed_count_
;
169 int64 changed_display_id_
;
171 int focus_changed_count_
;
172 int activation_changed_count_
;
174 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
177 gfx::Display
GetPrimaryDisplay() {
178 return Shell::GetScreen()->GetDisplayNearestWindow(
179 Shell::GetAllRootWindows()[0]);
182 gfx::Display
GetSecondaryDisplay() {
183 return Shell::GetScreen()->GetDisplayNearestWindow(
184 Shell::GetAllRootWindows()[1]);
187 void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position
,
189 DisplayLayout
layout(position
, offset
);
190 ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1);
191 Shell::GetInstance()->display_manager()->
192 SetLayoutForCurrentDisplays(layout
);
195 void SetSecondaryDisplayLayout(DisplayLayout::Position position
) {
196 SetSecondaryDisplayLayoutAndOffset(position
, 0);
199 void SetDefaultDisplayLayout(DisplayLayout::Position position
) {
200 Shell::GetInstance()->display_manager()->layout_store()->
201 SetDefaultDisplayLayout(DisplayLayout(position
, 0));
204 class DisplayControllerShutdownTest
: public test::AshTestBase
{
206 DisplayControllerShutdownTest() {}
207 ~DisplayControllerShutdownTest() override
{}
209 void TearDown() override
{
210 test::AshTestBase::TearDown();
211 if (!SupportsMultipleDisplays())
214 // Make sure that primary display is accessible after shutdown.
215 gfx::Display primary
= Shell::GetScreen()->GetPrimaryDisplay();
216 EXPECT_EQ("0,0 444x333", primary
.bounds().ToString());
217 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
221 DISALLOW_COPY_AND_ASSIGN(DisplayControllerShutdownTest
);
224 class StartupHelper
: public test::TestShellDelegate
,
225 public DisplayController::Observer
{
227 StartupHelper() : displays_initialized_(false) {}
228 ~StartupHelper() override
{}
230 // ash::ShellSelegate:
231 void PreInit() override
{
232 Shell::GetInstance()->display_controller()->AddObserver(this);
235 // ash::DisplayController::Observer:
236 void OnDisplaysInitialized() override
{
237 DCHECK(!displays_initialized_
);
238 displays_initialized_
= true;
241 bool displays_initialized() const {
242 return displays_initialized_
;
246 bool displays_initialized_
;
248 DISALLOW_COPY_AND_ASSIGN(StartupHelper
);
251 class DisplayControllerStartupTest
: public test::AshTestBase
{
253 DisplayControllerStartupTest() : startup_helper_(new StartupHelper
) {}
254 ~DisplayControllerStartupTest() override
{}
256 // ash::test::AshTestBase:
257 void SetUp() override
{
258 ash_test_helper()->set_test_shell_delegate(startup_helper_
);
259 test::AshTestBase::SetUp();
261 void TearDown() override
{
262 Shell::GetInstance()->display_controller()->RemoveObserver(startup_helper_
);
263 test::AshTestBase::TearDown();
266 const StartupHelper
* startup_helper() const { return startup_helper_
; }
269 StartupHelper
* startup_helper_
; // Owned by ash::Shell.
271 DISALLOW_COPY_AND_ASSIGN(DisplayControllerStartupTest
);
274 class TestEventHandler
: public ui::EventHandler
{
276 TestEventHandler() : target_root_(NULL
),
277 touch_radius_x_(0.0),
278 touch_radius_y_(0.0),
279 scroll_x_offset_(0.0),
280 scroll_y_offset_(0.0),
281 scroll_x_offset_ordinal_(0.0),
282 scroll_y_offset_ordinal_(0.0) {}
283 ~TestEventHandler() override
{}
285 void OnMouseEvent(ui::MouseEvent
* event
) override
{
286 if (event
->flags() & ui::EF_IS_SYNTHESIZED
&&
287 event
->type() != ui::ET_MOUSE_EXITED
&&
288 event
->type() != ui::ET_MOUSE_ENTERED
) {
291 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
292 mouse_location_
= event
->root_location();
293 target_root_
= target
->GetRootWindow();
294 event
->StopPropagation();
297 void OnTouchEvent(ui::TouchEvent
* event
) override
{
298 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
299 // Only record when the target is the background which covers
300 // entire root window.
301 if (target
->name() != kDesktopBackgroundView
)
303 touch_radius_x_
= event
->radius_x();
304 touch_radius_y_
= event
->radius_y();
305 event
->StopPropagation();
308 void OnScrollEvent(ui::ScrollEvent
* event
) override
{
309 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
310 // Only record when the target is the background which covers
311 // entire root window.
312 if (target
->name() != kDesktopBackgroundView
)
315 if (event
->type() == ui::ET_SCROLL
) {
316 scroll_x_offset_
= event
->x_offset();
317 scroll_y_offset_
= event
->y_offset();
318 scroll_x_offset_ordinal_
= event
->x_offset_ordinal();
319 scroll_y_offset_ordinal_
= event
->y_offset_ordinal();
321 event
->StopPropagation();
324 std::string
GetLocationAndReset() {
325 std::string result
= mouse_location_
.ToString();
326 mouse_location_
.SetPoint(0, 0);
331 float touch_radius_x() { return touch_radius_x_
; }
332 float touch_radius_y() { return touch_radius_y_
; }
333 float scroll_x_offset() { return scroll_x_offset_
; }
334 float scroll_y_offset() { return scroll_y_offset_
; }
335 float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_
; }
336 float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_
; }
339 gfx::Point mouse_location_
;
340 aura::Window
* target_root_
;
342 float touch_radius_x_
;
343 float touch_radius_y_
;
344 float scroll_x_offset_
;
345 float scroll_y_offset_
;
346 float scroll_x_offset_ordinal_
;
347 float scroll_y_offset_ordinal_
;
349 DISALLOW_COPY_AND_ASSIGN(TestEventHandler
);
352 gfx::Display::Rotation
GetStoredRotation(int64 id
) {
353 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id
).rotation();
356 float GetStoredUIScale(int64 id
) {
357 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id
).
358 GetEffectiveUIScale();
362 void GetPrimaryAndSeconary(aura::Window
** primary
,
363 aura::Window
** secondary
) {
364 *primary
= Shell::GetPrimaryRootWindow();
365 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
366 *secondary
= root_windows
[0] == *primary
? root_windows
[1] : root_windows
[0];
369 std::string
GetXWindowName(aura::WindowTreeHost
* host
) {
371 XFetchName(gfx::GetXDisplay(), host
->GetAcceleratedWidget(), &name
);
372 std::string
ret(name
);
380 typedef test::AshTestBase DisplayControllerTest
;
382 TEST_F(DisplayControllerShutdownTest
, Shutdown
) {
383 if (!SupportsMultipleDisplays())
386 UpdateDisplay("444x333, 200x200");
389 TEST_F(DisplayControllerStartupTest
, Startup
) {
390 if (!SupportsMultipleDisplays())
393 EXPECT_TRUE(startup_helper()->displays_initialized());
396 TEST_F(DisplayControllerTest
, SecondaryDisplayLayout
) {
397 if (!SupportsMultipleDisplays())
400 // Creates windows to catch activation change event.
401 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
404 TestObserver observer
;
405 UpdateDisplay("500x500,400x400");
406 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
407 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
408 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
409 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
410 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
411 gfx::Insets
insets(5, 5, 5, 5);
412 int64 secondary_display_id
= ScreenUtil::GetSecondaryDisplay().id();
413 Shell::GetInstance()->display_manager()->UpdateWorkAreaOfDisplay(
414 secondary_display_id
, insets
);
416 // Default layout is RIGHT.
417 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
418 EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
419 EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());
420 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
421 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
423 // Layout the secondary display to the bottom of the primary.
424 SetSecondaryDisplayLayout(DisplayLayout::BOTTOM
);
425 EXPECT_EQ(1, observer
.CountAndReset());
426 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
427 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
428 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
429 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
430 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
431 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
432 EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
433 EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());
435 // Layout the secondary display to the left of the primary.
436 SetSecondaryDisplayLayout(DisplayLayout::LEFT
);
437 EXPECT_EQ(1, observer
.CountAndReset());
438 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
439 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
440 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
441 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
442 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
443 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
444 EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
445 EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());
447 // Layout the secondary display to the top of the primary.
448 SetSecondaryDisplayLayout(DisplayLayout::TOP
);
449 EXPECT_EQ(1, observer
.CountAndReset());
450 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
451 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
452 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
453 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
454 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
455 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
456 EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
457 EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
459 // Layout to the right with an offset.
460 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, 300);
461 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
462 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
463 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
464 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
465 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
466 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
467 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
468 EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString());
470 // Keep the minimum 100.
471 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, 490);
472 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
473 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
474 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
475 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
476 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
477 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
478 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
479 EXPECT_EQ("500,400 400x400", GetSecondaryDisplay().bounds().ToString());
481 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, -400);
482 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
483 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
484 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
485 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
486 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
487 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
488 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
489 EXPECT_EQ("500,-300 400x400", GetSecondaryDisplay().bounds().ToString());
491 // Layout to the bottom with an offset.
492 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -200);
493 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
494 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
495 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
496 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
497 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
498 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
499 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
500 EXPECT_EQ("-200,500 400x400", GetSecondaryDisplay().bounds().ToString());
502 // Keep the minimum 100.
503 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, 490);
504 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
505 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
506 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
507 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
508 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
509 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
510 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
511 EXPECT_EQ("400,500 400x400", GetSecondaryDisplay().bounds().ToString());
513 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -400);
514 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
515 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
516 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
517 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
518 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
519 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
520 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
521 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
523 // Setting the same layout shouldn't invoke observers.
524 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -400);
525 EXPECT_EQ(0, observer
.GetChangedDisplayIdAndReset());
526 EXPECT_EQ(0, observer
.GetBoundsChangedCountAndReset());
527 EXPECT_EQ(0, observer
.GetWorkareaChangedCountAndReset());
528 EXPECT_EQ(0, observer
.CountAndReset()); // resize and add
529 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
530 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
531 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
532 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
534 UpdateDisplay("500x500");
535 EXPECT_LE(1, observer
.GetFocusChangedCountAndReset());
536 EXPECT_LE(1, observer
.GetActivationChangedCountAndReset());
541 DisplayInfo
CreateDisplayInfo(int64 id
,
543 gfx::Display::Rotation rotation
) {
544 DisplayInfo
info(id
, "", false);
545 info
.SetBounds(gfx::Rect(0, y
, 500, 500));
546 info
.set_rotation(rotation
);
550 DisplayInfo
CreateMirroredDisplayInfo(int64 id
,
551 float device_scale_factor
) {
552 DisplayInfo info
= CreateDisplayInfo(id
, 0, gfx::Display::ROTATE_0
);
553 info
.set_device_scale_factor(device_scale_factor
);
559 TEST_F(DisplayControllerTest
, MirrorToDockedWithFullscreen
) {
560 if (!SupportsMultipleDisplays())
563 // Creates windows to catch activation change event.
564 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
568 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
570 const DisplayInfo internal_display_info
=
571 CreateMirroredDisplayInfo(1, 2.0f
);
572 const DisplayInfo external_display_info
=
573 CreateMirroredDisplayInfo(2, 1.0f
);
575 std::vector
<DisplayInfo
> display_info_list
;
577 display_info_list
.push_back(internal_display_info
);
578 display_info_list
.push_back(external_display_info
);
579 display_manager
->OnNativeDisplaysChanged(display_info_list
);
580 const int64 internal_display_id
=
581 test::DisplayManagerTestApi(display_manager
).
582 SetFirstDisplayAsInternalDisplay();
583 EXPECT_EQ(1, internal_display_id
);
584 EXPECT_EQ(2U, display_manager
->num_connected_displays());
585 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
587 wm::WindowState
* window_state
= wm::GetWindowState(w1
.get());
588 const wm::WMEvent
toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN
);
589 window_state
->OnWMEvent(&toggle_fullscreen_event
);
590 EXPECT_TRUE(window_state
->IsFullscreen());
591 EXPECT_EQ("0,0 250x250", w1
->bounds().ToString());
593 TestObserver observer
;
594 display_info_list
.clear();
595 display_info_list
.push_back(external_display_info
);
596 display_manager
->OnNativeDisplaysChanged(display_info_list
);
597 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
598 EXPECT_EQ(1U, display_manager
->num_connected_displays());
599 // Observers are called due to primary change.
600 EXPECT_EQ(2, observer
.GetChangedDisplayIdAndReset());
601 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
602 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
603 EXPECT_EQ(1, observer
.GetPrimaryChangedCountAndReset());
604 EXPECT_EQ(1, observer
.CountAndReset());
605 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
606 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
608 EXPECT_TRUE(window_state
->IsFullscreen());
609 EXPECT_EQ("0,0 500x500", w1
->bounds().ToString());
612 TEST_F(DisplayControllerTest
, BoundsUpdated
) {
613 if (!SupportsMultipleDisplays())
616 // Creates windows to catch activation change event.
617 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
620 TestObserver observer
;
621 SetDefaultDisplayLayout(DisplayLayout::BOTTOM
);
622 UpdateDisplay("200x200,300x300"); // layout, resize and add.
623 EXPECT_EQ(1, observer
.CountAndReset());
624 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
625 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
627 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
628 gfx::Insets
insets(5, 5, 5, 5);
629 display_manager
->UpdateWorkAreaOfDisplay(
630 ScreenUtil::GetSecondaryDisplay().id(), insets
);
632 EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
633 EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
634 EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
636 UpdateDisplay("400x400,200x200");
637 EXPECT_EQ(1, observer
.CountAndReset()); // two resizes
638 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
639 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
640 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
641 EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
643 UpdateDisplay("400x400,300x300");
644 EXPECT_EQ(1, observer
.CountAndReset());
645 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
646 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
647 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
648 EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
650 UpdateDisplay("400x400");
651 EXPECT_EQ(1, observer
.CountAndReset());
652 EXPECT_LE(1, observer
.GetFocusChangedCountAndReset());
653 EXPECT_LE(1, observer
.GetActivationChangedCountAndReset());
654 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
655 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
657 UpdateDisplay("400x500*2,300x300");
658 EXPECT_EQ(1, observer
.CountAndReset());
659 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
660 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
661 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
662 EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
663 EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
666 UpdateDisplay("400x500*2,300x300");
667 // We still call into Pre/PostDisplayConfigurationChange().
668 EXPECT_EQ(1, observer
.CountAndReset());
669 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
670 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
673 observer
.GetRotationChangedCountAndReset(); // we only want to reset.
674 int64 primary_id
= GetPrimaryDisplay().id();
675 display_manager
->SetDisplayRotation(primary_id
, gfx::Display::ROTATE_90
);
676 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
677 EXPECT_EQ(1, observer
.CountAndReset());
678 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
679 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
680 display_manager
->SetDisplayRotation(primary_id
, gfx::Display::ROTATE_90
);
681 EXPECT_EQ(0, observer
.GetRotationChangedCountAndReset());
682 EXPECT_EQ(0, observer
.CountAndReset());
683 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
684 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
686 // UI scale is eanbled only on internal display.
687 int64 secondary_id
= GetSecondaryDisplay().id();
688 test::DisplayManagerTestApi(display_manager
)
689 .SetInternalDisplayId(secondary_id
);
691 display_manager
->SetDisplayUIScale(secondary_id
, 1.125f
);
692 EXPECT_EQ(1, observer
.CountAndReset());
693 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
694 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
695 display_manager
->SetDisplayUIScale(secondary_id
, 1.125f
);
696 EXPECT_EQ(0, observer
.CountAndReset());
697 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
698 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
699 display_manager
->SetDisplayUIScale(primary_id
, 1.125f
);
700 EXPECT_EQ(0, observer
.CountAndReset());
701 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
702 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
703 display_manager
->SetDisplayUIScale(primary_id
, 1.125f
);
704 EXPECT_EQ(0, observer
.CountAndReset());
705 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
706 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
709 TEST_F(DisplayControllerTest
, SwapPrimary
) {
710 if (!SupportsMultipleDisplays())
713 DisplayController
* display_controller
=
714 Shell::GetInstance()->display_controller();
715 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
717 UpdateDisplay("200x200,300x300");
718 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
719 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
721 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
722 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
724 EXPECT_NE(primary_display
.id(), secondary_display
.id());
725 aura::Window
* primary_root
=
726 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
727 aura::Window
* secondary_root
=
728 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
729 EXPECT_NE(primary_root
, secondary_root
);
730 aura::Window
* shelf_window
=
731 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
732 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
733 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
734 EXPECT_EQ(primary_display
.id(),
735 Shell::GetScreen()->GetDisplayNearestPoint(
736 gfx::Point(-100, -100)).id());
737 EXPECT_EQ(primary_display
.id(),
738 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
740 EXPECT_EQ("0,0 200x200", primary_display
.bounds().ToString());
741 EXPECT_EQ("0,0 200x153", primary_display
.work_area().ToString());
742 EXPECT_EQ("200,0 300x300", secondary_display
.bounds().ToString());
743 EXPECT_EQ("200,0 300x253", secondary_display
.work_area().ToString());
744 EXPECT_EQ("right, 50",
745 display_manager
->GetCurrentDisplayLayout().ToString());
747 // Switch primary and secondary
748 display_controller
->SetPrimaryDisplay(secondary_display
);
749 const DisplayLayout
& inverted_layout
=
750 display_manager
->GetCurrentDisplayLayout();
751 EXPECT_EQ("left, -50", inverted_layout
.ToString());
753 EXPECT_EQ(secondary_display
.id(),
754 Shell::GetScreen()->GetPrimaryDisplay().id());
755 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
756 EXPECT_EQ(primary_display
.id(),
757 Shell::GetScreen()->GetDisplayNearestPoint(
758 gfx::Point(-100, -100)).id());
759 EXPECT_EQ(secondary_display
.id(),
760 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
764 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
767 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
768 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
769 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
771 // Test if the bounds are correctly swapped.
772 gfx::Display swapped_primary
= Shell::GetScreen()->GetPrimaryDisplay();
773 gfx::Display swapped_secondary
= ScreenUtil::GetSecondaryDisplay();
774 EXPECT_EQ("0,0 300x300", swapped_primary
.bounds().ToString());
775 EXPECT_EQ("0,0 300x253", swapped_primary
.work_area().ToString());
776 EXPECT_EQ("-200,-50 200x200", swapped_secondary
.bounds().ToString());
778 EXPECT_EQ("-200,-50 200x153", swapped_secondary
.work_area().ToString());
780 aura::WindowTracker tracker
;
781 tracker
.Add(primary_root
);
782 tracker
.Add(secondary_root
);
784 // Deleting 2nd display should move the primary to original primary display.
785 UpdateDisplay("200x200");
786 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
787 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
788 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
789 EXPECT_EQ(primary_display
.id(),
790 Shell::GetScreen()->GetDisplayNearestPoint(
791 gfx::Point(-100, -100)).id());
792 EXPECT_EQ(primary_display
.id(),
793 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
794 EXPECT_TRUE(tracker
.Contains(primary_root
));
795 EXPECT_FALSE(tracker
.Contains(secondary_root
));
796 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
799 TEST_F(DisplayControllerTest
, FindNearestDisplay
) {
800 if (!SupportsMultipleDisplays())
803 DisplayController
* display_controller
=
804 Shell::GetInstance()->display_controller();
805 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
807 UpdateDisplay("200x200,300x300");
808 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
809 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
811 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
812 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
813 EXPECT_NE(primary_display
.id(), secondary_display
.id());
814 aura::Window
* primary_root
=
815 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
816 aura::Window
* secondary_root
=
817 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
818 EXPECT_NE(primary_root
, secondary_root
);
820 // Test that points outside of any display return the nearest display.
821 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
822 gfx::Point(-100, 0)).id());
823 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
824 gfx::Point(0, -100)).id());
825 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
826 gfx::Point(100, 100)).id());
827 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
828 gfx::Point(224, 25)).id());
829 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
830 gfx::Point(226, 25)).id());
831 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
832 gfx::Point(600, 100)).id());
833 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
834 gfx::Point(174, 225)).id());
835 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
836 gfx::Point(176, 225)).id());
837 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
838 gfx::Point(300, 400)).id());
841 TEST_F(DisplayControllerTest
, SwapPrimaryById
) {
842 if (!SupportsMultipleDisplays())
845 DisplayController
* display_controller
=
846 Shell::GetInstance()->display_controller();
847 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
849 UpdateDisplay("200x200,300x300");
850 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
851 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
853 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
854 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
856 EXPECT_NE(primary_display
.id(), secondary_display
.id());
857 aura::Window
* primary_root
=
858 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
859 aura::Window
* secondary_root
=
860 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
861 aura::Window
* shelf_window
=
862 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
863 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
864 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
865 EXPECT_NE(primary_root
, secondary_root
);
866 EXPECT_EQ(primary_display
.id(),
867 Shell::GetScreen()->GetDisplayNearestPoint(
868 gfx::Point(-100, -100)).id());
869 EXPECT_EQ(primary_display
.id(),
870 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
872 // Switch primary and secondary by display ID.
873 TestObserver observer
;
874 display_controller
->SetPrimaryDisplayId(secondary_display
.id());
875 EXPECT_EQ(secondary_display
.id(),
876 Shell::GetScreen()->GetPrimaryDisplay().id());
877 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
878 EXPECT_LT(0, observer
.CountAndReset());
882 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
885 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
886 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
887 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
889 const DisplayLayout
& inverted_layout
=
890 display_manager
->GetCurrentDisplayLayout();
892 EXPECT_EQ("left, -50", inverted_layout
.ToString());
894 // Calling the same ID don't do anything.
895 display_controller
->SetPrimaryDisplayId(secondary_display
.id());
896 EXPECT_EQ(0, observer
.CountAndReset());
898 aura::WindowTracker tracker
;
899 tracker
.Add(primary_root
);
900 tracker
.Add(secondary_root
);
902 // Deleting 2nd display should move the primary to original primary display.
903 UpdateDisplay("200x200");
904 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
905 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
906 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
907 EXPECT_EQ(primary_display
.id(),
908 Shell::GetScreen()->GetDisplayNearestPoint(
909 gfx::Point(-100, -100)).id());
910 EXPECT_EQ(primary_display
.id(),
911 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
912 EXPECT_TRUE(tracker
.Contains(primary_root
));
913 EXPECT_FALSE(tracker
.Contains(secondary_root
));
914 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
916 // Adding 2nd display with the same ID. The 2nd display should become primary
917 // since secondary id is still stored as desirable_primary_id.
918 std::vector
<DisplayInfo
> display_info_list
;
919 display_info_list
.push_back(
920 display_manager
->GetDisplayInfo(primary_display
.id()));
921 display_info_list
.push_back(
922 display_manager
->GetDisplayInfo(secondary_display
.id()));
923 display_manager
->OnNativeDisplaysChanged(display_info_list
);
925 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
926 EXPECT_EQ(secondary_display
.id(),
927 Shell::GetScreen()->GetPrimaryDisplay().id());
928 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
931 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
934 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
935 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
937 // Deleting 2nd display and adding 2nd display with a different ID. The 2nd
938 // display shouldn't become primary.
939 UpdateDisplay("200x200");
940 DisplayInfo
third_display_info(
941 secondary_display
.id() + 1, std::string(), false);
942 third_display_info
.SetBounds(secondary_display
.bounds());
943 ASSERT_NE(primary_display
.id(), third_display_info
.id());
945 const DisplayInfo
& primary_display_info
=
946 display_manager
->GetDisplayInfo(primary_display
.id());
947 std::vector
<DisplayInfo
> display_info_list2
;
948 display_info_list2
.push_back(primary_display_info
);
949 display_info_list2
.push_back(third_display_info
);
950 display_manager
->OnNativeDisplaysChanged(display_info_list2
);
951 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
952 EXPECT_EQ(primary_display
.id(),
953 Shell::GetScreen()->GetPrimaryDisplay().id());
954 EXPECT_EQ(third_display_info
.id(), ScreenUtil::GetSecondaryDisplay().id());
957 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
960 display_controller
->GetRootWindowForDisplayId(third_display_info
.id()));
961 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
964 TEST_F(DisplayControllerTest
, CursorDeviceScaleFactorSwapPrimary
) {
965 if (!SupportsMultipleDisplays())
968 DisplayController
* display_controller
=
969 Shell::GetInstance()->display_controller();
971 UpdateDisplay("200x200,200x200*2");
972 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
973 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
975 aura::Window
* primary_root
=
976 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
977 aura::Window
* secondary_root
=
978 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
979 EXPECT_NE(primary_root
, secondary_root
);
981 test::CursorManagerTestApi
test_api(Shell::GetInstance()->cursor_manager());
983 EXPECT_EQ(1.0f
, primary_root
->GetHost()->compositor()->
984 device_scale_factor());
985 primary_root
->MoveCursorTo(gfx::Point(50, 50));
986 EXPECT_EQ(1.0f
, test_api
.GetCurrentCursor().device_scale_factor());
987 EXPECT_EQ(2.0f
, secondary_root
->GetHost()->compositor()->
988 device_scale_factor());
989 secondary_root
->MoveCursorTo(gfx::Point(50, 50));
990 EXPECT_EQ(2.0f
, test_api
.GetCurrentCursor().device_scale_factor());
992 // Switch primary and secondary
993 display_controller
->SetPrimaryDisplay(secondary_display
);
995 // Cursor's device scale factor should be updated accroding to the swap of
996 // primary and secondary.
997 EXPECT_EQ(1.0f
, secondary_root
->GetHost()->compositor()->
998 device_scale_factor());
999 secondary_root
->MoveCursorTo(gfx::Point(50, 50));
1000 EXPECT_EQ(1.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1001 primary_root
->MoveCursorTo(gfx::Point(50, 50));
1002 EXPECT_EQ(2.0f
, primary_root
->GetHost()->compositor()->
1003 device_scale_factor());
1004 EXPECT_EQ(2.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1006 // Deleting 2nd display.
1007 UpdateDisplay("200x200");
1008 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
1010 // Cursor's device scale factor should be updated even without moving cursor.
1011 EXPECT_EQ(1.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1013 primary_root
->MoveCursorTo(gfx::Point(50, 50));
1014 EXPECT_EQ(1.0f
, primary_root
->GetHost()->compositor()->
1015 device_scale_factor());
1016 EXPECT_EQ(1.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1019 TEST_F(DisplayControllerTest
, OverscanInsets
) {
1020 if (!SupportsMultipleDisplays())
1023 DisplayController
* display_controller
=
1024 Shell::GetInstance()->display_controller();
1025 TestEventHandler event_handler
;
1026 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1028 UpdateDisplay("120x200,300x400*2");
1029 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1030 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1032 display_controller
->SetOverscanInsets(display1
.id(),
1033 gfx::Insets(10, 15, 20, 25));
1034 EXPECT_EQ("0,0 80x170", root_windows
[0]->bounds().ToString());
1035 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
1036 EXPECT_EQ("80,0 150x200",
1037 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1039 ui::test::EventGenerator
generator(root_windows
[0]);
1040 generator
.MoveMouseToInHost(20, 25);
1041 EXPECT_EQ("5,15", event_handler
.GetLocationAndReset());
1043 display_controller
->SetOverscanInsets(display1
.id(), gfx::Insets());
1044 EXPECT_EQ("0,0 120x200", root_windows
[0]->bounds().ToString());
1045 EXPECT_EQ("120,0 150x200",
1046 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1048 generator
.MoveMouseToInHost(30, 20);
1049 EXPECT_EQ("30,20", event_handler
.GetLocationAndReset());
1051 // Make sure the root window transformer uses correct scale
1052 // factor when swapping display. Test crbug.com/253690.
1053 UpdateDisplay("400x300*2,600x400/o");
1054 root_windows
= Shell::GetAllRootWindows();
1056 Shell::GetAllRootWindows()[1]->GetHost()->
1057 GetRootTransform().TransformPoint(&point
);
1058 EXPECT_EQ("15,10", point
.ToString());
1060 display_controller
->SwapPrimaryDisplay();
1061 point
.SetPoint(0, 0);
1062 Shell::GetAllRootWindows()[1]->GetHost()->
1063 GetRootTransform().TransformPoint(&point
);
1064 EXPECT_EQ("15,10", point
.ToString());
1066 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1069 TEST_F(DisplayControllerTest
, Rotate
) {
1070 if (!SupportsMultipleDisplays())
1073 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1074 TestEventHandler event_handler
;
1075 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1077 UpdateDisplay("120x200,300x400*2");
1078 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1079 int64 display2_id
= ScreenUtil::GetSecondaryDisplay().id();
1080 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1081 ui::test::EventGenerator
generator1(root_windows
[0]);
1083 TestObserver observer
;
1084 EXPECT_EQ("120x200", root_windows
[0]->bounds().size().ToString());
1085 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
1086 EXPECT_EQ("120,0 150x200",
1087 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1088 generator1
.MoveMouseToInHost(50, 40);
1089 EXPECT_EQ("50,40", event_handler
.GetLocationAndReset());
1090 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display1
.id()));
1091 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display2_id
));
1092 EXPECT_EQ(0, observer
.GetRotationChangedCountAndReset());
1094 display_manager
->SetDisplayRotation(display1
.id(),
1095 gfx::Display::ROTATE_90
);
1096 EXPECT_EQ("200x120", root_windows
[0]->bounds().size().ToString());
1097 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
1098 EXPECT_EQ("200,0 150x200",
1099 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1100 generator1
.MoveMouseToInHost(50, 40);
1101 EXPECT_EQ("40,69", event_handler
.GetLocationAndReset());
1102 EXPECT_EQ(gfx::Display::ROTATE_90
, GetStoredRotation(display1
.id()));
1103 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display2_id
));
1104 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1106 DisplayLayout
display_layout(DisplayLayout::BOTTOM
, 50);
1107 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
1108 EXPECT_EQ("50,120 150x200",
1109 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1111 display_manager
->SetDisplayRotation(display2_id
,
1112 gfx::Display::ROTATE_270
);
1113 EXPECT_EQ("200x120", root_windows
[0]->bounds().size().ToString());
1114 EXPECT_EQ("200x150", root_windows
[1]->bounds().size().ToString());
1115 EXPECT_EQ("50,120 200x150",
1116 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1117 EXPECT_EQ(gfx::Display::ROTATE_90
, GetStoredRotation(display1
.id()));
1118 EXPECT_EQ(gfx::Display::ROTATE_270
, GetStoredRotation(display2_id
));
1119 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1121 #if !defined(OS_WIN)
1122 ui::test::EventGenerator
generator2(root_windows
[1]);
1123 generator2
.MoveMouseToInHost(50, 40);
1124 EXPECT_EQ("179,25", event_handler
.GetLocationAndReset());
1125 display_manager
->SetDisplayRotation(display1
.id(),
1126 gfx::Display::ROTATE_180
);
1128 EXPECT_EQ("120x200", root_windows
[0]->bounds().size().ToString());
1129 EXPECT_EQ("200x150", root_windows
[1]->bounds().size().ToString());
1130 // Dislay must share at least 100, so the x's offset becomes 20.
1131 EXPECT_EQ("20,200 200x150",
1132 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1133 EXPECT_EQ(gfx::Display::ROTATE_180
, GetStoredRotation(display1
.id()));
1134 EXPECT_EQ(gfx::Display::ROTATE_270
, GetStoredRotation(display2_id
));
1135 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1137 generator1
.MoveMouseToInHost(50, 40);
1138 EXPECT_EQ("69,159", event_handler
.GetLocationAndReset());
1141 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1144 TEST_F(DisplayControllerTest
, ScaleRootWindow
) {
1145 if (!SupportsMultipleDisplays())
1148 TestEventHandler event_handler
;
1149 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1151 UpdateDisplay("600x400*2@1.5,500x300");
1153 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1154 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1155 test::DisplayManagerTestApi(display_manager
)
1156 .SetInternalDisplayId(display1
.id());
1158 gfx::Display display2
= ScreenUtil::GetSecondaryDisplay();
1159 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1160 EXPECT_EQ("0,0 450x300", display1
.bounds().ToString());
1161 EXPECT_EQ("0,0 450x300", root_windows
[0]->bounds().ToString());
1162 EXPECT_EQ("450,0 500x300", display2
.bounds().ToString());
1163 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1164 EXPECT_EQ(1.0f
, GetStoredUIScale(display2
.id()));
1166 ui::test::EventGenerator
generator(root_windows
[0]);
1167 generator
.MoveMouseToInHost(599, 200);
1168 EXPECT_EQ("449,150", event_handler
.GetLocationAndReset());
1170 display_manager
->SetDisplayUIScale(display1
.id(), 1.25f
);
1171 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1172 display2
= ScreenUtil::GetSecondaryDisplay();
1173 EXPECT_EQ("0,0 375x250", display1
.bounds().ToString());
1174 EXPECT_EQ("0,0 375x250", root_windows
[0]->bounds().ToString());
1175 EXPECT_EQ("375,0 500x300", display2
.bounds().ToString());
1176 EXPECT_EQ(1.25f
, GetStoredUIScale(display1
.id()));
1177 EXPECT_EQ(1.0f
, GetStoredUIScale(display2
.id()));
1179 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1182 TEST_F(DisplayControllerTest
, TouchScale
) {
1183 if (!SupportsMultipleDisplays())
1186 TestEventHandler event_handler
;
1187 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1189 UpdateDisplay("200x200*2");
1190 gfx::Display display
= Shell::GetScreen()->GetPrimaryDisplay();
1191 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1192 aura::Window
* root_window
= root_windows
[0];
1193 ui::test::EventGenerator
generator(root_window
);
1195 generator
.PressMoveAndReleaseTouchTo(50, 50);
1196 // Default test touches have radius_x/y = 1.0, with device scale
1197 // factor = 2, the scaled radius_x/y should be 0.5.
1198 EXPECT_EQ(0.5, event_handler
.touch_radius_x());
1199 EXPECT_EQ(0.5, event_handler
.touch_radius_y());
1201 generator
.ScrollSequence(gfx::Point(0,0),
1202 base::TimeDelta::FromMilliseconds(100),
1205 // ordinal_offset is invariant to the device scale factor.
1206 EXPECT_EQ(event_handler
.scroll_x_offset(),
1207 event_handler
.scroll_x_offset_ordinal());
1208 EXPECT_EQ(event_handler
.scroll_y_offset(),
1209 event_handler
.scroll_y_offset_ordinal());
1211 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1214 TEST_F(DisplayControllerTest
, ConvertHostToRootCoords
) {
1215 if (!SupportsMultipleDisplays())
1218 TestEventHandler event_handler
;
1219 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1221 UpdateDisplay("600x400*2/r@1.5");
1223 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1224 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1225 EXPECT_EQ("0,0 300x450", display1
.bounds().ToString());
1226 EXPECT_EQ("0,0 300x450", root_windows
[0]->bounds().ToString());
1227 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1229 ui::test::EventGenerator
generator(root_windows
[0]);
1230 generator
.MoveMouseToInHost(0, 0);
1231 EXPECT_EQ("0,449", event_handler
.GetLocationAndReset());
1232 generator
.MoveMouseToInHost(599, 0);
1233 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1234 generator
.MoveMouseToInHost(599, 399);
1235 EXPECT_EQ("299,0", event_handler
.GetLocationAndReset());
1236 generator
.MoveMouseToInHost(0, 399);
1237 EXPECT_EQ("299,449", event_handler
.GetLocationAndReset());
1239 UpdateDisplay("600x400*2/u@1.5");
1240 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1241 root_windows
= Shell::GetAllRootWindows();
1242 EXPECT_EQ("0,0 450x300", display1
.bounds().ToString());
1243 EXPECT_EQ("0,0 450x300", root_windows
[0]->bounds().ToString());
1244 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1246 generator
.MoveMouseToInHost(0, 0);
1247 EXPECT_EQ("449,299", event_handler
.GetLocationAndReset());
1248 generator
.MoveMouseToInHost(599, 0);
1249 EXPECT_EQ("0,299", event_handler
.GetLocationAndReset());
1250 generator
.MoveMouseToInHost(599, 399);
1251 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1252 generator
.MoveMouseToInHost(0, 399);
1253 EXPECT_EQ("449,0", event_handler
.GetLocationAndReset());
1255 UpdateDisplay("600x400*2/l@1.5");
1256 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1257 root_windows
= Shell::GetAllRootWindows();
1258 EXPECT_EQ("0,0 300x450", display1
.bounds().ToString());
1259 EXPECT_EQ("0,0 300x450", root_windows
[0]->bounds().ToString());
1260 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1262 generator
.MoveMouseToInHost(0, 0);
1263 EXPECT_EQ("299,0", event_handler
.GetLocationAndReset());
1264 generator
.MoveMouseToInHost(599, 0);
1265 EXPECT_EQ("299,449", event_handler
.GetLocationAndReset());
1266 generator
.MoveMouseToInHost(599, 399);
1267 EXPECT_EQ("0,449", event_handler
.GetLocationAndReset());
1268 generator
.MoveMouseToInHost(0, 399);
1269 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1271 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1274 // Make sure that the compositor based mirroring can switch
1275 // from/to dock mode.
1276 TEST_F(DisplayControllerTest
, DockToSingle
) {
1277 if (!SupportsMultipleDisplays())
1280 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1282 const int64 internal_id
= 1;
1284 const DisplayInfo internal_display_info
=
1285 CreateDisplayInfo(internal_id
, 0, gfx::Display::ROTATE_0
);
1286 const DisplayInfo external_display_info
=
1287 CreateDisplayInfo(2, 1, gfx::Display::ROTATE_90
);
1289 std::vector
<DisplayInfo
> display_info_list
;
1291 display_info_list
.push_back(internal_display_info
);
1292 display_info_list
.push_back(external_display_info
);
1293 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1294 const int64 internal_display_id
=
1295 test::DisplayManagerTestApi(display_manager
).
1296 SetFirstDisplayAsInternalDisplay();
1297 EXPECT_EQ(internal_id
, internal_display_id
);
1298 EXPECT_EQ(2U, display_manager
->GetNumDisplays());
1301 display_info_list
.clear();
1302 display_info_list
.push_back(external_display_info
);
1303 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1304 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
1305 EXPECT_FALSE(Shell::GetPrimaryRootWindow()->GetHost()->
1306 GetRootTransform().IsIdentityOrIntegerTranslation());
1308 // Switch to single mode and make sure the transform is the one
1309 // for the internal display.
1310 display_info_list
.clear();
1311 display_info_list
.push_back(internal_display_info
);
1312 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1313 EXPECT_TRUE(Shell::GetPrimaryRootWindow()->GetHost()->
1314 GetRootTransform().IsIdentityOrIntegerTranslation());
1317 // Tests if switching two displays at the same time while the primary display
1318 // is swapped should not cause a crash. (crbug.com/426292)
1319 TEST_F(DisplayControllerTest
, ReplaceSwappedPrimary
) {
1320 if (!SupportsMultipleDisplays())
1322 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1324 const DisplayInfo first_display_info
=
1325 CreateDisplayInfo(10, 0, gfx::Display::ROTATE_0
);
1326 const DisplayInfo second_display_info
=
1327 CreateDisplayInfo(11, 1, gfx::Display::ROTATE_0
);
1329 std::vector
<DisplayInfo
> display_info_list
;
1331 display_info_list
.push_back(first_display_info
);
1332 display_info_list
.push_back(second_display_info
);
1333 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1335 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
1337 EXPECT_EQ(11, Shell::GetScreen()->GetPrimaryDisplay().id());
1339 display_info_list
.clear();
1340 const DisplayInfo new_first_display_info
=
1341 CreateDisplayInfo(20, 0, gfx::Display::ROTATE_0
);
1342 const DisplayInfo new_second_display_info
=
1343 CreateDisplayInfo(21, 1, gfx::Display::ROTATE_0
);
1344 display_info_list
.push_back(new_first_display_info
);
1345 display_info_list
.push_back(new_second_display_info
);
1346 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1348 EXPECT_EQ(20, Shell::GetScreen()->GetPrimaryDisplay().id());
1351 #if defined(USE_X11)
1352 TEST_F(DisplayControllerTest
, XWidowNameForRootWindow
) {
1353 EXPECT_EQ("aura_root_0", GetXWindowName(
1354 Shell::GetPrimaryRootWindow()->GetHost()));
1356 // Multiple display.
1357 UpdateDisplay("200x200,300x300");
1358 aura::Window
* primary
, *secondary
;
1359 GetPrimaryAndSeconary(&primary
, &secondary
);
1360 EXPECT_EQ("aura_root_0", GetXWindowName(primary
->GetHost()));
1361 EXPECT_EQ("aura_root_x", GetXWindowName(secondary
->GetHost()));
1364 primary
= secondary
= NULL
;
1365 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
1366 GetPrimaryAndSeconary(&primary
, &secondary
);
1367 EXPECT_EQ("aura_root_0", GetXWindowName(primary
->GetHost()));
1368 EXPECT_EQ("aura_root_x", GetXWindowName(secondary
->GetHost()));
1370 // Switching back to single display.
1371 UpdateDisplay("300x400");
1372 EXPECT_EQ("aura_root_0", GetXWindowName(
1373 Shell::GetPrimaryRootWindow()->GetHost()));