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"
42 const char kDesktopBackgroundView
[] = "DesktopBackgroundView";
47 explicit Resetter(T
* value
) : value_(*value
) {
51 T
value() { return value_
; }
55 DISALLOW_COPY_AND_ASSIGN(Resetter
);
58 class TestObserver
: public DisplayController::Observer
,
59 public gfx::DisplayObserver
,
60 public aura::client::FocusChangeObserver
,
61 public aura::client::ActivationChangeObserver
{
66 bounds_changed_count_(0),
67 rotation_changed_count_(0),
68 workarea_changed_count_(0),
69 primary_changed_count_(0),
70 changed_display_id_(0),
71 focus_changed_count_(0),
72 activation_changed_count_(0) {
73 Shell::GetInstance()->display_controller()->AddObserver(this);
74 Shell::GetScreen()->AddObserver(this);
75 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
77 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
81 ~TestObserver() override
{
82 Shell::GetInstance()->display_controller()->RemoveObserver(this);
83 Shell::GetScreen()->RemoveObserver(this);
84 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
86 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
90 // Overridden from DisplayController::Observer
91 void OnDisplayConfigurationChanging() override
{ ++changing_count_
; }
92 void OnDisplayConfigurationChanged() override
{ ++changed_count_
; }
94 // Overrideen from gfx::DisplayObserver
95 void OnDisplayMetricsChanged(const gfx::Display
& display
,
96 uint32_t metrics
) override
{
97 changed_display_id_
= display
.id();
98 if (metrics
& DISPLAY_METRIC_BOUNDS
)
99 ++bounds_changed_count_
;
100 if (metrics
& DISPLAY_METRIC_ROTATION
)
101 ++rotation_changed_count_
;
102 if (metrics
& DISPLAY_METRIC_WORK_AREA
)
103 ++workarea_changed_count_
;
104 if (metrics
& DISPLAY_METRIC_PRIMARY
)
105 ++primary_changed_count_
;
107 void OnDisplayAdded(const gfx::Display
& new_display
) override
{}
108 void OnDisplayRemoved(const gfx::Display
& old_display
) override
{}
110 // Overridden from aura::client::FocusChangeObserver
111 void OnWindowFocused(aura::Window
* gained_focus
,
112 aura::Window
* lost_focus
) override
{
113 focus_changed_count_
++;
116 // Overridden from aura::client::ActivationChangeObserver
117 void OnWindowActivated(
118 aura::client::ActivationChangeObserver::ActivationReason reason
,
119 aura::Window
* gained_active
,
120 aura::Window
* lost_active
) override
{
121 activation_changed_count_
++;
123 void OnAttemptToReactivateWindow(aura::Window
* request_active
,
124 aura::Window
* actual_active
) override
{}
126 int CountAndReset() {
127 EXPECT_EQ(changing_count_
, changed_count_
);
129 return Resetter
<int>(&changing_count_
).value();
132 int64
GetBoundsChangedCountAndReset() {
133 return Resetter
<int>(&bounds_changed_count_
).value();
136 int64
GetRotationChangedCountAndReset() {
137 return Resetter
<int>(&rotation_changed_count_
).value();
140 int64
GetWorkareaChangedCountAndReset() {
141 return Resetter
<int>(&workarea_changed_count_
).value();
144 int64
GetPrimaryChangedCountAndReset() {
145 return Resetter
<int>(&primary_changed_count_
).value();
148 int64
GetChangedDisplayIdAndReset() {
149 return Resetter
<int64
>(&changed_display_id_
).value();
152 int GetFocusChangedCountAndReset() {
153 return Resetter
<int>(&focus_changed_count_
).value();
156 int GetActivationChangedCountAndReset() {
157 return Resetter
<int>(&activation_changed_count_
).value();
164 int bounds_changed_count_
;
165 int rotation_changed_count_
;
166 int workarea_changed_count_
;
167 int primary_changed_count_
;
168 int64 changed_display_id_
;
170 int focus_changed_count_
;
171 int activation_changed_count_
;
173 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
176 gfx::Display
GetPrimaryDisplay() {
177 return Shell::GetScreen()->GetDisplayNearestWindow(
178 Shell::GetAllRootWindows()[0]);
181 gfx::Display
GetSecondaryDisplay() {
182 return Shell::GetScreen()->GetDisplayNearestWindow(
183 Shell::GetAllRootWindows()[1]);
186 void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position
,
188 DisplayLayout
layout(position
, offset
);
189 ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1);
190 Shell::GetInstance()->display_manager()->
191 SetLayoutForCurrentDisplays(layout
);
194 void SetSecondaryDisplayLayout(DisplayLayout::Position position
) {
195 SetSecondaryDisplayLayoutAndOffset(position
, 0);
198 void SetDefaultDisplayLayout(DisplayLayout::Position position
) {
199 Shell::GetInstance()->display_manager()->layout_store()->
200 SetDefaultDisplayLayout(DisplayLayout(position
, 0));
203 class DisplayControllerShutdownTest
: public test::AshTestBase
{
205 DisplayControllerShutdownTest() {}
206 ~DisplayControllerShutdownTest() override
{}
208 void TearDown() override
{
209 test::AshTestBase::TearDown();
210 if (!SupportsMultipleDisplays())
213 // Make sure that primary display is accessible after shutdown.
214 gfx::Display primary
= Shell::GetScreen()->GetPrimaryDisplay();
215 EXPECT_EQ("0,0 444x333", primary
.bounds().ToString());
216 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
220 DISALLOW_COPY_AND_ASSIGN(DisplayControllerShutdownTest
);
223 class StartupHelper
: public test::TestShellDelegate
,
224 public DisplayController::Observer
{
226 StartupHelper() : displays_initialized_(false) {}
227 ~StartupHelper() override
{}
229 // ash::ShellSelegate:
230 void PreInit() override
{
231 Shell::GetInstance()->display_controller()->AddObserver(this);
234 // ash::DisplayController::Observer:
235 void OnDisplaysInitialized() override
{
236 DCHECK(!displays_initialized_
);
237 displays_initialized_
= true;
240 bool displays_initialized() const {
241 return displays_initialized_
;
245 bool displays_initialized_
;
247 DISALLOW_COPY_AND_ASSIGN(StartupHelper
);
250 class DisplayControllerStartupTest
: public test::AshTestBase
{
252 DisplayControllerStartupTest() : startup_helper_(new StartupHelper
) {}
253 ~DisplayControllerStartupTest() override
{}
255 // ash::test::AshTestBase:
256 void SetUp() override
{
257 ash_test_helper()->set_test_shell_delegate(startup_helper_
);
258 test::AshTestBase::SetUp();
260 void TearDown() override
{
261 Shell::GetInstance()->display_controller()->RemoveObserver(startup_helper_
);
262 test::AshTestBase::TearDown();
265 const StartupHelper
* startup_helper() const { return startup_helper_
; }
268 StartupHelper
* startup_helper_
; // Owned by ash::Shell.
270 DISALLOW_COPY_AND_ASSIGN(DisplayControllerStartupTest
);
273 class TestEventHandler
: public ui::EventHandler
{
275 TestEventHandler() : target_root_(NULL
),
276 touch_radius_x_(0.0),
277 touch_radius_y_(0.0),
278 scroll_x_offset_(0.0),
279 scroll_y_offset_(0.0),
280 scroll_x_offset_ordinal_(0.0),
281 scroll_y_offset_ordinal_(0.0) {}
282 ~TestEventHandler() override
{}
284 void OnMouseEvent(ui::MouseEvent
* event
) override
{
285 if (event
->flags() & ui::EF_IS_SYNTHESIZED
&&
286 event
->type() != ui::ET_MOUSE_EXITED
&&
287 event
->type() != ui::ET_MOUSE_ENTERED
) {
290 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
291 mouse_location_
= event
->root_location();
292 target_root_
= target
->GetRootWindow();
293 event
->StopPropagation();
296 void OnTouchEvent(ui::TouchEvent
* event
) override
{
297 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
298 // Only record when the target is the background which covers
299 // entire root window.
300 if (target
->name() != kDesktopBackgroundView
)
302 touch_radius_x_
= event
->radius_x();
303 touch_radius_y_
= event
->radius_y();
304 event
->StopPropagation();
307 void OnScrollEvent(ui::ScrollEvent
* event
) override
{
308 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
309 // Only record when the target is the background which covers
310 // entire root window.
311 if (target
->name() != kDesktopBackgroundView
)
314 if (event
->type() == ui::ET_SCROLL
) {
315 scroll_x_offset_
= event
->x_offset();
316 scroll_y_offset_
= event
->y_offset();
317 scroll_x_offset_ordinal_
= event
->x_offset_ordinal();
318 scroll_y_offset_ordinal_
= event
->y_offset_ordinal();
320 event
->StopPropagation();
323 std::string
GetLocationAndReset() {
324 std::string result
= mouse_location_
.ToString();
325 mouse_location_
.SetPoint(0, 0);
330 float touch_radius_x() { return touch_radius_x_
; }
331 float touch_radius_y() { return touch_radius_y_
; }
332 float scroll_x_offset() { return scroll_x_offset_
; }
333 float scroll_y_offset() { return scroll_y_offset_
; }
334 float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_
; }
335 float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_
; }
338 gfx::Point mouse_location_
;
339 aura::Window
* target_root_
;
341 float touch_radius_x_
;
342 float touch_radius_y_
;
343 float scroll_x_offset_
;
344 float scroll_y_offset_
;
345 float scroll_x_offset_ordinal_
;
346 float scroll_y_offset_ordinal_
;
348 DISALLOW_COPY_AND_ASSIGN(TestEventHandler
);
351 float GetStoredUIScale(int64 id
) {
352 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id
).
353 GetEffectiveUIScale();
356 class TestMouseWatcherListener
: public views::MouseWatcherListener
{
358 TestMouseWatcherListener() {}
361 // views::MouseWatcherListener:
362 void MouseMovedOutOfHost() override
{}
364 DISALLOW_COPY_AND_ASSIGN(TestMouseWatcherListener
);
369 typedef test::AshTestBase DisplayControllerTest
;
371 TEST_F(DisplayControllerShutdownTest
, Shutdown
) {
372 if (!SupportsMultipleDisplays())
375 UpdateDisplay("444x333, 200x200");
378 TEST_F(DisplayControllerStartupTest
, Startup
) {
379 if (!SupportsMultipleDisplays())
382 EXPECT_TRUE(startup_helper()->displays_initialized());
385 TEST_F(DisplayControllerTest
, SecondaryDisplayLayout
) {
386 if (!SupportsMultipleDisplays())
389 // Creates windows to catch activation change event.
390 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
393 TestObserver observer
;
394 UpdateDisplay("500x500,400x400");
395 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
396 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
397 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
398 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
399 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
400 gfx::Insets
insets(5, 5, 5, 5);
401 int64 secondary_display_id
= ScreenUtil::GetSecondaryDisplay().id();
402 Shell::GetInstance()->display_manager()->UpdateWorkAreaOfDisplay(
403 secondary_display_id
, insets
);
405 // Default layout is RIGHT.
406 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
407 EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
408 EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());
409 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
410 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
412 // Layout the secondary display to the bottom of the primary.
413 SetSecondaryDisplayLayout(DisplayLayout::BOTTOM
);
414 EXPECT_EQ(1, observer
.CountAndReset());
415 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
416 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
417 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
418 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
419 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
420 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
421 EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
422 EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());
424 // Layout the secondary display to the left of the primary.
425 SetSecondaryDisplayLayout(DisplayLayout::LEFT
);
426 EXPECT_EQ(1, observer
.CountAndReset());
427 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
428 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
429 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
430 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
431 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
432 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
433 EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
434 EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());
436 // Layout the secondary display to the top of the primary.
437 SetSecondaryDisplayLayout(DisplayLayout::TOP
);
438 EXPECT_EQ(1, observer
.CountAndReset());
439 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
440 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
441 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
442 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
443 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
444 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
445 EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
446 EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
448 // Layout to the right with an offset.
449 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, 300);
450 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
451 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
452 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
453 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
454 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
455 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
456 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
457 EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString());
459 // Keep the minimum 100.
460 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, 490);
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,400 400x400", GetSecondaryDisplay().bounds().ToString());
470 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT
, -400);
471 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
472 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
473 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
474 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
475 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
476 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
477 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
478 EXPECT_EQ("500,-300 400x400", GetSecondaryDisplay().bounds().ToString());
480 // Layout to the bottom with an offset.
481 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -200);
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("-200,500 400x400", GetSecondaryDisplay().bounds().ToString());
491 // Keep the minimum 100.
492 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, 490);
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("400,500 400x400", GetSecondaryDisplay().bounds().ToString());
502 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -400);
503 EXPECT_EQ(secondary_display_id
, observer
.GetChangedDisplayIdAndReset());
504 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
505 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
506 EXPECT_EQ(1, observer
.CountAndReset()); // resize and add
507 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
508 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
509 EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
510 EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
512 // Setting the same layout shouldn't invoke observers.
513 SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM
, -400);
514 EXPECT_EQ(0, observer
.GetChangedDisplayIdAndReset());
515 EXPECT_EQ(0, observer
.GetBoundsChangedCountAndReset());
516 EXPECT_EQ(0, observer
.GetWorkareaChangedCountAndReset());
517 EXPECT_EQ(0, 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 UpdateDisplay("500x500");
524 EXPECT_LE(1, observer
.GetFocusChangedCountAndReset());
525 EXPECT_LE(1, observer
.GetActivationChangedCountAndReset());
530 DisplayInfo
CreateDisplayInfo(int64 id
,
532 gfx::Display::Rotation rotation
) {
533 DisplayInfo
info(id
, "", false);
534 info
.SetBounds(gfx::Rect(0, y
, 500, 500));
535 info
.SetRotation(rotation
, gfx::Display::ROTATION_SOURCE_ACTIVE
);
539 DisplayInfo
CreateMirroredDisplayInfo(int64 id
,
540 float device_scale_factor
) {
541 DisplayInfo info
= CreateDisplayInfo(id
, 0, gfx::Display::ROTATE_0
);
542 info
.set_device_scale_factor(device_scale_factor
);
548 TEST_F(DisplayControllerTest
, MirrorToDockedWithFullscreen
) {
549 if (!SupportsMultipleDisplays())
552 // Creates windows to catch activation change event.
553 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
557 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
559 const DisplayInfo internal_display_info
=
560 CreateMirroredDisplayInfo(1, 2.0f
);
561 const DisplayInfo external_display_info
=
562 CreateMirroredDisplayInfo(2, 1.0f
);
564 std::vector
<DisplayInfo
> display_info_list
;
566 display_info_list
.push_back(internal_display_info
);
567 display_info_list
.push_back(external_display_info
);
568 display_manager
->OnNativeDisplaysChanged(display_info_list
);
569 const int64 internal_display_id
=
570 test::DisplayManagerTestApi(display_manager
).
571 SetFirstDisplayAsInternalDisplay();
572 EXPECT_EQ(1, internal_display_id
);
573 EXPECT_EQ(2U, display_manager
->num_connected_displays());
574 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
576 wm::WindowState
* window_state
= wm::GetWindowState(w1
.get());
577 const wm::WMEvent
toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN
);
578 window_state
->OnWMEvent(&toggle_fullscreen_event
);
579 EXPECT_TRUE(window_state
->IsFullscreen());
580 EXPECT_EQ("0,0 250x250", w1
->bounds().ToString());
582 TestObserver observer
;
583 display_info_list
.clear();
584 display_info_list
.push_back(external_display_info
);
585 display_manager
->OnNativeDisplaysChanged(display_info_list
);
586 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
587 EXPECT_EQ(1U, display_manager
->num_connected_displays());
588 // Observers are called due to primary change.
589 EXPECT_EQ(2, observer
.GetChangedDisplayIdAndReset());
590 EXPECT_EQ(1, observer
.GetBoundsChangedCountAndReset());
591 EXPECT_EQ(1, observer
.GetWorkareaChangedCountAndReset());
592 EXPECT_EQ(1, observer
.GetPrimaryChangedCountAndReset());
593 EXPECT_EQ(1, observer
.CountAndReset());
594 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
595 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
597 EXPECT_TRUE(window_state
->IsFullscreen());
598 EXPECT_EQ("0,0 500x500", w1
->bounds().ToString());
601 TEST_F(DisplayControllerTest
, BoundsUpdated
) {
602 if (!SupportsMultipleDisplays())
605 // Creates windows to catch activation change event.
606 scoped_ptr
<aura::Window
> w1(CreateTestWindowInShellWithId(1));
609 TestObserver observer
;
610 SetDefaultDisplayLayout(DisplayLayout::BOTTOM
);
611 UpdateDisplay("200x200,300x300"); // layout, resize and add.
612 EXPECT_EQ(1, observer
.CountAndReset());
613 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
614 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
616 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
617 gfx::Insets
insets(5, 5, 5, 5);
618 display_manager
->UpdateWorkAreaOfDisplay(
619 ScreenUtil::GetSecondaryDisplay().id(), insets
);
621 EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
622 EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
623 EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
625 UpdateDisplay("400x400,200x200");
626 EXPECT_EQ(1, observer
.CountAndReset()); // two resizes
627 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
628 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
629 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
630 EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
632 UpdateDisplay("400x400,300x300");
633 EXPECT_EQ(1, observer
.CountAndReset());
634 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
635 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
636 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
637 EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
639 UpdateDisplay("400x400");
640 EXPECT_EQ(1, observer
.CountAndReset());
641 EXPECT_LE(1, observer
.GetFocusChangedCountAndReset());
642 EXPECT_LE(1, observer
.GetActivationChangedCountAndReset());
643 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
644 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
646 UpdateDisplay("400x500*2,300x300");
647 EXPECT_EQ(1, observer
.CountAndReset());
648 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
649 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
650 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
651 EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
652 EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
655 UpdateDisplay("400x500*2,300x300");
656 // We still call into Pre/PostDisplayConfigurationChange().
657 EXPECT_EQ(1, observer
.CountAndReset());
658 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
659 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
662 observer
.GetRotationChangedCountAndReset(); // we only want to reset.
663 int64 primary_id
= GetPrimaryDisplay().id();
664 display_manager
->SetDisplayRotation(primary_id
, gfx::Display::ROTATE_90
,
665 gfx::Display::ROTATION_SOURCE_ACTIVE
);
666 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
667 EXPECT_EQ(1, observer
.CountAndReset());
668 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
669 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
670 display_manager
->SetDisplayRotation(primary_id
, gfx::Display::ROTATE_90
,
671 gfx::Display::ROTATION_SOURCE_ACTIVE
);
672 EXPECT_EQ(0, observer
.GetRotationChangedCountAndReset());
673 EXPECT_EQ(0, observer
.CountAndReset());
674 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
675 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
677 // UI scale is eanbled only on internal display.
678 int64 secondary_id
= GetSecondaryDisplay().id();
679 test::DisplayManagerTestApi(display_manager
)
680 .SetInternalDisplayId(secondary_id
);
682 display_manager
->SetDisplayUIScale(secondary_id
, 1.125f
);
683 EXPECT_EQ(1, observer
.CountAndReset());
684 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
685 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
686 display_manager
->SetDisplayUIScale(secondary_id
, 1.125f
);
687 EXPECT_EQ(0, observer
.CountAndReset());
688 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
689 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
690 display_manager
->SetDisplayUIScale(primary_id
, 1.125f
);
691 EXPECT_EQ(0, observer
.CountAndReset());
692 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
693 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
694 display_manager
->SetDisplayUIScale(primary_id
, 1.125f
);
695 EXPECT_EQ(0, observer
.CountAndReset());
696 EXPECT_EQ(0, observer
.GetFocusChangedCountAndReset());
697 EXPECT_EQ(0, observer
.GetActivationChangedCountAndReset());
700 TEST_F(DisplayControllerTest
, SwapPrimary
) {
701 if (!SupportsMultipleDisplays())
704 DisplayController
* display_controller
=
705 Shell::GetInstance()->display_controller();
706 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
708 UpdateDisplay("200x200,300x300");
709 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
710 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
712 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
713 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
715 EXPECT_NE(primary_display
.id(), secondary_display
.id());
716 aura::Window
* primary_root
=
717 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
718 aura::Window
* secondary_root
=
719 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
720 EXPECT_NE(primary_root
, secondary_root
);
721 aura::Window
* shelf_window
=
722 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
723 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
724 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
725 EXPECT_EQ(primary_display
.id(),
726 Shell::GetScreen()->GetDisplayNearestPoint(
727 gfx::Point(-100, -100)).id());
728 EXPECT_EQ(primary_display
.id(),
729 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
731 EXPECT_EQ("0,0 200x200", primary_display
.bounds().ToString());
732 EXPECT_EQ("0,0 200x153", primary_display
.work_area().ToString());
733 EXPECT_EQ("200,0 300x300", secondary_display
.bounds().ToString());
734 EXPECT_EQ("200,0 300x253", secondary_display
.work_area().ToString());
735 EXPECT_EQ("right, 50",
736 display_manager
->GetCurrentDisplayLayout().ToString());
738 // Switch primary and secondary
739 display_controller
->SetPrimaryDisplay(secondary_display
);
740 const DisplayLayout
& inverted_layout
=
741 display_manager
->GetCurrentDisplayLayout();
742 EXPECT_EQ("left, -50", inverted_layout
.ToString());
744 EXPECT_EQ(secondary_display
.id(),
745 Shell::GetScreen()->GetPrimaryDisplay().id());
746 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
747 EXPECT_EQ(primary_display
.id(),
748 Shell::GetScreen()->GetDisplayNearestPoint(
749 gfx::Point(-100, -100)).id());
750 EXPECT_EQ(secondary_display
.id(),
751 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
755 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
758 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
759 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
760 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
762 // Test if the bounds are correctly swapped.
763 gfx::Display swapped_primary
= Shell::GetScreen()->GetPrimaryDisplay();
764 gfx::Display swapped_secondary
= ScreenUtil::GetSecondaryDisplay();
765 EXPECT_EQ("0,0 300x300", swapped_primary
.bounds().ToString());
766 EXPECT_EQ("0,0 300x253", swapped_primary
.work_area().ToString());
767 EXPECT_EQ("-200,-50 200x200", swapped_secondary
.bounds().ToString());
769 EXPECT_EQ("-200,-50 200x153", swapped_secondary
.work_area().ToString());
771 aura::WindowTracker tracker
;
772 tracker
.Add(primary_root
);
773 tracker
.Add(secondary_root
);
775 // Deleting 2nd display should move the primary to original primary display.
776 UpdateDisplay("200x200");
777 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
778 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
779 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
780 EXPECT_EQ(primary_display
.id(),
781 Shell::GetScreen()->GetDisplayNearestPoint(
782 gfx::Point(-100, -100)).id());
783 EXPECT_EQ(primary_display
.id(),
784 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
785 EXPECT_TRUE(tracker
.Contains(primary_root
));
786 EXPECT_FALSE(tracker
.Contains(secondary_root
));
787 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
790 TEST_F(DisplayControllerTest
, FindNearestDisplay
) {
791 if (!SupportsMultipleDisplays())
794 DisplayController
* display_controller
=
795 Shell::GetInstance()->display_controller();
796 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
798 UpdateDisplay("200x200,300x300");
799 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
800 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
802 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
803 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
804 EXPECT_NE(primary_display
.id(), secondary_display
.id());
805 aura::Window
* primary_root
=
806 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
807 aura::Window
* secondary_root
=
808 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
809 EXPECT_NE(primary_root
, secondary_root
);
811 // Test that points outside of any display return the nearest display.
812 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
813 gfx::Point(-100, 0)).id());
814 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
815 gfx::Point(0, -100)).id());
816 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
817 gfx::Point(100, 100)).id());
818 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
819 gfx::Point(224, 25)).id());
820 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
821 gfx::Point(226, 25)).id());
822 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
823 gfx::Point(600, 100)).id());
824 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
825 gfx::Point(174, 225)).id());
826 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
827 gfx::Point(176, 225)).id());
828 EXPECT_EQ(secondary_display
.id(), Shell::GetScreen()->GetDisplayNearestPoint(
829 gfx::Point(300, 400)).id());
832 TEST_F(DisplayControllerTest
, SwapPrimaryById
) {
833 if (!SupportsMultipleDisplays())
836 DisplayController
* display_controller
=
837 Shell::GetInstance()->display_controller();
838 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
840 UpdateDisplay("200x200,300x300");
841 gfx::Display primary_display
= Shell::GetScreen()->GetPrimaryDisplay();
842 gfx::Display secondary_display
= ScreenUtil::GetSecondaryDisplay();
844 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 50);
845 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
847 EXPECT_NE(primary_display
.id(), secondary_display
.id());
848 aura::Window
* primary_root
=
849 display_controller
->GetRootWindowForDisplayId(primary_display
.id());
850 aura::Window
* secondary_root
=
851 display_controller
->GetRootWindowForDisplayId(secondary_display
.id());
852 aura::Window
* shelf_window
=
853 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
854 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
855 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
856 EXPECT_NE(primary_root
, secondary_root
);
857 EXPECT_EQ(primary_display
.id(),
858 Shell::GetScreen()->GetDisplayNearestPoint(
859 gfx::Point(-100, -100)).id());
860 EXPECT_EQ(primary_display
.id(),
861 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
863 // Switch primary and secondary by display ID.
864 TestObserver observer
;
865 display_controller
->SetPrimaryDisplayId(secondary_display
.id());
866 EXPECT_EQ(secondary_display
.id(),
867 Shell::GetScreen()->GetPrimaryDisplay().id());
868 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
869 EXPECT_LT(0, observer
.CountAndReset());
873 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
876 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
877 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
878 EXPECT_FALSE(secondary_root
->Contains(shelf_window
));
880 const DisplayLayout
& inverted_layout
=
881 display_manager
->GetCurrentDisplayLayout();
883 EXPECT_EQ("left, -50", inverted_layout
.ToString());
885 // Calling the same ID don't do anything.
886 display_controller
->SetPrimaryDisplayId(secondary_display
.id());
887 EXPECT_EQ(0, observer
.CountAndReset());
889 aura::WindowTracker tracker
;
890 tracker
.Add(primary_root
);
891 tracker
.Add(secondary_root
);
893 // Deleting 2nd display should move the primary to original primary display.
894 UpdateDisplay("200x200");
895 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
896 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
897 EXPECT_EQ(primary_display
.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
898 EXPECT_EQ(primary_display
.id(),
899 Shell::GetScreen()->GetDisplayNearestPoint(
900 gfx::Point(-100, -100)).id());
901 EXPECT_EQ(primary_display
.id(),
902 Shell::GetScreen()->GetDisplayNearestWindow(NULL
).id());
903 EXPECT_TRUE(tracker
.Contains(primary_root
));
904 EXPECT_FALSE(tracker
.Contains(secondary_root
));
905 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
907 // Adding 2nd display with the same ID. The 2nd display should become primary
908 // since secondary id is still stored as desirable_primary_id.
909 std::vector
<DisplayInfo
> display_info_list
;
910 display_info_list
.push_back(
911 display_manager
->GetDisplayInfo(primary_display
.id()));
912 display_info_list
.push_back(
913 display_manager
->GetDisplayInfo(secondary_display
.id()));
914 display_manager
->OnNativeDisplaysChanged(display_info_list
);
916 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
917 EXPECT_EQ(secondary_display
.id(),
918 Shell::GetScreen()->GetPrimaryDisplay().id());
919 EXPECT_EQ(primary_display
.id(), ScreenUtil::GetSecondaryDisplay().id());
922 display_controller
->GetRootWindowForDisplayId(secondary_display
.id()));
925 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
926 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
928 // Deleting 2nd display and adding 2nd display with a different ID. The 2nd
929 // display shouldn't become primary.
930 UpdateDisplay("200x200");
931 DisplayInfo
third_display_info(
932 secondary_display
.id() + 1, std::string(), false);
933 third_display_info
.SetBounds(secondary_display
.bounds());
934 ASSERT_NE(primary_display
.id(), third_display_info
.id());
936 const DisplayInfo
& primary_display_info
=
937 display_manager
->GetDisplayInfo(primary_display
.id());
938 std::vector
<DisplayInfo
> display_info_list2
;
939 display_info_list2
.push_back(primary_display_info
);
940 display_info_list2
.push_back(third_display_info
);
941 display_manager
->OnNativeDisplaysChanged(display_info_list2
);
942 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
943 EXPECT_EQ(primary_display
.id(),
944 Shell::GetScreen()->GetPrimaryDisplay().id());
945 EXPECT_EQ(third_display_info
.id(), ScreenUtil::GetSecondaryDisplay().id());
948 display_controller
->GetRootWindowForDisplayId(primary_display
.id()));
951 display_controller
->GetRootWindowForDisplayId(third_display_info
.id()));
952 EXPECT_TRUE(primary_root
->Contains(shelf_window
));
955 TEST_F(DisplayControllerTest
, OverscanInsets
) {
956 if (!SupportsMultipleDisplays())
959 DisplayController
* display_controller
=
960 Shell::GetInstance()->display_controller();
961 TestEventHandler event_handler
;
962 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
964 UpdateDisplay("120x200,300x400*2");
965 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
966 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
968 display_controller
->SetOverscanInsets(display1
.id(),
969 gfx::Insets(10, 15, 20, 25));
970 EXPECT_EQ("0,0 80x170", root_windows
[0]->bounds().ToString());
971 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
972 EXPECT_EQ("80,0 150x200",
973 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
975 ui::test::EventGenerator
generator(root_windows
[0]);
976 generator
.MoveMouseToInHost(20, 25);
977 EXPECT_EQ("5,15", event_handler
.GetLocationAndReset());
979 display_controller
->SetOverscanInsets(display1
.id(), gfx::Insets());
980 EXPECT_EQ("0,0 120x200", root_windows
[0]->bounds().ToString());
981 EXPECT_EQ("120,0 150x200",
982 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
984 generator
.MoveMouseToInHost(30, 20);
985 EXPECT_EQ("30,20", event_handler
.GetLocationAndReset());
987 // Make sure the root window transformer uses correct scale
988 // factor when swapping display. Test crbug.com/253690.
989 UpdateDisplay("400x300*2,600x400/o");
990 root_windows
= Shell::GetAllRootWindows();
992 Shell::GetAllRootWindows()[1]->GetHost()->
993 GetRootTransform().TransformPoint(&point
);
994 EXPECT_EQ("15,10", point
.ToString());
996 display_controller
->SwapPrimaryDisplay();
997 point
.SetPoint(0, 0);
998 Shell::GetAllRootWindows()[1]->GetHost()->
999 GetRootTransform().TransformPoint(&point
);
1000 EXPECT_EQ("15,10", point
.ToString());
1002 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1005 TEST_F(DisplayControllerTest
, Rotate
) {
1006 if (!SupportsMultipleDisplays())
1009 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1010 TestEventHandler event_handler
;
1011 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1013 UpdateDisplay("120x200,300x400*2");
1014 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1015 int64 display2_id
= ScreenUtil::GetSecondaryDisplay().id();
1016 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1017 ui::test::EventGenerator
generator1(root_windows
[0]);
1019 TestObserver observer
;
1020 EXPECT_EQ("120x200", root_windows
[0]->bounds().size().ToString());
1021 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
1022 EXPECT_EQ("120,0 150x200",
1023 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1024 generator1
.MoveMouseToInHost(50, 40);
1025 EXPECT_EQ("50,40", event_handler
.GetLocationAndReset());
1026 EXPECT_EQ(gfx::Display::ROTATE_0
, GetActiveDisplayRotation(display1
.id()));
1027 EXPECT_EQ(gfx::Display::ROTATE_0
, GetActiveDisplayRotation(display2_id
));
1028 EXPECT_EQ(0, observer
.GetRotationChangedCountAndReset());
1030 display_manager
->SetDisplayRotation(display1
.id(), gfx::Display::ROTATE_90
,
1031 gfx::Display::ROTATION_SOURCE_ACTIVE
);
1032 EXPECT_EQ("200x120", root_windows
[0]->bounds().size().ToString());
1033 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
1034 EXPECT_EQ("200,0 150x200",
1035 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1036 generator1
.MoveMouseToInHost(50, 40);
1037 EXPECT_EQ("40,69", event_handler
.GetLocationAndReset());
1038 EXPECT_EQ(gfx::Display::ROTATE_90
, GetActiveDisplayRotation(display1
.id()));
1039 EXPECT_EQ(gfx::Display::ROTATE_0
, GetActiveDisplayRotation(display2_id
));
1040 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1042 DisplayLayout
display_layout(DisplayLayout::BOTTOM
, 50);
1043 display_manager
->SetLayoutForCurrentDisplays(display_layout
);
1044 EXPECT_EQ("50,120 150x200",
1045 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1047 display_manager
->SetDisplayRotation(display2_id
, gfx::Display::ROTATE_270
,
1048 gfx::Display::ROTATION_SOURCE_ACTIVE
);
1049 EXPECT_EQ("200x120", root_windows
[0]->bounds().size().ToString());
1050 EXPECT_EQ("200x150", root_windows
[1]->bounds().size().ToString());
1051 EXPECT_EQ("50,120 200x150",
1052 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1053 EXPECT_EQ(gfx::Display::ROTATE_90
, GetActiveDisplayRotation(display1
.id()));
1054 EXPECT_EQ(gfx::Display::ROTATE_270
, GetActiveDisplayRotation(display2_id
));
1055 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1057 #if !defined(OS_WIN)
1058 ui::test::EventGenerator
generator2(root_windows
[1]);
1059 generator2
.MoveMouseToInHost(50, 40);
1060 EXPECT_EQ("179,25", event_handler
.GetLocationAndReset());
1061 display_manager
->SetDisplayRotation(display1
.id(), gfx::Display::ROTATE_180
,
1062 gfx::Display::ROTATION_SOURCE_ACTIVE
);
1064 EXPECT_EQ("120x200", root_windows
[0]->bounds().size().ToString());
1065 EXPECT_EQ("200x150", root_windows
[1]->bounds().size().ToString());
1066 // Dislay must share at least 100, so the x's offset becomes 20.
1067 EXPECT_EQ("20,200 200x150",
1068 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1069 EXPECT_EQ(gfx::Display::ROTATE_180
, GetActiveDisplayRotation(display1
.id()));
1070 EXPECT_EQ(gfx::Display::ROTATE_270
, GetActiveDisplayRotation(display2_id
));
1071 EXPECT_EQ(1, observer
.GetRotationChangedCountAndReset());
1073 generator1
.MoveMouseToInHost(50, 40);
1074 EXPECT_EQ("69,159", event_handler
.GetLocationAndReset());
1077 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1080 TEST_F(DisplayControllerTest
, ScaleRootWindow
) {
1081 if (!SupportsMultipleDisplays())
1084 TestEventHandler event_handler
;
1085 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1087 UpdateDisplay("600x400*2@1.5,500x300");
1089 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1090 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1091 test::DisplayManagerTestApi(display_manager
)
1092 .SetInternalDisplayId(display1
.id());
1094 gfx::Display display2
= ScreenUtil::GetSecondaryDisplay();
1095 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1096 EXPECT_EQ("0,0 450x300", display1
.bounds().ToString());
1097 EXPECT_EQ("0,0 450x300", root_windows
[0]->bounds().ToString());
1098 EXPECT_EQ("450,0 500x300", display2
.bounds().ToString());
1099 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1100 EXPECT_EQ(1.0f
, GetStoredUIScale(display2
.id()));
1102 ui::test::EventGenerator
generator(root_windows
[0]);
1103 generator
.MoveMouseToInHost(599, 200);
1104 EXPECT_EQ("449,150", event_handler
.GetLocationAndReset());
1106 display_manager
->SetDisplayUIScale(display1
.id(), 1.25f
);
1107 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1108 display2
= ScreenUtil::GetSecondaryDisplay();
1109 EXPECT_EQ("0,0 375x250", display1
.bounds().ToString());
1110 EXPECT_EQ("0,0 375x250", root_windows
[0]->bounds().ToString());
1111 EXPECT_EQ("375,0 500x300", display2
.bounds().ToString());
1112 EXPECT_EQ(1.25f
, GetStoredUIScale(display1
.id()));
1113 EXPECT_EQ(1.0f
, GetStoredUIScale(display2
.id()));
1115 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1118 TEST_F(DisplayControllerTest
, TouchScale
) {
1119 if (!SupportsMultipleDisplays())
1122 TestEventHandler event_handler
;
1123 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1125 UpdateDisplay("200x200*2");
1126 gfx::Display display
= Shell::GetScreen()->GetPrimaryDisplay();
1127 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1128 aura::Window
* root_window
= root_windows
[0];
1129 ui::test::EventGenerator
generator(root_window
);
1131 generator
.PressMoveAndReleaseTouchTo(50, 50);
1132 // Default test touches have radius_x/y = 1.0, with device scale
1133 // factor = 2, the scaled radius_x/y should be 0.5.
1134 EXPECT_EQ(0.5, event_handler
.touch_radius_x());
1135 EXPECT_EQ(0.5, event_handler
.touch_radius_y());
1137 generator
.ScrollSequence(gfx::Point(0,0),
1138 base::TimeDelta::FromMilliseconds(100),
1141 // ordinal_offset is invariant to the device scale factor.
1142 EXPECT_EQ(event_handler
.scroll_x_offset(),
1143 event_handler
.scroll_x_offset_ordinal());
1144 EXPECT_EQ(event_handler
.scroll_y_offset(),
1145 event_handler
.scroll_y_offset_ordinal());
1147 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1150 TEST_F(DisplayControllerTest
, ConvertHostToRootCoords
) {
1151 if (!SupportsMultipleDisplays())
1154 TestEventHandler event_handler
;
1155 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
1157 UpdateDisplay("600x400*2/r@1.5");
1159 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
1160 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1161 EXPECT_EQ("0,0 300x450", display1
.bounds().ToString());
1162 EXPECT_EQ("0,0 300x450", root_windows
[0]->bounds().ToString());
1163 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1165 ui::test::EventGenerator
generator(root_windows
[0]);
1166 generator
.MoveMouseToInHost(0, 0);
1167 EXPECT_EQ("0,449", event_handler
.GetLocationAndReset());
1168 generator
.MoveMouseToInHost(599, 0);
1169 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1170 generator
.MoveMouseToInHost(599, 399);
1171 EXPECT_EQ("299,0", event_handler
.GetLocationAndReset());
1172 generator
.MoveMouseToInHost(0, 399);
1173 EXPECT_EQ("299,449", event_handler
.GetLocationAndReset());
1175 UpdateDisplay("600x400*2/u@1.5");
1176 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1177 root_windows
= Shell::GetAllRootWindows();
1178 EXPECT_EQ("0,0 450x300", display1
.bounds().ToString());
1179 EXPECT_EQ("0,0 450x300", root_windows
[0]->bounds().ToString());
1180 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1182 generator
.MoveMouseToInHost(0, 0);
1183 EXPECT_EQ("449,299", event_handler
.GetLocationAndReset());
1184 generator
.MoveMouseToInHost(599, 0);
1185 EXPECT_EQ("0,299", event_handler
.GetLocationAndReset());
1186 generator
.MoveMouseToInHost(599, 399);
1187 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1188 generator
.MoveMouseToInHost(0, 399);
1189 EXPECT_EQ("449,0", event_handler
.GetLocationAndReset());
1191 UpdateDisplay("600x400*2/l@1.5");
1192 display1
= Shell::GetScreen()->GetPrimaryDisplay();
1193 root_windows
= Shell::GetAllRootWindows();
1194 EXPECT_EQ("0,0 300x450", display1
.bounds().ToString());
1195 EXPECT_EQ("0,0 300x450", root_windows
[0]->bounds().ToString());
1196 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
1198 generator
.MoveMouseToInHost(0, 0);
1199 EXPECT_EQ("299,0", event_handler
.GetLocationAndReset());
1200 generator
.MoveMouseToInHost(599, 0);
1201 EXPECT_EQ("299,449", event_handler
.GetLocationAndReset());
1202 generator
.MoveMouseToInHost(599, 399);
1203 EXPECT_EQ("0,449", event_handler
.GetLocationAndReset());
1204 generator
.MoveMouseToInHost(0, 399);
1205 EXPECT_EQ("0,0", event_handler
.GetLocationAndReset());
1207 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
1210 // Make sure that the compositor based mirroring can switch
1211 // from/to dock mode.
1212 TEST_F(DisplayControllerTest
, DockToSingle
) {
1213 if (!SupportsMultipleDisplays())
1216 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1218 const int64 internal_id
= 1;
1220 const DisplayInfo internal_display_info
=
1221 CreateDisplayInfo(internal_id
, 0, gfx::Display::ROTATE_0
);
1222 const DisplayInfo external_display_info
=
1223 CreateDisplayInfo(2, 1, gfx::Display::ROTATE_90
);
1225 std::vector
<DisplayInfo
> display_info_list
;
1227 display_info_list
.push_back(internal_display_info
);
1228 display_info_list
.push_back(external_display_info
);
1229 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1230 const int64 internal_display_id
=
1231 test::DisplayManagerTestApi(display_manager
).
1232 SetFirstDisplayAsInternalDisplay();
1233 EXPECT_EQ(internal_id
, internal_display_id
);
1234 EXPECT_EQ(2U, display_manager
->GetNumDisplays());
1237 display_info_list
.clear();
1238 display_info_list
.push_back(external_display_info
);
1239 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1240 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
1241 EXPECT_FALSE(Shell::GetPrimaryRootWindow()->GetHost()->
1242 GetRootTransform().IsIdentityOrIntegerTranslation());
1244 // Switch to single mode and make sure the transform is the one
1245 // for the internal display.
1246 display_info_list
.clear();
1247 display_info_list
.push_back(internal_display_info
);
1248 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1249 EXPECT_TRUE(Shell::GetPrimaryRootWindow()->GetHost()->
1250 GetRootTransform().IsIdentityOrIntegerTranslation());
1253 // Tests if switching two displays at the same time while the primary display
1254 // is swapped should not cause a crash. (crbug.com/426292)
1255 TEST_F(DisplayControllerTest
, ReplaceSwappedPrimary
) {
1256 if (!SupportsMultipleDisplays())
1258 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1260 const DisplayInfo first_display_info
=
1261 CreateDisplayInfo(10, 0, gfx::Display::ROTATE_0
);
1262 const DisplayInfo second_display_info
=
1263 CreateDisplayInfo(11, 1, gfx::Display::ROTATE_0
);
1265 std::vector
<DisplayInfo
> display_info_list
;
1267 display_info_list
.push_back(first_display_info
);
1268 display_info_list
.push_back(second_display_info
);
1269 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1271 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
1273 EXPECT_EQ(11, Shell::GetScreen()->GetPrimaryDisplay().id());
1275 display_info_list
.clear();
1276 const DisplayInfo new_first_display_info
=
1277 CreateDisplayInfo(20, 0, gfx::Display::ROTATE_0
);
1278 const DisplayInfo new_second_display_info
=
1279 CreateDisplayInfo(21, 1, gfx::Display::ROTATE_0
);
1280 display_info_list
.push_back(new_first_display_info
);
1281 display_info_list
.push_back(new_second_display_info
);
1282 display_manager
->OnNativeDisplaysChanged(display_info_list
);
1284 EXPECT_EQ(20, Shell::GetScreen()->GetPrimaryDisplay().id());
1287 TEST_F(DisplayControllerTest
, UpdateMouseLocationAfterDisplayChange
) {
1288 if (!SupportsMultipleDisplays())
1291 UpdateDisplay("200x200,300x300");
1292 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1294 aura::Env
* env
= aura::Env::GetInstance();
1296 ui::test::EventGenerator
generator(root_windows
[0]);
1298 // Set the initial position.
1299 generator
.MoveMouseToInHost(350, 150);
1300 EXPECT_EQ("350,150", env
->last_mouse_location().ToString());
1302 // A mouse pointer will stay in the 2nd display.
1303 UpdateDisplay("300x300,200x200");
1304 EXPECT_EQ("450,50", env
->last_mouse_location().ToString());
1306 // A mouse pointer will be outside of displays and move to the
1307 // center of 2nd display.
1308 UpdateDisplay("300x300,100x100");
1309 EXPECT_EQ("350,50", env
->last_mouse_location().ToString());
1311 // 2nd display was disconnected, and the cursor is
1312 // now in the 1st display.
1313 UpdateDisplay("400x400");
1314 EXPECT_EQ("50,350", env
->last_mouse_location().ToString());
1316 // 1st display's resolution has changed, and the mouse pointer is
1317 // now outside. Move the mouse pointer to the center of 1st display.
1318 UpdateDisplay("300x300");
1319 EXPECT_EQ("150,150", env
->last_mouse_location().ToString());
1321 // Move the mouse pointer to the bottom of 1st display.
1322 generator
.MoveMouseToInHost(150, 290);
1323 EXPECT_EQ("150,290", env
->last_mouse_location().ToString());
1325 // The mouse pointer is now on 2nd display.
1326 UpdateDisplay("300x280,200x200");
1327 EXPECT_EQ("450,10", env
->last_mouse_location().ToString());
1330 TEST_F(DisplayControllerTest
, UpdateMouseLocationAfterDisplayChange_2ndOnLeft
) {
1331 if (!SupportsMultipleDisplays())
1334 // Set the 2nd display on the left.
1335 DisplayLayoutStore
* layout_store
=
1336 Shell::GetInstance()->display_manager()->layout_store();
1337 DisplayLayout layout
= layout_store
->default_display_layout();
1338 layout
.position
= DisplayLayout::LEFT
;
1339 layout_store
->SetDefaultDisplayLayout(layout
);
1341 UpdateDisplay("200x200,300x300");
1342 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1344 EXPECT_EQ("-300,0 300x300",
1345 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1347 aura::Env
* env
= aura::Env::GetInstance();
1349 // Set the initial position.
1350 root_windows
[0]->MoveCursorTo(gfx::Point(-150, 250));
1351 EXPECT_EQ("-150,250", env
->last_mouse_location().ToString());
1353 // A mouse pointer will stay in 2nd display.
1354 UpdateDisplay("300x300,200x300");
1355 EXPECT_EQ("-50,150", env
->last_mouse_location().ToString());
1357 // A mouse pointer will be outside of displays and move to the
1358 // center of 2nd display.
1359 UpdateDisplay("300x300,200x100");
1360 EXPECT_EQ("-100,50", env
->last_mouse_location().ToString());
1362 // 2nd display was disconnected. Mouse pointer should move to
1364 UpdateDisplay("300x300");
1365 EXPECT_EQ("150,150", env
->last_mouse_location().ToString());
1368 // Test that the cursor swaps displays and that its scale factor and rotation
1369 // are updated when the primary display is swapped.
1370 TEST_F(DisplayControllerTest
,
1371 UpdateMouseLocationAfterDisplayChange_SwapPrimary
) {
1372 if (!SupportsMultipleDisplays())
1375 UpdateDisplay("200x200,200x200*2/r");
1377 aura::Env
* env
= aura::Env::GetInstance();
1378 Shell
* shell
= Shell::GetInstance();
1379 DisplayController
* display_controller
= shell
->display_controller();
1380 test::CursorManagerTestApi
test_api(shell
->cursor_manager());
1382 display_controller
->GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(20, 50));
1384 EXPECT_EQ("20,50", env
->last_mouse_location().ToString());
1385 EXPECT_EQ(1.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1386 EXPECT_EQ(gfx::Display::ROTATE_0
, test_api
.GetCurrentCursorRotation());
1388 display_controller
->SwapPrimaryDisplay();
1390 EXPECT_EQ("20,50", env
->last_mouse_location().ToString());
1391 EXPECT_EQ(2.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1392 EXPECT_EQ(gfx::Display::ROTATE_90
, test_api
.GetCurrentCursorRotation());
1395 // Test that the cursor moves to the other display and that its scale factor
1396 // and rotation are updated when the primary display is disconnected.
1397 TEST_F(DisplayControllerTest
,
1398 UpdateMouseLocationAfterDisplayChange_PrimaryDisconnected
) {
1399 if (!SupportsMultipleDisplays())
1402 aura::Env
* env
= aura::Env::GetInstance();
1403 Shell
* shell
= Shell::GetInstance();
1404 DisplayController
* display_controller
= shell
->display_controller();
1405 test::CursorManagerTestApi
test_api(shell
->cursor_manager());
1407 UpdateDisplay("300x300*2/r,200x200");
1408 // Swap the primary display to make it possible to remove the primary display
1409 // via UpdateDisplay().
1410 display_controller
->SwapPrimaryDisplay();
1411 int primary_display_id
= display_controller
->GetPrimaryDisplayId();
1413 display_controller
->GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(20, 50));
1415 EXPECT_EQ("20,50", env
->last_mouse_location().ToString());
1416 EXPECT_EQ(1.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1417 EXPECT_EQ(gfx::Display::ROTATE_0
, test_api
.GetCurrentCursorRotation());
1419 UpdateDisplay("300x300*2/r");
1420 ASSERT_NE(primary_display_id
, display_controller
->GetPrimaryDisplayId());
1422 // Cursor should be centered on the remaining display.
1423 EXPECT_EQ("75,75", env
->last_mouse_location().ToString());
1424 EXPECT_EQ(2.0f
, test_api
.GetCurrentCursor().device_scale_factor());
1425 EXPECT_EQ(gfx::Display::ROTATE_90
, test_api
.GetCurrentCursorRotation());
1428 // GetRootWindowForDisplayId() for removed gfx::Display during
1429 // OnDisplayRemoved() should not cause crash. See http://crbug.com/415222
1430 TEST_F(DisplayControllerTest
,
1431 GetRootWindowForDisplayIdDuringDisplayDisconnection
) {
1432 if (!SupportsMultipleDisplays())
1435 UpdateDisplay("300x300,200x200");
1436 aura::Window
* root2
=
1437 Shell::GetInstance()->display_controller()->GetRootWindowForDisplayId(
1438 ScreenUtil::GetSecondaryDisplay().id());
1439 views::Widget
* widget
= views::Widget::CreateWindowWithContextAndBounds(
1440 nullptr, root2
, gfx::Rect(350, 0, 100, 100));
1441 views::View
* view
= new views::View();
1442 widget
->GetContentsView()->AddChildView(view
);
1443 view
->SetBounds(0, 0, 100, 100);
1446 TestMouseWatcherListener listener
;
1447 views::MouseWatcher
watcher(
1448 new views::MouseWatcherViewHost(view
, gfx::Insets()), &listener
);
1451 ui::test::EventGenerator
event_generator(
1452 widget
->GetNativeWindow()->GetRootWindow());
1453 event_generator
.MoveMouseToCenterOf(widget
->GetNativeWindow());
1455 UpdateDisplay("300x300");