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/mouse_watcher.h"
33 #include "ui/views/mouse_watcher_view_host.h"
34 #include "ui/views/view.h"
35 #include "ui/views/widget/widget.h"
36 #include "ui/wm/public/activation_change_observer.h"
37 #include "ui/wm/public/activation_client.h"
41 #include "ui/gfx/x/x11_types.h"
48 const char kDesktopBackgroundView
[] = "DesktopBackgroundView";
53 explicit Resetter(T
* value
) : value_(*value
) {
57 T
value() { return value_
; }
61 DISALLOW_COPY_AND_ASSIGN(Resetter
);
64 class TestObserver
: public DisplayController::Observer
,
65 public gfx::DisplayObserver
,
66 public aura::client::FocusChangeObserver
,
67 public aura::client::ActivationChangeObserver
{
72 bounds_changed_count_(0),
73 rotation_changed_count_(0),
74 workarea_changed_count_(0),
75 primary_changed_count_(0),
76 changed_display_id_(0),
77 focus_changed_count_(0),
78 activation_changed_count_(0) {
79 Shell::GetInstance()->display_controller()->AddObserver(this);
80 Shell::GetScreen()->AddObserver(this);
81 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
83 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
87 ~TestObserver() override
{
88 Shell::GetInstance()->display_controller()->RemoveObserver(this);
89 Shell::GetScreen()->RemoveObserver(this);
90 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
92 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
96 // Overridden from DisplayController::Observer
97 void OnDisplayConfigurationChanging() override
{ ++changing_count_
; }
98 void OnDisplayConfigurationChanged() override
{ ++changed_count_
; }
100 // Overrideen from gfx::DisplayObserver
101 void OnDisplayMetricsChanged(const gfx::Display
& display
,
102 uint32_t metrics
) override
{
103 changed_display_id_
= display
.id();
104 if (metrics
& DISPLAY_METRIC_BOUNDS
)
105 ++bounds_changed_count_
;
106 if (metrics
& DISPLAY_METRIC_ROTATION
)
107 ++rotation_changed_count_
;
108 if (metrics
& DISPLAY_METRIC_WORK_AREA
)
109 ++workarea_changed_count_
;
110 if (metrics
& DISPLAY_METRIC_PRIMARY
)
111 ++primary_changed_count_
;
113 void OnDisplayAdded(const gfx::Display
& new_display
) override
{}
114 void OnDisplayRemoved(const gfx::Display
& old_display
) override
{}
116 // Overridden from aura::client::FocusChangeObserver
117 void OnWindowFocused(aura::Window
* gained_focus
,
118 aura::Window
* lost_focus
) override
{
119 focus_changed_count_
++;
122 // Overridden from aura::client::ActivationChangeObserver
123 void OnWindowActivated(aura::Window
* gained_active
,
124 aura::Window
* lost_active
) override
{
125 activation_changed_count_
++;
127 void OnAttemptToReactivateWindow(aura::Window
* request_active
,
128 aura::Window
* actual_active
) override
{}
130 int CountAndReset() {
131 EXPECT_EQ(changing_count_
, changed_count_
);
133 return Resetter
<int>(&changing_count_
).value();
136 int64
GetBoundsChangedCountAndReset() {
137 return Resetter
<int>(&bounds_changed_count_
).value();
140 int64
GetRotationChangedCountAndReset() {
141 return Resetter
<int>(&rotation_changed_count_
).value();
144 int64
GetWorkareaChangedCountAndReset() {
145 return Resetter
<int>(&workarea_changed_count_
).value();
148 int64
GetPrimaryChangedCountAndReset() {
149 return Resetter
<int>(&primary_changed_count_
).value();
152 int64
GetChangedDisplayIdAndReset() {
153 return Resetter
<int64
>(&changed_display_id_
).value();
156 int GetFocusChangedCountAndReset() {
157 return Resetter
<int>(&focus_changed_count_
).value();
160 int GetActivationChangedCountAndReset() {
161 return Resetter
<int>(&activation_changed_count_
).value();
168 int bounds_changed_count_
;
169 int rotation_changed_count_
;
170 int workarea_changed_count_
;
171 int primary_changed_count_
;
172 int64 changed_display_id_
;
174 int focus_changed_count_
;
175 int activation_changed_count_
;
177 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
180 gfx::Display
GetPrimaryDisplay() {
181 return Shell::GetScreen()->GetDisplayNearestWindow(
182 Shell::GetAllRootWindows()[0]);
185 gfx::Display
GetSecondaryDisplay() {
186 return Shell::GetScreen()->GetDisplayNearestWindow(
187 Shell::GetAllRootWindows()[1]);
190 void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position
,
192 DisplayLayout
layout(position
, offset
);
193 ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1);
194 Shell::GetInstance()->display_manager()->
195 SetLayoutForCurrentDisplays(layout
);
198 void SetSecondaryDisplayLayout(DisplayLayout::Position position
) {
199 SetSecondaryDisplayLayoutAndOffset(position
, 0);
202 void SetDefaultDisplayLayout(DisplayLayout::Position position
) {
203 Shell::GetInstance()->display_manager()->layout_store()->
204 SetDefaultDisplayLayout(DisplayLayout(position
, 0));
207 class DisplayControllerShutdownTest
: public test::AshTestBase
{
209 DisplayControllerShutdownTest() {}
210 ~DisplayControllerShutdownTest() override
{}
212 void TearDown() override
{
213 test::AshTestBase::TearDown();
214 if (!SupportsMultipleDisplays())
217 // Make sure that primary display is accessible after shutdown.
218 gfx::Display primary
= Shell::GetScreen()->GetPrimaryDisplay();
219 EXPECT_EQ("0,0 444x333", primary
.bounds().ToString());
220 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
224 DISALLOW_COPY_AND_ASSIGN(DisplayControllerShutdownTest
);
227 class StartupHelper
: public test::TestShellDelegate
,
228 public DisplayController::Observer
{
230 StartupHelper() : displays_initialized_(false) {}
231 ~StartupHelper() override
{}
233 // ash::ShellSelegate:
234 void PreInit() override
{
235 Shell::GetInstance()->display_controller()->AddObserver(this);
238 // ash::DisplayController::Observer:
239 void OnDisplaysInitialized() override
{
240 DCHECK(!displays_initialized_
);
241 displays_initialized_
= true;
244 bool displays_initialized() const {
245 return displays_initialized_
;
249 bool displays_initialized_
;
251 DISALLOW_COPY_AND_ASSIGN(StartupHelper
);
254 class DisplayControllerStartupTest
: public test::AshTestBase
{
256 DisplayControllerStartupTest() : startup_helper_(new StartupHelper
) {}
257 ~DisplayControllerStartupTest() override
{}
259 // ash::test::AshTestBase:
260 void SetUp() override
{
261 ash_test_helper()->set_test_shell_delegate(startup_helper_
);
262 test::AshTestBase::SetUp();
264 void TearDown() override
{
265 Shell::GetInstance()->display_controller()->RemoveObserver(startup_helper_
);
266 test::AshTestBase::TearDown();
269 const StartupHelper
* startup_helper() const { return startup_helper_
; }
272 StartupHelper
* startup_helper_
; // Owned by ash::Shell.
274 DISALLOW_COPY_AND_ASSIGN(DisplayControllerStartupTest
);
277 class TestEventHandler
: public ui::EventHandler
{
279 TestEventHandler() : target_root_(NULL
),
280 touch_radius_x_(0.0),
281 touch_radius_y_(0.0),
282 scroll_x_offset_(0.0),
283 scroll_y_offset_(0.0),
284 scroll_x_offset_ordinal_(0.0),
285 scroll_y_offset_ordinal_(0.0) {}
286 ~TestEventHandler() override
{}
288 void OnMouseEvent(ui::MouseEvent
* event
) override
{
289 if (event
->flags() & ui::EF_IS_SYNTHESIZED
&&
290 event
->type() != ui::ET_MOUSE_EXITED
&&
291 event
->type() != ui::ET_MOUSE_ENTERED
) {
294 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
295 mouse_location_
= event
->root_location();
296 target_root_
= target
->GetRootWindow();
297 event
->StopPropagation();
300 void OnTouchEvent(ui::TouchEvent
* 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
)
306 touch_radius_x_
= event
->radius_x();
307 touch_radius_y_
= event
->radius_y();
308 event
->StopPropagation();
311 void OnScrollEvent(ui::ScrollEvent
* event
) override
{
312 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
313 // Only record when the target is the background which covers
314 // entire root window.
315 if (target
->name() != kDesktopBackgroundView
)
318 if (event
->type() == ui::ET_SCROLL
) {
319 scroll_x_offset_
= event
->x_offset();
320 scroll_y_offset_
= event
->y_offset();
321 scroll_x_offset_ordinal_
= event
->x_offset_ordinal();
322 scroll_y_offset_ordinal_
= event
->y_offset_ordinal();
324 event
->StopPropagation();
327 std::string
GetLocationAndReset() {
328 std::string result
= mouse_location_
.ToString();
329 mouse_location_
.SetPoint(0, 0);
334 float touch_radius_x() { return touch_radius_x_
; }
335 float touch_radius_y() { return touch_radius_y_
; }
336 float scroll_x_offset() { return scroll_x_offset_
; }
337 float scroll_y_offset() { return scroll_y_offset_
; }
338 float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_
; }
339 float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_
; }
342 gfx::Point mouse_location_
;
343 aura::Window
* target_root_
;
345 float touch_radius_x_
;
346 float touch_radius_y_
;
347 float scroll_x_offset_
;
348 float scroll_y_offset_
;
349 float scroll_x_offset_ordinal_
;
350 float scroll_y_offset_ordinal_
;
352 DISALLOW_COPY_AND_ASSIGN(TestEventHandler
);
355 gfx::Display::Rotation
GetStoredRotation(int64 id
) {
356 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id
).rotation();
359 float GetStoredUIScale(int64 id
) {
360 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id
).
361 GetEffectiveUIScale();
365 void GetPrimaryAndSeconary(aura::Window
** primary
,
366 aura::Window
** secondary
) {
367 *primary
= Shell::GetPrimaryRootWindow();
368 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
369 *secondary
= root_windows
[0] == *primary
? root_windows
[1] : root_windows
[0];
372 std::string
GetXWindowName(aura::WindowTreeHost
* host
) {
374 XFetchName(gfx::GetXDisplay(), host
->GetAcceleratedWidget(), &name
);
375 std::string
ret(name
);
381 class TestMouseWatcherListener
: public views::MouseWatcherListener
{
383 TestMouseWatcherListener() {}
386 // views::MouseWatcherListener:
387 void MouseMovedOutOfHost() override
{}
389 DISALLOW_COPY_AND_ASSIGN(TestMouseWatcherListener
);
394 typedef test::AshTestBase DisplayControllerTest
;
396 TEST_F(DisplayControllerShutdownTest
, Shutdown
) {
397 if (!SupportsMultipleDisplays())
400 UpdateDisplay("444x333, 200x200");
403 TEST_F(DisplayControllerStartupTest
, Startup
) {
404 if (!SupportsMultipleDisplays())
407 EXPECT_TRUE(startup_helper()->displays_initialized());
410 TEST_F(DisplayControllerTest
, SecondaryDisplayLayout
) {
411 if (!SupportsMultipleDisplays())
414 // Creates windows to catch activation change event.
415 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
418 TestObserver observer
;
419 UpdateDisplay("500x500,400x400");
420 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
421 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
422 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
423 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
424 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
425 gfx::Insets
insets(5, 5, 5, 5);
426 int64 secondary_display_id
= ScreenUtil::GetSecondaryDisplay().id();
427 Shell::GetInstance()->display_manager()->UpdateWorkAreaOfDisplay(
428 secondary_display_id
, insets
);
430 // Default layout is RIGHT.
431 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
432 EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
433 EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());
434 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
435 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
437 // Layout the secondary display to the bottom of the primary.
438 SetSecondaryDisplayLayout(DisplayLayout::BOTTOM
);
439 EXPECT_EQ(1, observer
.CountAndReset());
440 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
441 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
442 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
443 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
444 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
445 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
446 EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
447 EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());
449 // Layout the secondary display to the left of the primary.
450 SetSecondaryDisplayLayout(DisplayLayout::LEFT
);
451 EXPECT_EQ(1, observer
.CountAndReset());
452 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
453 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
454 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
455 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
456 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
457 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
458 EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
459 EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());
461 // Layout the secondary display to the top of the primary.
462 SetSecondaryDisplayLayout(DisplayLayout::TOP
);
463 EXPECT_EQ(1, observer
.CountAndReset());
464 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
465 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
466 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
467 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
468 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
469 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
470 EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
471 EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
473 // Layout to the right with an offset.
474 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, 300);
475 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
476 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
477 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
478 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
479 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
480 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
481 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
482 EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString());
484 // Keep the minimum 100.
485 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, 490);
486 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
487 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
488 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
489 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
490 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
491 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
492 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
493 EXPECT_EQ("500,400 400x400", GetSecondaryDisplay().bounds().ToString());
495 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, -400);
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("500,-300 400x400", GetSecondaryDisplay().bounds().ToString());
505 // Layout to the bottom with an offset.
506 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -200);
507 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
508 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
509 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
510 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
511 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
512 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
513 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
514 EXPECT_EQ("-200,500 400x400", GetSecondaryDisplay().bounds().ToString());
516 // Keep the minimum 100.
517 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, 490);
518 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
519 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
520 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
521 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
522 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
523 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
524 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
525 EXPECT_EQ("400,500 400x400", GetSecondaryDisplay().bounds().ToString());
527 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -400);
528 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
529 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
530 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
531 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
532 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
533 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
534 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
535 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
537 // Setting the same layout shouldn't invoke observers.
538 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -400);
539 EXPECT_EQ(0, observer
.GetChangedDisplayIdAndReset());
540 EXPECT_EQ(0, observer
.GetBoundsChangedCountAndReset());
541 EXPECT_EQ(0, observer
.GetWorkareaChangedCountAndReset());
542 EXPECT_EQ(0, observer
.CountAndReset()); // resize and add
543 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
544 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
545 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
546 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
548 UpdateDisplay("500x500");
549 EXPECT_LE(1, observer
.GetFocusChangedCountAndReset());
550 EXPECT_LE(1, observer
.GetActivationChangedCountAndReset());
555 DisplayInfo
CreateDisplayInfo(int64 id
,
557 gfx::Display::Rotation rotation
) {
558 DisplayInfo
info(id
, "", false);
559 info
.SetBounds(gfx::Rect(0, y
, 500, 500));
560 info
.set_rotation(rotation
);
564 DisplayInfo
CreateMirroredDisplayInfo(int64 id
,
565 float device_scale_factor
) {
566 DisplayInfo info
= CreateDisplayInfo(id
, 0, gfx::Display::ROTATE_0
);
567 info
.set_device_scale_factor(device_scale_factor
);
573 TEST_F(DisplayControllerTest
, MirrorToDockedWithFullscreen
) {
574 if (!SupportsMultipleDisplays())
577 // Creates windows to catch activation change event.
578 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
582 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
584 const DisplayInfo internal_display_info
=
585 CreateMirroredDisplayInfo(1, 2.0f
);
586 const DisplayInfo external_display_info
=
587 CreateMirroredDisplayInfo(2, 1.0f
);
589 std::vector
<DisplayInfo
> display_info_list
;
591 display_info_list
.push_back(internal_display_info
);
592 display_info_list
.push_back(external_display_info
);
593 display_manager
->OnNativeDisplaysChanged(display_info_list
);
594 const int64 internal_display_id
=
595 test::DisplayManagerTestApi(display_manager
).
596 SetFirstDisplayAsInternalDisplay();
597 EXPECT_EQ(1, internal_display_id
);
598 EXPECT_EQ(2U, display_manager
->num_connected_displays());
599 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
601 wm::WindowState
* window_state
= wm::GetWindowState(w1
.get());
602 const wm::WMEvent
toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN
);
603 window_state
->OnWMEvent(&toggle_fullscreen_event
);
604 EXPECT_TRUE(window_state
->IsFullscreen());
605 EXPECT_EQ("0,0 250x250", w1
->bounds().ToString());
607 TestObserver observer
;
608 display_info_list
.clear();
609 display_info_list
.push_back(external_display_info
);
610 display_manager
->OnNativeDisplaysChanged(display_info_list
);
611 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
612 EXPECT_EQ(1U, display_manager
->num_connected_displays());
613 // Observers are called due to primary change.
614 EXPECT_EQ(2, observer
.GetChangedDisplayIdAndReset());
615 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
616 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
617 EXPECT_EQ(1, observer
.GetPrimaryChangedCountAndReset());
618 EXPECT_EQ(1, observer
.CountAndReset());
619 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
620 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
622 EXPECT_TRUE(window_state
->IsFullscreen());
623 EXPECT_EQ("0,0 500x500", w1
->bounds().ToString());
626 TEST_F(DisplayControllerTest
, BoundsUpdated
) {
627 if (!SupportsMultipleDisplays())
630 // Creates windows to catch activation change event.
631 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
634 TestObserver observer
;
635 SetDefaultDisplayLayout(DisplayLayout::BOTTOM
);
636 UpdateDisplay("200x200,300x300"); // layout, resize and add.
637 EXPECT_EQ(1, observer
.CountAndReset());
638 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
639 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
641 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
642 gfx::Insets
insets(5, 5, 5, 5);
643 display_manager
->UpdateWorkAreaOfDisplay(
644 ScreenUtil::GetSecondaryDisplay().id(), insets
);
646 EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
647 EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
648 EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
650 UpdateDisplay("400x400,200x200");
651 EXPECT_EQ(1, observer
.CountAndReset()); // two resizes
652 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
653 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
654 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
655 EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
657 UpdateDisplay("400x400,300x300");
658 EXPECT_EQ(1, observer
.CountAndReset());
659 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
660 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
661 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
662 EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
664 UpdateDisplay("400x400");
665 EXPECT_EQ(1, observer
.CountAndReset());
666 EXPECT_LE(1, observer
.GetFocusChangedCountAndReset());
667 EXPECT_LE(1, observer
.GetActivationChangedCountAndReset());
668 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
669 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
671 UpdateDisplay("400x500*2,300x300");
672 EXPECT_EQ(1, observer
.CountAndReset());
673 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
674 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
675 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
676 EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
677 EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
680 UpdateDisplay("400x500*2,300x300");
681 // We still call into Pre/PostDisplayConfigurationChange().
682 EXPECT_EQ(1, observer
.CountAndReset());
683 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
684 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
687 observer
.GetRotationChangedCountAndReset(); // we only want to reset.
688 int64 primary_id
= GetPrimaryDisplay().id();
689 display_manager
->SetDisplayRotation(primary_id
, gfx::Display::ROTATE_90
);
690 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
691 EXPECT_EQ(1, observer
.CountAndReset());
692 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
693 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
694 display_manager
->SetDisplayRotation(primary_id
, gfx::Display::ROTATE_90
);
695 EXPECT_EQ(0, observer
.GetRotationChangedCountAndReset());
696 EXPECT_EQ(0, observer
.CountAndReset());
697 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
698 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
700 // UI scale is eanbled only on internal display.
701 int64 secondary_id
= GetSecondaryDisplay().id();
702 test::DisplayManagerTestApi(display_manager
)
703 .SetInternalDisplayId(secondary_id
);
705 display_manager
->SetDisplayUIScale(secondary_id
, 1.125f
);
706 EXPECT_EQ(1, observer
.CountAndReset());
707 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
708 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
709 display_manager
->SetDisplayUIScale(secondary_id
, 1.125f
);
710 EXPECT_EQ(0, observer
.CountAndReset());
711 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
712 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
713 display_manager
->SetDisplayUIScale(primary_id
, 1.125f
);
714 EXPECT_EQ(0, observer
.CountAndReset());
715 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
716 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
717 display_manager
->SetDisplayUIScale(primary_id
, 1.125f
);
718 EXPECT_EQ(0, observer
.CountAndReset());
719 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
720 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
723 TEST_F(DisplayControllerTest
, SwapPrimary
) {
724 if (!SupportsMultipleDisplays())
727 DisplayController
* display_controller
=
728 Shell::GetInstance()->display_controller();
729 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
731 UpdateDisplay("200x200,300x300");
732 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
733 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
735 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
736 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
738 EXPECT_NE(primary_display
.id(), secondary_display
.id());
739 aura::Window
* primary_root
=
740 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
741 aura::Window
* secondary_root
=
742 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
743 EXPECT_NE(primary_root
, secondary_root
);
744 aura::Window
* shelf_window
=
745 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
746 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
747 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
748 EXPECT_EQ(primary_display
.id(),
749 Shell::GetScreen()->GetDisplayNearestPoint(
750 gfx::Point(-100, -100)).id());
751 EXPECT_EQ(primary_display
.id(),
752 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
754 EXPECT_EQ("0,0 200x200", primary_display
.bounds().ToString());
755 EXPECT_EQ("0,0 200x153", primary_display
.work_area().ToString());
756 EXPECT_EQ("200,0 300x300", secondary_display
.bounds().ToString());
757 EXPECT_EQ("200,0 300x253", secondary_display
.work_area().ToString());
758 EXPECT_EQ("right, 50",
759 display_manager
->GetCurrentDisplayLayout().ToString());
761 // Switch primary and secondary
762 display_controller
->SetPrimaryDisplay(secondary_display
);
763 const DisplayLayout
& inverted_layout
=
764 display_manager
->GetCurrentDisplayLayout();
765 EXPECT_EQ("left, -50", inverted_layout
.ToString());
767 EXPECT_EQ(secondary_display
.id(),
768 Shell::GetScreen()->GetPrimaryDisplay().id());
769 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
770 EXPECT_EQ(primary_display
.id(),
771 Shell::GetScreen()->GetDisplayNearestPoint(
772 gfx::Point(-100, -100)).id());
773 EXPECT_EQ(secondary_display
.id(),
774 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
778 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
781 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
782 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
783 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
785 // Test if the bounds are correctly swapped.
786 gfx::Display swapped_primary
= Shell::GetScreen()->GetPrimaryDisplay();
787 gfx::Display swapped_secondary
= ScreenUtil::GetSecondaryDisplay();
788 EXPECT_EQ("0,0 300x300", swapped_primary
.bounds().ToString());
789 EXPECT_EQ("0,0 300x253", swapped_primary
.work_area().ToString());
790 EXPECT_EQ("-200,-50 200x200", swapped_secondary
.bounds().ToString());
792 EXPECT_EQ("-200,-50 200x153", swapped_secondary
.work_area().ToString());
794 aura::WindowTracker tracker
;
795 tracker
.Add(primary_root
);
796 tracker
.Add(secondary_root
);
798 // Deleting 2nd display should move the primary to original primary display.
799 UpdateDisplay("200x200");
800 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
801 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
802 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
803 EXPECT_EQ(primary_display
.id(),
804 Shell::GetScreen()->GetDisplayNearestPoint(
805 gfx::Point(-100, -100)).id());
806 EXPECT_EQ(primary_display
.id(),
807 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
808 EXPECT_TRUE(tracker
.Contains(primary_root
));
809 EXPECT_FALSE(tracker
.Contains(secondary_root
));
810 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
813 TEST_F(DisplayControllerTest
, FindNearestDisplay
) {
814 if (!SupportsMultipleDisplays())
817 DisplayController
* display_controller
=
818 Shell::GetInstance()->display_controller();
819 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
821 UpdateDisplay("200x200,300x300");
822 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
823 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
825 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
826 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
827 EXPECT_NE(primary_display
.id(), secondary_display
.id());
828 aura::Window
* primary_root
=
829 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
830 aura::Window
* secondary_root
=
831 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
832 EXPECT_NE(primary_root
, secondary_root
);
834 // Test that points outside of any display return the nearest display.
835 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
836 gfx::Point(-100, 0)).id());
837 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
838 gfx::Point(0, -100)).id());
839 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
840 gfx::Point(100, 100)).id());
841 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
842 gfx::Point(224, 25)).id());
843 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
844 gfx::Point(226, 25)).id());
845 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
846 gfx::Point(600, 100)).id());
847 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
848 gfx::Point(174, 225)).id());
849 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
850 gfx::Point(176, 225)).id());
851 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
852 gfx::Point(300, 400)).id());
855 TEST_F(DisplayControllerTest
, SwapPrimaryById
) {
856 if (!SupportsMultipleDisplays())
859 DisplayController
* display_controller
=
860 Shell::GetInstance()->display_controller();
861 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
863 UpdateDisplay("200x200,300x300");
864 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
865 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
867 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
868 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
870 EXPECT_NE(primary_display
.id(), secondary_display
.id());
871 aura::Window
* primary_root
=
872 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
873 aura::Window
* secondary_root
=
874 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
875 aura::Window
* shelf_window
=
876 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
877 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
878 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
879 EXPECT_NE(primary_root
, secondary_root
);
880 EXPECT_EQ(primary_display
.id(),
881 Shell::GetScreen()->GetDisplayNearestPoint(
882 gfx::Point(-100, -100)).id());
883 EXPECT_EQ(primary_display
.id(),
884 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
886 // Switch primary and secondary by display ID.
887 TestObserver observer
;
888 display_controller
->SetPrimaryDisplayId(secondary_display
.id());
889 EXPECT_EQ(secondary_display
.id(),
890 Shell::GetScreen()->GetPrimaryDisplay().id());
891 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
892 EXPECT_LT(0, observer
.CountAndReset());
896 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
899 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
900 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
901 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
903 const DisplayLayout
& inverted_layout
=
904 display_manager
->GetCurrentDisplayLayout();
906 EXPECT_EQ("left, -50", inverted_layout
.ToString());
908 // Calling the same ID don't do anything.
909 display_controller
->SetPrimaryDisplayId(secondary_display
.id());
910 EXPECT_EQ(0, observer
.CountAndReset());
912 aura::WindowTracker tracker
;
913 tracker
.Add(primary_root
);
914 tracker
.Add(secondary_root
);
916 // Deleting 2nd display should move the primary to original primary display.
917 UpdateDisplay("200x200");
918 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
919 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
920 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
921 EXPECT_EQ(primary_display
.id(),
922 Shell::GetScreen()->GetDisplayNearestPoint(
923 gfx::Point(-100, -100)).id());
924 EXPECT_EQ(primary_display
.id(),
925 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
926 EXPECT_TRUE(tracker
.Contains(primary_root
));
927 EXPECT_FALSE(tracker
.Contains(secondary_root
));
928 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
930 // Adding 2nd display with the same ID. The 2nd display should become primary
931 // since secondary id is still stored as desirable_primary_id.
932 std::vector
<DisplayInfo
> display_info_list
;
933 display_info_list
.push_back(
934 display_manager
->GetDisplayInfo(primary_display
.id()));
935 display_info_list
.push_back(
936 display_manager
->GetDisplayInfo(secondary_display
.id()));
937 display_manager
->OnNativeDisplaysChanged(display_info_list
);
939 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
940 EXPECT_EQ(secondary_display
.id(),
941 Shell::GetScreen()->GetPrimaryDisplay().id());
942 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
945 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
948 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
949 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
951 // Deleting 2nd display and adding 2nd display with a different ID. The 2nd
952 // display shouldn't become primary.
953 UpdateDisplay("200x200");
954 DisplayInfo
third_display_info(
955 secondary_display
.id() + 1, std::string(), false);
956 third_display_info
.SetBounds(secondary_display
.bounds());
957 ASSERT_NE(primary_display
.id(), third_display_info
.id());
959 const DisplayInfo
& primary_display_info
=
960 display_manager
->GetDisplayInfo(primary_display
.id());
961 std::vector
<DisplayInfo
> display_info_list2
;
962 display_info_list2
.push_back(primary_display_info
);
963 display_info_list2
.push_back(third_display_info
);
964 display_manager
->OnNativeDisplaysChanged(display_info_list2
);
965 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
966 EXPECT_EQ(primary_display
.id(),
967 Shell::GetScreen()->GetPrimaryDisplay().id());
968 EXPECT_EQ(third_display_info
.id(), ScreenUtil::GetSecondaryDisplay().id());
971 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
974 display_controller
->GetRootWindowForDisplayId(third_display_info
.id()));
975 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
978 TEST_F(DisplayControllerTest
, OverscanInsets
) {
979 if (!SupportsMultipleDisplays())
982 DisplayController
* display_controller
=
983 Shell::GetInstance()->display_controller();
984 TestEventHandler event_handler
;
985 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
987 UpdateDisplay("120x200,300x400*2");
988 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
989 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
991 display_controller
->SetOverscanInsets(display1
.id(),
992 gfx::Insets(10, 15, 20, 25));
993 EXPECT_EQ("0,0 80x170", root_windows
[0]->bounds().ToString());
994 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
995 EXPECT_EQ("80,0 150x200",
996 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
998 ui::test::EventGenerator
generator(root_windows
[0]);
999 generator
.MoveMouseToInHost(20, 25);
1000 EXPECT_EQ("5,15", event_handler
.GetLocationAndReset());
1002 display_controller
->SetOverscanInsets(display1
.id(), gfx::Insets());
1003 EXPECT_EQ("0,0 120x200", root_windows
[0]->bounds().ToString());
1004 EXPECT_EQ("120,0 150x200",
1005 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1007 generator
.MoveMouseToInHost(30, 20);
1008 EXPECT_EQ("30,20", event_handler
.GetLocationAndReset());
1010 // Make sure the root window transformer uses correct scale
1011 // factor when swapping display. Test crbug.com/253690.
1012 UpdateDisplay("400x300*2,600x400/o");
1013 root_windows
= Shell::GetAllRootWindows();
1015 Shell::GetAllRootWindows()[1]->GetHost()->
1016 GetRootTransform().TransformPoint(&point
);
1017 EXPECT_EQ("15,10", point
.ToString());
1019 display_controller
->SwapPrimaryDisplay();
1020 point
.SetPoint(0, 0);
1021 Shell::GetAllRootWindows()[1]->GetHost()->
1022 GetRootTransform().TransformPoint(&point
);
1023 EXPECT_EQ("15,10", point
.ToString());
1025 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1028 TEST_F(DisplayControllerTest
, Rotate
) {
1029 if (!SupportsMultipleDisplays())
1032 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1033 TestEventHandler event_handler
;
1034 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1036 UpdateDisplay("120x200,300x400*2");
1037 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1038 int64 display2_id
= ScreenUtil::GetSecondaryDisplay().id();
1039 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1040 ui::test::EventGenerator
generator1(root_windows
[0]);
1042 TestObserver observer
;
1043 EXPECT_EQ("120x200", root_windows
[0]->bounds().size().ToString());
1044 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
1045 EXPECT_EQ("120,0 150x200",
1046 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1047 generator1
.MoveMouseToInHost(50, 40);
1048 EXPECT_EQ("50,40", event_handler
.GetLocationAndReset());
1049 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display1
.id()));
1050 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display2_id
));
1051 EXPECT_EQ(0, observer
.GetRotationChangedCountAndReset());
1053 display_manager
->SetDisplayRotation(display1
.id(),
1054 gfx::Display::ROTATE_90
);
1055 EXPECT_EQ("200x120", root_windows
[0]->bounds().size().ToString());
1056 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
1057 EXPECT_EQ("200,0 150x200",
1058 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1059 generator1
.MoveMouseToInHost(50, 40);
1060 EXPECT_EQ("40,69", event_handler
.GetLocationAndReset());
1061 EXPECT_EQ(gfx::Display::ROTATE_90
, GetStoredRotation(display1
.id()));
1062 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display2_id
));
1063 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1065 DisplayLayout
display_layout(DisplayLayout::BOTTOM
, 50);
1066 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
1067 EXPECT_EQ("50,120 150x200",
1068 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1070 display_manager
->SetDisplayRotation(display2_id
,
1071 gfx::Display::ROTATE_270
);
1072 EXPECT_EQ("200x120", root_windows
[0]->bounds().size().ToString());
1073 EXPECT_EQ("200x150", root_windows
[1]->bounds().size().ToString());
1074 EXPECT_EQ("50,120 200x150",
1075 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1076 EXPECT_EQ(gfx::Display::ROTATE_90
, GetStoredRotation(display1
.id()));
1077 EXPECT_EQ(gfx::Display::ROTATE_270
, GetStoredRotation(display2_id
));
1078 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1080 #if !defined(OS_WIN)
1081 ui::test::EventGenerator
generator2(root_windows
[1]);
1082 generator2
.MoveMouseToInHost(50, 40);
1083 EXPECT_EQ("179,25", event_handler
.GetLocationAndReset());
1084 display_manager
->SetDisplayRotation(display1
.id(),
1085 gfx::Display::ROTATE_180
);
1087 EXPECT_EQ("120x200", root_windows
[0]->bounds().size().ToString());
1088 EXPECT_EQ("200x150", root_windows
[1]->bounds().size().ToString());
1089 // Dislay must share at least 100, so the x's offset becomes 20.
1090 EXPECT_EQ("20,200 200x150",
1091 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1092 EXPECT_EQ(gfx::Display::ROTATE_180
, GetStoredRotation(display1
.id()));
1093 EXPECT_EQ(gfx::Display::ROTATE_270
, GetStoredRotation(display2_id
));
1094 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1096 generator1
.MoveMouseToInHost(50, 40);
1097 EXPECT_EQ("69,159", event_handler
.GetLocationAndReset());
1100 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1103 TEST_F(DisplayControllerTest
, ScaleRootWindow
) {
1104 if (!SupportsMultipleDisplays())
1107 TestEventHandler event_handler
;
1108 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1110 UpdateDisplay("600x400*2@1.5,500x300");
1112 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1113 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1114 test::DisplayManagerTestApi(display_manager
)
1115 .SetInternalDisplayId(display1
.id());
1117 gfx::Display display2
= ScreenUtil::GetSecondaryDisplay();
1118 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1119 EXPECT_EQ("0,0 450x300", display1
.bounds().ToString());
1120 EXPECT_EQ("0,0 450x300", root_windows
[0]->bounds().ToString());
1121 EXPECT_EQ("450,0 500x300", display2
.bounds().ToString());
1122 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1123 EXPECT_EQ(1.0f
, GetStoredUIScale(display2
.id()));
1125 ui::test::EventGenerator
generator(root_windows
[0]);
1126 generator
.MoveMouseToInHost(599, 200);
1127 EXPECT_EQ("449,150", event_handler
.GetLocationAndReset());
1129 display_manager
->SetDisplayUIScale(display1
.id(), 1.25f
);
1130 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1131 display2
= ScreenUtil::GetSecondaryDisplay();
1132 EXPECT_EQ("0,0 375x250", display1
.bounds().ToString());
1133 EXPECT_EQ("0,0 375x250", root_windows
[0]->bounds().ToString());
1134 EXPECT_EQ("375,0 500x300", display2
.bounds().ToString());
1135 EXPECT_EQ(1.25f
, GetStoredUIScale(display1
.id()));
1136 EXPECT_EQ(1.0f
, GetStoredUIScale(display2
.id()));
1138 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1141 TEST_F(DisplayControllerTest
, TouchScale
) {
1142 if (!SupportsMultipleDisplays())
1145 TestEventHandler event_handler
;
1146 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1148 UpdateDisplay("200x200*2");
1149 gfx::Display display
= Shell::GetScreen()->GetPrimaryDisplay();
1150 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1151 aura::Window
* root_window
= root_windows
[0];
1152 ui::test::EventGenerator
generator(root_window
);
1154 generator
.PressMoveAndReleaseTouchTo(50, 50);
1155 // Default test touches have radius_x/y = 1.0, with device scale
1156 // factor = 2, the scaled radius_x/y should be 0.5.
1157 EXPECT_EQ(0.5, event_handler
.touch_radius_x());
1158 EXPECT_EQ(0.5, event_handler
.touch_radius_y());
1160 generator
.ScrollSequence(gfx::Point(0,0),
1161 base::TimeDelta::FromMilliseconds(100),
1164 // ordinal_offset is invariant to the device scale factor.
1165 EXPECT_EQ(event_handler
.scroll_x_offset(),
1166 event_handler
.scroll_x_offset_ordinal());
1167 EXPECT_EQ(event_handler
.scroll_y_offset(),
1168 event_handler
.scroll_y_offset_ordinal());
1170 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1173 TEST_F(DisplayControllerTest
, ConvertHostToRootCoords
) {
1174 if (!SupportsMultipleDisplays())
1177 TestEventHandler event_handler
;
1178 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1180 UpdateDisplay("600x400*2/r@1.5");
1182 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1183 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1184 EXPECT_EQ("0,0 300x450", display1
.bounds().ToString());
1185 EXPECT_EQ("0,0 300x450", root_windows
[0]->bounds().ToString());
1186 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1188 ui::test::EventGenerator
generator(root_windows
[0]);
1189 generator
.MoveMouseToInHost(0, 0);
1190 EXPECT_EQ("0,449", event_handler
.GetLocationAndReset());
1191 generator
.MoveMouseToInHost(599, 0);
1192 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1193 generator
.MoveMouseToInHost(599, 399);
1194 EXPECT_EQ("299,0", event_handler
.GetLocationAndReset());
1195 generator
.MoveMouseToInHost(0, 399);
1196 EXPECT_EQ("299,449", event_handler
.GetLocationAndReset());
1198 UpdateDisplay("600x400*2/u@1.5");
1199 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1200 root_windows
= Shell::GetAllRootWindows();
1201 EXPECT_EQ("0,0 450x300", display1
.bounds().ToString());
1202 EXPECT_EQ("0,0 450x300", root_windows
[0]->bounds().ToString());
1203 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1205 generator
.MoveMouseToInHost(0, 0);
1206 EXPECT_EQ("449,299", event_handler
.GetLocationAndReset());
1207 generator
.MoveMouseToInHost(599, 0);
1208 EXPECT_EQ("0,299", event_handler
.GetLocationAndReset());
1209 generator
.MoveMouseToInHost(599, 399);
1210 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1211 generator
.MoveMouseToInHost(0, 399);
1212 EXPECT_EQ("449,0", event_handler
.GetLocationAndReset());
1214 UpdateDisplay("600x400*2/l@1.5");
1215 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1216 root_windows
= Shell::GetAllRootWindows();
1217 EXPECT_EQ("0,0 300x450", display1
.bounds().ToString());
1218 EXPECT_EQ("0,0 300x450", root_windows
[0]->bounds().ToString());
1219 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1221 generator
.MoveMouseToInHost(0, 0);
1222 EXPECT_EQ("299,0", event_handler
.GetLocationAndReset());
1223 generator
.MoveMouseToInHost(599, 0);
1224 EXPECT_EQ("299,449", event_handler
.GetLocationAndReset());
1225 generator
.MoveMouseToInHost(599, 399);
1226 EXPECT_EQ("0,449", event_handler
.GetLocationAndReset());
1227 generator
.MoveMouseToInHost(0, 399);
1228 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1230 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1233 // Make sure that the compositor based mirroring can switch
1234 // from/to dock mode.
1235 TEST_F(DisplayControllerTest
, DockToSingle
) {
1236 if (!SupportsMultipleDisplays())
1239 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1241 const int64 internal_id
= 1;
1243 const DisplayInfo internal_display_info
=
1244 CreateDisplayInfo(internal_id
, 0, gfx::Display::ROTATE_0
);
1245 const DisplayInfo external_display_info
=
1246 CreateDisplayInfo(2, 1, gfx::Display::ROTATE_90
);
1248 std::vector
<DisplayInfo
> display_info_list
;
1250 display_info_list
.push_back(internal_display_info
);
1251 display_info_list
.push_back(external_display_info
);
1252 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1253 const int64 internal_display_id
=
1254 test::DisplayManagerTestApi(display_manager
).
1255 SetFirstDisplayAsInternalDisplay();
1256 EXPECT_EQ(internal_id
, internal_display_id
);
1257 EXPECT_EQ(2U, display_manager
->GetNumDisplays());
1260 display_info_list
.clear();
1261 display_info_list
.push_back(external_display_info
);
1262 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1263 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
1264 EXPECT_FALSE(Shell::GetPrimaryRootWindow()->GetHost()->
1265 GetRootTransform().IsIdentityOrIntegerTranslation());
1267 // Switch to single mode and make sure the transform is the one
1268 // for the internal display.
1269 display_info_list
.clear();
1270 display_info_list
.push_back(internal_display_info
);
1271 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1272 EXPECT_TRUE(Shell::GetPrimaryRootWindow()->GetHost()->
1273 GetRootTransform().IsIdentityOrIntegerTranslation());
1276 // Tests if switching two displays at the same time while the primary display
1277 // is swapped should not cause a crash. (crbug.com/426292)
1278 TEST_F(DisplayControllerTest
, ReplaceSwappedPrimary
) {
1279 if (!SupportsMultipleDisplays())
1281 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1283 const DisplayInfo first_display_info
=
1284 CreateDisplayInfo(10, 0, gfx::Display::ROTATE_0
);
1285 const DisplayInfo second_display_info
=
1286 CreateDisplayInfo(11, 1, gfx::Display::ROTATE_0
);
1288 std::vector
<DisplayInfo
> display_info_list
;
1290 display_info_list
.push_back(first_display_info
);
1291 display_info_list
.push_back(second_display_info
);
1292 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1294 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
1296 EXPECT_EQ(11, Shell::GetScreen()->GetPrimaryDisplay().id());
1298 display_info_list
.clear();
1299 const DisplayInfo new_first_display_info
=
1300 CreateDisplayInfo(20, 0, gfx::Display::ROTATE_0
);
1301 const DisplayInfo new_second_display_info
=
1302 CreateDisplayInfo(21, 1, gfx::Display::ROTATE_0
);
1303 display_info_list
.push_back(new_first_display_info
);
1304 display_info_list
.push_back(new_second_display_info
);
1305 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1307 EXPECT_EQ(20, Shell::GetScreen()->GetPrimaryDisplay().id());
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()));
1336 TEST_F(DisplayControllerTest
, UpdateMouseLocationAfterDisplayChange
) {
1337 if (!SupportsMultipleDisplays())
1340 UpdateDisplay("200x200,300x300");
1341 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1343 aura::Env
* env
= aura::Env::GetInstance();
1345 ui::test::EventGenerator
generator(root_windows
[0]);
1347 // Set the initial position.
1348 generator
.MoveMouseToInHost(350, 150);
1349 EXPECT_EQ("350,150", env
->last_mouse_location().ToString());
1351 // A mouse pointer will stay in the 2nd display.
1352 UpdateDisplay("300x300,200x200");
1353 EXPECT_EQ("450,50", env
->last_mouse_location().ToString());
1355 // A mouse pointer will be outside of displays and move to the
1356 // center of 2nd display.
1357 UpdateDisplay("300x300,100x100");
1358 EXPECT_EQ("350,50", env
->last_mouse_location().ToString());
1360 // 2nd display was disconnected, and the cursor is
1361 // now in the 1st display.
1362 UpdateDisplay("400x400");
1363 EXPECT_EQ("50,350", env
->last_mouse_location().ToString());
1365 // 1st display's resolution has changed, and the mouse pointer is
1366 // now outside. Move the mouse pointer to the center of 1st display.
1367 UpdateDisplay("300x300");
1368 EXPECT_EQ("150,150", env
->last_mouse_location().ToString());
1370 // Move the mouse pointer to the bottom of 1st display.
1371 generator
.MoveMouseToInHost(150, 290);
1372 EXPECT_EQ("150,290", env
->last_mouse_location().ToString());
1374 // The mouse pointer is now on 2nd display.
1375 UpdateDisplay("300x280,200x200");
1376 EXPECT_EQ("450,10", env
->last_mouse_location().ToString());
1379 TEST_F(DisplayControllerTest
, UpdateMouseLocationAfterDisplayChange_2ndOnLeft
) {
1380 if (!SupportsMultipleDisplays())
1383 // Set the 2nd display on the left.
1384 DisplayLayoutStore
* layout_store
=
1385 Shell::GetInstance()->display_manager()->layout_store();
1386 DisplayLayout layout
= layout_store
->default_display_layout();
1387 layout
.position
= DisplayLayout::LEFT
;
1388 layout_store
->SetDefaultDisplayLayout(layout
);
1390 UpdateDisplay("200x200,300x300");
1391 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1393 EXPECT_EQ("-300,0 300x300",
1394 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1396 aura::Env
* env
= aura::Env::GetInstance();
1398 // Set the initial position.
1399 root_windows
[0]->MoveCursorTo(gfx::Point(-150, 250));
1400 EXPECT_EQ("-150,250", env
->last_mouse_location().ToString());
1402 // A mouse pointer will stay in 2nd display.
1403 UpdateDisplay("300x300,200x300");
1404 EXPECT_EQ("-50,150", env
->last_mouse_location().ToString());
1406 // A mouse pointer will be outside of displays and move to the
1407 // center of 2nd display.
1408 UpdateDisplay("300x300,200x100");
1409 EXPECT_EQ("-100,50", env
->last_mouse_location().ToString());
1411 // 2nd display was disconnected. Mouse pointer should move to
1413 UpdateDisplay("300x300");
1414 EXPECT_EQ("150,150", env
->last_mouse_location().ToString());
1417 // Test that the cursor swaps displays and that its scale factor and rotation
1418 // are updated when the primary display is swapped.
1419 TEST_F(DisplayControllerTest
,
1420 UpdateMouseLocationAfterDisplayChange_SwapPrimary
) {
1421 if (!SupportsMultipleDisplays())
1424 UpdateDisplay("200x200,200x200*2/r");
1426 aura::Env
* env
= aura::Env::GetInstance();
1427 Shell
* shell
= Shell::GetInstance();
1428 DisplayController
* display_controller
= shell
->display_controller();
1429 test::CursorManagerTestApi
test_api(shell
->cursor_manager());
1431 display_controller
->GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(20, 50));
1433 EXPECT_EQ("20,50", env
->last_mouse_location().ToString());
1434 EXPECT_EQ(1.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1435 EXPECT_EQ(gfx::Display::ROTATE_0
, test_api
.GetCurrentCursorRotation());
1437 display_controller
->SwapPrimaryDisplay();
1439 EXPECT_EQ("20,50", env
->last_mouse_location().ToString());
1440 EXPECT_EQ(2.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1441 EXPECT_EQ(gfx::Display::ROTATE_90
, test_api
.GetCurrentCursorRotation());
1444 // Test that the cursor moves to the other display and that its scale factor
1445 // and rotation are updated when the primary display is disconnected.
1446 TEST_F(DisplayControllerTest
,
1447 UpdateMouseLocationAfterDisplayChange_PrimaryDisconnected
) {
1448 if (!SupportsMultipleDisplays())
1451 aura::Env
* env
= aura::Env::GetInstance();
1452 Shell
* shell
= Shell::GetInstance();
1453 DisplayController
* display_controller
= shell
->display_controller();
1454 test::CursorManagerTestApi
test_api(shell
->cursor_manager());
1456 UpdateDisplay("300x300*2/r,200x200");
1457 // Swap the primary display to make it possible to remove the primary display
1458 // via UpdateDisplay().
1459 display_controller
->SwapPrimaryDisplay();
1460 int primary_display_id
= display_controller
->GetPrimaryDisplayId();
1462 display_controller
->GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(20, 50));
1464 EXPECT_EQ("20,50", env
->last_mouse_location().ToString());
1465 EXPECT_EQ(1.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1466 EXPECT_EQ(gfx::Display::ROTATE_0
, test_api
.GetCurrentCursorRotation());
1468 UpdateDisplay("300x300*2/r");
1469 ASSERT_NE(primary_display_id
, display_controller
->GetPrimaryDisplayId());
1471 // Cursor should be centered on the remaining display.
1472 EXPECT_EQ("75,75", env
->last_mouse_location().ToString());
1473 EXPECT_EQ(2.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1474 EXPECT_EQ(gfx::Display::ROTATE_90
, test_api
.GetCurrentCursorRotation());
1477 // GetRootWindowForDisplayId() for removed gfx::Display during
1478 // OnDisplayRemoved() should not cause crash. See http://crbug.com/415222
1479 TEST_F(DisplayControllerTest
,
1480 GetRootWindowForDisplayIdDuringDisplayDisconnection
) {
1481 if (!SupportsMultipleDisplays())
1484 UpdateDisplay("300x300,200x200");
1485 aura::Window
* root2
=
1486 Shell::GetInstance()->display_controller()->GetRootWindowForDisplayId(
1487 ScreenUtil::GetSecondaryDisplay().id());
1488 views::Widget
* widget
= views::Widget::CreateWindowWithContextAndBounds(
1489 nullptr, root2
, gfx::Rect(350, 0, 100, 100));
1490 views::View
* view
= new views::View();
1491 widget
->GetContentsView()->AddChildView(view
);
1492 view
->SetBounds(0, 0, 100, 100);
1495 TestMouseWatcherListener listener
;
1496 views::MouseWatcher
watcher(
1497 new views::MouseWatcherViewHost(view
, gfx::Insets()), &listener
);
1500 ui::test::EventGenerator
event_generator(
1501 widget
->GetNativeWindow()->GetRootWindow());
1502 event_generator
.MoveMouseToCenterOf(widget
->GetNativeWindow());
1504 UpdateDisplay("300x300");