summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/accelerators/accelerator_controller_unittest.cc5
-rw-r--r--ash/ash.gyp2
-rw-r--r--ash/dip_unittest.cc14
-rw-r--r--ash/display/display_change_observer_x11.cc65
-rw-r--r--ash/display/display_controller.cc44
-rw-r--r--ash/display/display_controller.h3
-rw-r--r--ash/display/display_controller_unittest.cc35
-rw-r--r--ash/display/display_info.cc143
-rw-r--r--ash/display/display_info.h130
-rw-r--r--ash/display/display_manager.cc393
-rw-r--r--ash/display/display_manager.h75
-rw-r--r--ash/display/display_manager_unittest.cc221
-rw-r--r--ash/test/ash_test_base.cc10
-rw-r--r--ash/test/ash_test_base.h4
-rw-r--r--ash/test/display_manager_test_api.cc49
-rw-r--r--ash/test/display_manager_test_api.h4
-rw-r--r--ash/wm/system_gesture_event_filter_unittest.cc5
-rw-r--r--ui/aura/root_window.cc1
-rw-r--r--ui/base/x/events_x.cc8
-rw-r--r--ui/base/x/x11_util.cc10
-rw-r--r--ui/base/x/x11_util.h8
-rw-r--r--ui/gfx/display.cc14
-rw-r--r--ui/gfx/display.h10
23 files changed, 498 insertions, 755 deletions
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc
index 62b52c2..ccc574d 100644
--- a/ash/accelerators/accelerator_controller_unittest.cc
+++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -14,7 +14,6 @@
#include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/test/ash_test_base.h"
-#include "ash/test/display_manager_test_api.h"
#include "ash/test/test_shell_delegate.h"
#include "ash/volume_control_delegate.h"
#include "ash/wm/window_util.h"
@@ -314,8 +313,8 @@ class AcceleratorControllerTest : public test::AshTestBase {
protected:
void EnableInternalDisplay() {
- test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
- SetFirstDisplayAsInternalDisplay();
+ Shell::GetInstance()->display_manager()->
+ SetFirstDisplayAsInternalDisplayForTest();
}
static AcceleratorController* GetController();
diff --git a/ash/ash.gyp b/ash/ash.gyp
index ec824a4..a4c6f7c 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -81,8 +81,6 @@
'display/display_controller.h',
'display/display_error_dialog.cc',
'display/display_error_dialog.h',
- 'display/display_info.h',
- 'display/display_info.cc',
'display/display_manager.cc',
'display/display_manager.h',
'display/event_transformation_handler.cc',
diff --git a/ash/dip_unittest.cc b/ash/dip_unittest.cc
index 2c00d71a..1df1ec7 100644
--- a/ash/dip_unittest.cc
+++ b/ash/dip_unittest.cc
@@ -5,7 +5,6 @@
#include <algorithm>
#include <vector>
-#include "ash/display/display_manager.h"
#include "ash/launcher/launcher.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
@@ -30,7 +29,7 @@ typedef ash::test::AshTestBase DIPTest;
// Test if the WM sets correct work area under different density.
TEST_F(DIPTest, WorkArea) {
- UpdateDisplay("1000x900*1.0f");
+ ChangeDisplayConfig(1.0f, gfx::Rect(0, 0, 1000, 900));
aura::RootWindow* root = Shell::GetPrimaryRootWindow();
const gfx::Display display =
@@ -41,16 +40,13 @@ TEST_F(DIPTest, WorkArea) {
EXPECT_EQ("0,0 1000x852", work_area.ToString());
EXPECT_EQ("0,0,48,0", display.bounds().InsetsFrom(work_area).ToString());
- UpdateDisplay("2000x1800*2.0f");
- gfx::Screen* screen = Shell::GetScreen();
+ ChangeDisplayConfig(2.0f, gfx::Rect(0, 0, 2000, 1800));
- const gfx::Display display_2x = screen->GetDisplayNearestWindow(root);
- const internal::DisplayInfo display_info_2x =
- Shell::GetInstance()->display_manager()->GetDisplayInfo(display_2x);
+ const gfx::Display display_2x =
+ Shell::GetScreen()->GetDisplayNearestWindow(root);
// The |bounds_in_pixel()| should report bounds in pixel coordinate.
- EXPECT_EQ("1,1 2000x1800",
- display_info_2x.bounds_in_pixel().ToString());
+ EXPECT_EQ("0,0 2000x1800", display_2x.bounds_in_pixel().ToString());
// Aura and views coordinates are in DIP, so they their bounds do not change.
EXPECT_EQ("0,0 1000x900", display_2x.bounds().ToString());
diff --git a/ash/display/display_change_observer_x11.cc b/ash/display/display_change_observer_x11.cc
index d4d7c4e..b7114ce 100644
--- a/ash/display/display_change_observer_x11.cc
+++ b/ash/display/display_change_observer_x11.cc
@@ -11,12 +11,9 @@
#include <X11/extensions/Xrandr.h>
-#include "ash/display/display_info.h"
#include "ash/display/display_manager.h"
#include "ash/shell.h"
#include "base/message_pump_aurax11.h"
-#include "grit/ash_strings.h"
-#include "ui/base/l10n/l10n_util.h"
#include "ui/base/x/x11_util.h"
#include "ui/compositor/dip_util.h"
#include "ui/gfx/display.h"
@@ -48,7 +45,7 @@ XRRModeInfo* FindMode(XRRScreenResources* screen_resources, XID current_mode) {
return NULL;
}
-bool CompareDisplayY(const DisplayInfo& lhs, const DisplayInfo& rhs) {
+bool CompareDisplayY(const gfx::Display& lhs, const gfx::Display& rhs) {
return lhs.bounds_in_pixel().y() < rhs.bounds_in_pixel().y();
}
@@ -79,12 +76,6 @@ bool ShouldIgnoreSize(XRROutputInfo *output_info) {
return false;
}
-std::string GetDisplayName(XID output_id) {
- std::string display_name;
- ui::GetOutputDeviceData(output_id, NULL, NULL, &display_name);
- return display_name;
-}
-
} // namespace
DisplayChangeObserverX11::DisplayChangeObserverX11()
@@ -110,14 +101,15 @@ void DisplayChangeObserverX11::OnDisplayModeChanged() {
crtc_info_map[crtc_id] = crtc_info;
}
- std::vector<DisplayInfo> displays;
+ std::vector<gfx::Display> displays;
std::set<int> y_coords;
std::set<int64> ids;
for (int output_index = 0; output_index < screen_resources->noutput;
output_index++) {
- XID output = screen_resources->outputs[output_index];
XRROutputInfo *output_info =
- XRRGetOutputInfo(xdisplay_, screen_resources, output);
+ XRRGetOutputInfo(xdisplay_,
+ screen_resources,
+ screen_resources->outputs[output_index]);
if (output_info->connection != RR_Connected) {
XRRFreeOutputInfo(output_info);
continue;
@@ -137,6 +129,7 @@ void DisplayChangeObserverX11::OnDisplayModeChanged() {
// Mirrored monitors have the same y coordinates.
if (y_coords.find(crtc_info->y) != y_coords.end())
continue;
+ displays.push_back(gfx::Display());
float device_scale_factor = 1.0f;
if (!ShouldIgnoreSize(output_info) &&
@@ -144,43 +137,24 @@ void DisplayChangeObserverX11::OnDisplayModeChanged() {
kHighDensityDPIThreshold) {
device_scale_factor = 2.0f;
}
- gfx::Rect display_bounds(
- crtc_info->x, crtc_info->y, mode->width, mode->height);
-
- XRRFreeOutputInfo(output_info);
- bool is_internal = chromeos::OutputConfigurator::IsInternalOutputName(
- std::string(output_info->name));
-
- std::string name = is_internal ?
- l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME) :
- GetDisplayName(output);
- if (name.empty())
- name = l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME);
-
- bool has_overscan;
- ui::GetOutputOverscanFlag(output, &has_overscan);
+ displays.back().SetScaleAndBounds(
+ device_scale_factor,
+ gfx::Rect(crtc_info->x, crtc_info->y, mode->width, mode->height));
uint16 manufacturer_id = 0;
uint16 product_code = 0;
- int64 id = gfx::Display::kInvalidDisplayID;
-
- if (ui::GetOutputDeviceData(
- output, &manufacturer_id, &product_code, NULL) &&
+ if (ui::GetOutputDeviceData(screen_resources->outputs[output_index],
+ &manufacturer_id, &product_code, NULL) &&
manufacturer_id != 0) {
// An ID based on display's index will be assigned later if this call
// fails.
int64 new_id = gfx::Display::GetID(
manufacturer_id, product_code, output_index);
- if (ids.find(new_id) == ids.end())
- id = new_id;
+ if (ids.find(new_id) == ids.end()) {
+ displays.back().set_id(new_id);
+ ids.insert(new_id);
+ }
}
- if (id == gfx::Display::kInvalidDisplayID)
- id = output_index;
- ids.insert(id);
-
- displays.push_back(DisplayInfo(id, name, has_overscan));
- displays.back().set_device_scale_factor(device_scale_factor);
- displays.back().SetBounds(display_bounds);
y_coords.insert(crtc_info->y);
XRRFreeOutputInfo(output_info);
@@ -196,7 +170,14 @@ void DisplayChangeObserverX11::OnDisplayModeChanged() {
// PowerManager lays out the outputs vertically. Sort them by Y
// coordinates.
std::sort(displays.begin(), displays.end(), CompareDisplayY);
-
+ int64 id = 0;
+ for (std::vector<gfx::Display>::iterator iter = displays.begin();
+ iter != displays.end(); ++iter) {
+ if (iter->id() == gfx::Display::kInvalidDisplayID) {
+ iter->set_id(id);
+ ++id;
+ }
+ }
// DisplayManager can be null during the boot.
Shell::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays);
}
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc
index 29987d5..2d645a1 100644
--- a/ash/display/display_controller.cc
+++ b/ash/display/display_controller.cc
@@ -296,8 +296,26 @@ bool DisplayController::HasPrimaryDisplay() {
}
void DisplayController::InitPrimaryDisplay() {
- const gfx::Display* primary_candidate =
- GetDisplayManager()->GetPrimaryDisplayCandidate();
+ const gfx::Display* primary_candidate = GetDisplayManager()->GetDisplayAt(0);
+#if defined(OS_CHROMEOS)
+ if (base::chromeos::IsRunningOnChromeOS()) {
+ internal::DisplayManager* display_manager = GetDisplayManager();
+ // On ChromeOS device, root windows are stacked vertically, and
+ // default primary is the one on top.
+ int count = display_manager->GetNumDisplays();
+ int y = primary_candidate->bounds_in_pixel().y();
+ for (int i = 1; i < count; ++i) {
+ const gfx::Display* display = display_manager->GetDisplayAt(i);
+ if (display->IsInternal()) {
+ primary_candidate = display;
+ break;
+ } else if (display->bounds_in_pixel().y() < y) {
+ primary_candidate = display;
+ y = display->bounds_in_pixel().y();
+ }
+ }
+ }
+#endif
primary_display_id = primary_candidate->id();
AddRootWindowForDisplay(*primary_candidate);
UpdateDisplayBoundsForLayout();
@@ -387,10 +405,6 @@ void DisplayController::SetOverscanInsets(int64 display_id,
GetDisplayManager()->SetOverscanInsets(display_id, insets_in_dip);
}
-void DisplayController::ClearCustomOverscanInsets(int64 display_id) {
- GetDisplayManager()->ClearCustomOverscanInsets(display_id);
-}
-
std::vector<internal::RootWindowController*>
DisplayController::GetAllRootWindowControllers() {
std::vector<internal::RootWindowController*> controllers;
@@ -545,13 +559,11 @@ void DisplayController::SetPrimaryDisplay(
GetLayoutForDisplay(new_primary_display).Invert());
// Update the dispay manager with new display info.
- std::vector<internal::DisplayInfo> display_info_list;
- display_info_list.push_back(display_manager->GetDisplayInfo(
- display_manager->GetDisplayForId(primary_display_id)));
- display_info_list.push_back(display_manager->GetDisplayInfo(
- *GetSecondaryDisplay()));
+ std::vector<gfx::Display> displays;
+ displays.push_back(display_manager->GetDisplayForId(primary_display_id));
+ displays.push_back(*GetSecondaryDisplay());
GetDisplayManager()->set_force_bounds_changed(true);
- GetDisplayManager()->UpdateDisplays(display_info_list);
+ GetDisplayManager()->UpdateDisplays(displays);
GetDisplayManager()->set_force_bounds_changed(false);
}
@@ -565,15 +577,12 @@ gfx::Display* DisplayController::GetSecondaryDisplay() {
void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) {
if (limiter_.get())
limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
- DCHECK(!GetDisplayManager()->GetDisplayInfo(display).
- bounds_in_pixel().IsEmpty());
NotifyDisplayConfigurationChanging();
UpdateDisplayBoundsForLayout();
aura::RootWindow* root = root_windows_[display.id()];
SetDisplayPropertiesOnHostWindow(root, display);
- root->SetHostBounds(
- GetDisplayManager()->GetDisplayInfo(display).bounds_in_pixel());
+ root->SetHostBounds(display.bounds_in_pixel());
}
void DisplayController::OnDisplayAdded(const gfx::Display& display) {
@@ -589,8 +598,7 @@ void DisplayController::OnDisplayAdded(const gfx::Display& display) {
internal::kDisplayIdKey, display.id());
primary_root_window_for_replace_ = NULL;
UpdateDisplayBoundsForLayout();
- root_windows_[display.id()]->SetHostBounds(
- GetDisplayManager()->GetDisplayInfo(display).bounds_in_pixel());
+ root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel());
} else {
DCHECK(!root_windows_.empty());
aura::RootWindow* root = AddRootWindowForDisplay(display);
diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h
index 65b4570..2674483 100644
--- a/ash/display/display_controller.h
+++ b/ash/display/display_controller.h
@@ -141,11 +141,10 @@ class ASH_EXPORT DisplayController : public gfx::DisplayObserver {
// mode, this return a RootWindowController for the primary root window only.
std::vector<internal::RootWindowController*> GetAllRootWindowControllers();
- // Gets/Sets/Clears the overscan insets for the specified |display_id|. See
+ // Gets/Sets the overscan insets for the specified |display_id|. See
// display_manager.h for the details.
gfx::Insets GetOverscanInsets(int64 display_id) const;
void SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip);
- void ClearCustomOverscanInsets(int64 display_id);
const DisplayLayout& default_display_layout() const {
return default_display_layout_;
diff --git a/ash/display/display_controller_unittest.cc b/ash/display/display_controller_unittest.cc
index c07a9b7..a507062 100644
--- a/ash/display/display_controller_unittest.cc
+++ b/ash/display/display_controller_unittest.cc
@@ -395,15 +395,14 @@ TEST_F(DisplayControllerTest, SwapPrimaryById) {
EXPECT_FALSE(tracker.Contains(secondary_root));
EXPECT_TRUE(primary_root->Contains(launcher_window));
- internal::DisplayManager* display_manager =
- Shell::GetInstance()->display_manager();
// Adding 2nd display with the same ID. The 2nd display should become primary
// since secondary id is still stored as desirable_primary_id.
- std::vector<internal::DisplayInfo> display_info_list;
- display_info_list.push_back(display_manager->GetDisplayInfo(primary_display));
- display_info_list.push_back(
- display_manager->GetDisplayInfo(secondary_display));
- display_manager->OnNativeDisplaysChanged(display_info_list);
+ std::vector<gfx::Display> displays;
+ displays.push_back(primary_display);
+ displays.push_back(secondary_display);
+ internal::DisplayManager* display_manager =
+ Shell::GetInstance()->display_manager();
+ display_manager->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
EXPECT_EQ(secondary_display.id(),
@@ -420,27 +419,23 @@ TEST_F(DisplayControllerTest, SwapPrimaryById) {
// Deleting 2nd display and adding 2nd display with a different ID. The 2nd
// display shouldn't become primary.
UpdateDisplay("200x200");
- internal::DisplayInfo third_display_info(
- secondary_display.id() + 1, std::string(), false);
- third_display_info.SetBounds(secondary_display.bounds());
- ASSERT_NE(primary_display.id(), third_display_info.id());
-
- const internal::DisplayInfo& primary_display_info =
- display_manager->GetDisplayInfo(primary_display);
- std::vector<internal::DisplayInfo> display_info_list2;
- display_info_list2.push_back(primary_display_info);
- display_info_list2.push_back(third_display_info);
- display_manager->OnNativeDisplaysChanged(display_info_list2);
+ std::vector<gfx::Display> displays2;
+ gfx::Display third_display(
+ secondary_display.id() + 1, secondary_display.bounds());
+ ASSERT_NE(primary_display.id(), third_display.id());
+ displays2.push_back(primary_display);
+ displays2.push_back(third_display);
+ display_manager->OnNativeDisplaysChanged(displays2);
EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
EXPECT_EQ(primary_display.id(),
Shell::GetScreen()->GetPrimaryDisplay().id());
- EXPECT_EQ(third_display_info.id(), ScreenAsh::GetSecondaryDisplay().id());
+ EXPECT_EQ(third_display.id(), ScreenAsh::GetSecondaryDisplay().id());
EXPECT_EQ(
primary_root,
display_controller->GetRootWindowForDisplayId(primary_display.id()));
EXPECT_NE(
primary_root,
- display_controller->GetRootWindowForDisplayId(third_display_info.id()));
+ display_controller->GetRootWindowForDisplayId(third_display.id()));
EXPECT_TRUE(primary_root->Contains(launcher_window));
}
diff --git a/ash/display/display_info.cc b/ash/display/display_info.cc
deleted file mode 100644
index e94ea9e..0000000
--- a/ash/display/display_info.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdio.h>
-
-#include "ash/display/display_info.h"
-#include "base/logging.h"
-#include "base/stringprintf.h"
-#include "ui/gfx/display.h"
-
-#if defined(OS_WIN)
-#include "ui/aura/root_window_host.h"
-#endif
-
-namespace ash {
-namespace internal {
-
-// satic
-DisplayInfo DisplayInfo::CreateFromSpec(const std::string& spec) {
- return CreateFromSpecWithID(spec, gfx::Display::kInvalidDisplayID);
-}
-
-// static
-DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec,
- int64 id) {
- // Default bounds for a display.
- const int kDefaultHostWindowX = 200;
- const int kDefaultHostWindowY = 200;
- const int kDefaultHostWindowWidth = 1280;
- const int kDefaultHostWindowHeight = 1024;
-
- static int64 synthesized_display_id = 1000;
-
-#if defined(OS_WIN)
- gfx::Rect bounds(aura::RootWindowHost::GetNativeScreenSize());
-#else
- gfx::Rect bounds(kDefaultHostWindowX, kDefaultHostWindowY,
- kDefaultHostWindowWidth, kDefaultHostWindowHeight);
-#endif
-
- int x = 0, y = 0, width, height;
- float scale = 1.0f;
- if (sscanf(spec.c_str(), "%dx%d*%f", &width, &height, &scale) >= 2 ||
- sscanf(spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height,
- &scale) >= 4) {
- bounds.SetRect(x, y, width, height);
- }
- if (id == gfx::Display::kInvalidDisplayID)
- id = synthesized_display_id++;
- DisplayInfo display_info(
- id, base::StringPrintf("Display-%d", static_cast<int>(id)), false);
- display_info.set_device_scale_factor(scale);
- display_info.SetBounds(bounds);
- DVLOG(1) << "DisplayInfoFromSpec info=" << display_info.ToString()
- << ", spec=" << spec;
- return display_info;
-}
-
-DisplayInfo::DisplayInfo()
- : id_(gfx::Display::kInvalidDisplayID),
- has_overscan_(false),
- device_scale_factor_(1.0f),
- overscan_insets_in_dip_(-1, -1, -1, -1),
- has_custom_overscan_insets_(false) {
-}
-
-DisplayInfo::DisplayInfo(int64 id,
- const std::string& name,
- bool has_overscan)
- : id_(id),
- name_(name),
- has_overscan_(has_overscan),
- device_scale_factor_(1.0f),
- overscan_insets_in_dip_(-1, -1, -1, -1),
- has_custom_overscan_insets_(false) {
-}
-
-DisplayInfo::~DisplayInfo() {
-}
-
-void DisplayInfo::CopyFromNative(const DisplayInfo& native_info) {
- DCHECK(id_ == native_info.id_);
- name_ = native_info.name_;
- has_overscan_ = native_info.has_overscan_;
-
- DCHECK(!native_info.original_bounds_in_pixel_.IsEmpty());
- original_bounds_in_pixel_ = native_info.original_bounds_in_pixel_;
- bounds_in_pixel_ = native_info.bounds_in_pixel_;
- device_scale_factor_ = native_info.device_scale_factor_;
-}
-
-void DisplayInfo::SetBounds(const gfx::Rect& new_original_bounds) {
- original_bounds_in_pixel_ = bounds_in_pixel_ = new_original_bounds;
-}
-
-void DisplayInfo::UpdateBounds(const gfx::Rect& new_original_bounds) {
- bool overscan = original_bounds_in_pixel_ != bounds_in_pixel_;
- original_bounds_in_pixel_ = bounds_in_pixel_ = new_original_bounds;
- if (overscan) {
- original_bounds_in_pixel_.Inset(
- overscan_insets_in_dip_.Scale(-device_scale_factor_));
- }
-}
-
-void DisplayInfo::UpdateOverscanInfo(bool can_overscan) {
- bounds_in_pixel_ = original_bounds_in_pixel_;
- if (can_overscan) {
- if (has_custom_overscan_insets_) {
- bounds_in_pixel_.Inset(
- overscan_insets_in_dip_.Scale(device_scale_factor_));
- } else if (has_overscan_) {
- // Currently we assume 5% overscan and hope for the best if TV claims it
- // overscan, but doesn't expose how much.
- int width = bounds_in_pixel_.width() / 40;
- int height = bounds_in_pixel_.height() / 40;
- gfx::Insets insets_in_pixel(height, width, height, width);
- overscan_insets_in_dip_ =
- insets_in_pixel.Scale(1.0 / device_scale_factor_);
- bounds_in_pixel_.Inset(
- overscan_insets_in_dip_.Scale(device_scale_factor_));
- }
- }
-}
-
-void DisplayInfo::SetOverscanInsets(bool custom,
- const gfx::Insets& insets_in_dip) {
- has_custom_overscan_insets_ = custom;
- overscan_insets_in_dip_ = insets_in_dip;
-}
-
-std::string DisplayInfo::ToString() const {
- return base::StringPrintf(
- "DisplayInfo[%lld] bounds=%s, original=%s, scale=%f, overscan=%s",
- static_cast<long long int>(id_),
- bounds_in_pixel_.ToString().c_str(),
- original_bounds_in_pixel_.ToString().c_str(),
- device_scale_factor_,
- overscan_insets_in_dip_.ToString().c_str());
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/ash/display/display_info.h b/ash/display/display_info.h
deleted file mode 100644
index 94adf1d..0000000
--- a/ash/display/display_info.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_DISPLAY_DISPLAY_INFO_H_
-#define ASH_DISPLAY_DISPLAY_INFO_H_
-
-#include <string>
-
-#include "ash/ash_export.h"
-#include "base/gtest_prod_util.h"
-#include "ui/gfx/insets.h"
-#include "ui/gfx/rect.h"
-
-namespace gfx {
-class Display;
-}
-
-namespace ash {
-namespace internal {
-
-// DisplayInfo contains metadata for each display. This is used to
-// create |gfx::Display| as well as to maintain extra infomation
-// to manage displays in ash environment.
-// This class is intentionally made copiable.
-class ASH_EXPORT DisplayInfo {
- public:
- // Creates a DisplayInfo from string spec. 100+200-1440x800 creates display
- // whose size is 1440x800 at the location (100, 200) in screen's coordinates.
- // The location can be omitted and be just "1440x800", which creates
- // display at the origin of the screen. An empty string creates
- // the display with default size.
- // The device scale factor can be specified by "*", like "1280x780*2",
- // or will use the value of |gfx::Display::GetForcedDeviceScaleFactor()| if
- // --force-device-scale-factor is specified.
- static DisplayInfo CreateFromSpec(const std::string& spec);
-
- // Creates a DisplayInfo from string spec using given |id|.
- static DisplayInfo CreateFromSpecWithID(const std::string& spec,
- int64 id);
-
- DisplayInfo();
- DisplayInfo(int64 id, const std::string& name, bool has_overscan);
- ~DisplayInfo();
-
- int64 id() const { return id_; }
-
- // The name of the display.
- const std::string& name() const { return name_; }
-
- // True if the display has overscan.
- bool has_overscan() const { return has_overscan_; }
-
- // Gets/Sets the device scale factor of the display.
- float device_scale_factor() const { return device_scale_factor_; }
- void set_device_scale_factor(float scale) { device_scale_factor_ = scale; }
-
- // The original bounds_in_pixel for the display. This can be different from
- // the |bounds_in_pixel| in case of overscan insets.
- const gfx::Rect original_bounds_in_pixel() const {
- return original_bounds_in_pixel_;
- }
-
- // The bounds for the display in pixels.
- const gfx::Rect bounds_in_pixel() const { return bounds_in_pixel_; }
-
- // The overscan insets for the display in DIP. The default value is
- // (-1, -1, -1, -1), which indicates that no overscan should be applied.
- const gfx::Insets& overscan_insets_in_dip() const {
- return overscan_insets_in_dip_;
- }
-
- // Copy the display info except for two fields that can be modified by a user
- // (|has_custom_overscan_insets_| and |custom_overscan_insets_in_dip_|).
- void CopyFromNative(const DisplayInfo& native_info);
-
- // Set the |original_bounds_in_pixel| and |bounds_in_pixel| to
- // given |bounds|.
- void SetBounds(const gfx::Rect& bounds_in_pixel);
-
- // Sets the |bounds_in_pixel| and updates original bounds based on
- // current overscan configuration.
- void UpdateBounds(const gfx::Rect& bounds_in_pixel);
-
- // Update the |bounds_in_pixel| according to the current overscan
- // settings.
- // 1) If can_overscan is false, then |bounds_in_pixel| is equal to
- // |original_bounds_in_pixel|.
- // 2) If this has custom overscan insets
- // (i.e. |has_custom_overscan_insets_| is true), it simply applies
- // the existing |overscan_insets_in_dip_|.
- // 3) If this doesn't have custom overscan insets, then this updates
- // |overscan_insets_in_dip_| to default value (5% of the display size)
- // and apply the insets.
- void UpdateOverscanInfo(bool can_overscan);
-
- // Sets/Clears the overscan insets.
- void SetOverscanInsets(bool custom,
- const gfx::Insets& insets_in_dip);
- void clear_has_custom_overscan_insets() {
- has_custom_overscan_insets_ = false;
- }
-
- // Returns a string representation of the DisplayInfo;
- std::string ToString() const;
-
- private:
- FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, AutomaticOverscanInsets);
- // Set the overscan flag. Used for test.
- void set_has_overscan_for_test(bool has_overscan) {
- has_overscan_ = has_overscan;
- }
-
- int64 id_;
- std::string name_;
- bool has_overscan_;
- float device_scale_factor_;
- gfx::Rect original_bounds_in_pixel_;
- gfx::Rect bounds_in_pixel_;
- gfx::Insets overscan_insets_in_dip_;
-
- // True if the |overscan_insets_in_dip| is specified by a user. This
- // is used not to override the insets by native insets.
- bool has_custom_overscan_insets_;
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_DISPLAY_DISPLAY_INFO_H_
diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc
index 6aef6f4..170b340 100644
--- a/ash/display/display_manager.cc
+++ b/ash/display/display_manager.cc
@@ -46,12 +46,10 @@
#endif
DECLARE_WINDOW_PROPERTY_TYPE(int64);
+typedef std::vector<gfx::Display> DisplayList;
namespace ash {
namespace internal {
-typedef std::vector<gfx::Display> DisplayList;
-typedef std::vector<DisplayInfo> DisplayInfoList;
-
namespace {
// Default bounds for a display.
@@ -66,38 +64,29 @@ struct DisplaySortFunctor {
}
};
-struct DisplayInfoSortFunctor {
- bool operator()(const DisplayInfo& a, const DisplayInfo& b) {
- return a.id() < b.id();
- }
-};
-
gfx::Display& GetInvalidDisplay() {
static gfx::Display* invalid_display = new gfx::Display();
return *invalid_display;
}
#if defined(OS_CHROMEOS)
-
-int64 FindInternalDisplayID() {
- std::vector<XID> outputs;
- ui::GetOutputDeviceHandles(&outputs);
- std::vector<std::string> output_names = ui::GetOutputNames(outputs);
- for (size_t i = 0; i < output_names.size(); ++i) {
- if (chromeos::OutputConfigurator::IsInternalOutputName(
- output_names[i])) {
- uint16 manufacturer_id = 0;
- uint16 product_code = 0;
- ui::GetOutputDeviceData(
- outputs[i], &manufacturer_id, &product_code, NULL);
- return gfx::Display::GetID(manufacturer_id, product_code, i);
- }
- }
- return gfx::Display::kInvalidDisplayID;
+int64 GetDisplayIdForOutput(XID output, int output_index) {
+ uint16 manufacturer_id = 0;
+ uint16 product_code = 0;
+ ui::GetOutputDeviceData(
+ output, &manufacturer_id, &product_code, NULL);
+ return gfx::Display::GetID(manufacturer_id, product_code, output_index);
}
-
#endif
+gfx::Insets GetDefaultDisplayOverscan(const gfx::Display& display) {
+ // Currently we assume 5% overscan and hope for the best if TV claims it
+ // overscan, but doesn't expose how much.
+ int width = display.bounds().width() / 40;
+ int height = display.bounds().height() / 40;
+ return gfx::Insets(height, width, height, width);
+}
+
} // namespace
using aura::RootWindow;
@@ -170,34 +159,24 @@ const gfx::Display& DisplayManager::FindDisplayContainingPoint(
void DisplayManager::SetOverscanInsets(int64 display_id,
const gfx::Insets& insets_in_dip) {
- display_info_[display_id].SetOverscanInsets(true, insets_in_dip);
- DisplayInfoList display_info_list;
- for (DisplayList::const_iterator iter = displays_.begin();
- iter != displays_.end(); ++iter) {
- display_info_list.push_back(GetDisplayInfo(*iter));
- }
- UpdateDisplays(display_info_list);
-}
+ display_info_[display_id].overscan_insets_in_dip = insets_in_dip;
+ display_info_[display_id].has_custom_overscan_insets = true;
-void DisplayManager::ClearCustomOverscanInsets(int64 display_id) {
- display_info_[display_id].clear_has_custom_overscan_insets();
- DisplayInfoList display_info_list;
- for (DisplayList::const_iterator iter = displays_.begin();
- iter != displays_.end(); ++iter) {
- display_info_list.push_back(GetDisplayInfo(*iter));
- }
- UpdateDisplays(display_info_list);
+ // Copies the |displays_| because UpdateDisplays() compares the passed
+ // displays and its internal |displays_|.
+ DisplayList displays = displays_;
+ UpdateDisplays(displays);
}
gfx::Insets DisplayManager::GetOverscanInsets(int64 display_id) const {
std::map<int64, DisplayInfo>::const_iterator it =
display_info_.find(display_id);
return (it != display_info_.end()) ?
- it->second.overscan_insets_in_dip() : gfx::Insets();
+ it->second.overscan_insets_in_dip : gfx::Insets();
}
void DisplayManager::OnNativeDisplaysChanged(
- const std::vector<DisplayInfo>& updated_displays) {
+ const std::vector<gfx::Display>& updated_displays) {
if (updated_displays.empty()) {
// Don't update the displays when all displays are disconnected.
// This happens when:
@@ -211,34 +190,55 @@ void DisplayManager::OnNativeDisplaysChanged(
// display list will be updated correctly.
return;
}
-
- bool internal_display_connected = false;
- for (DisplayInfoList::const_iterator iter = updated_displays.begin();
- iter != updated_displays.end() && !internal_display_connected;
- ++iter) {
- internal_display_connected = IsInternalDisplayId(iter->id());
- if (internal_display_connected)
- internal_display_info_.reset(new DisplayInfo(*iter));
+ DisplayList new_displays = updated_displays;
+ if (HasInternalDisplay()) {
+ bool internal_display_connected = false;
+ for (DisplayList::const_iterator iter = updated_displays.begin();
+ iter != updated_displays.end(); ++iter) {
+ if ((*iter).IsInternal()) {
+ internal_display_connected = true;
+ // Update the internal display cache.
+ internal_display_.reset(new gfx::Display);
+ *internal_display_.get() = *iter;
+ break;
+ }
+ }
+ // If the internal display wasn't connected, use the cached value.
+ if (!internal_display_connected) {
+ // Internal display may be reported as disconnect during startup time.
+ if (!internal_display_.get()) {
+ internal_display_.reset(
+ new gfx::Display(gfx::Display::InternalDisplayId(),
+ gfx::Rect(800, 600)));
+ }
+ new_displays.push_back(*internal_display_.get());
+ }
+ } else {
+ new_displays = updated_displays;
}
- DisplayInfoList new_display_info_list = updated_displays;
-
- if (HasInternalDisplay() && !internal_display_connected) {
- if (!internal_display_info_.get()) {
- // TODO(oshima): Get has_custom value.
- internal_display_info_.reset(new DisplayInfo(
- gfx::Display::InternalDisplayId(),
- l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME),
- false));
- internal_display_info_->SetBounds(gfx::Rect(0, 0, 800, 600));
+
+ RefreshDisplayInfo();
+
+ for (DisplayList::const_iterator iter = new_displays.begin();
+ iter != new_displays.end(); ++iter) {
+ std::map<int64, DisplayInfo>::iterator info =
+ display_info_.find(iter->id());
+ if (info != display_info_.end()) {
+ info->second.original_bounds_in_pixel = iter->bounds_in_pixel();
+ if (info->second.has_overscan && !info->second.has_custom_overscan_insets)
+ info->second.overscan_insets_in_dip = GetDefaultDisplayOverscan(*iter);
+ } else {
+ display_info_[iter->id()].original_bounds_in_pixel =
+ iter->bounds_in_pixel();
}
- new_display_info_list.push_back(*internal_display_info_.get());
}
- UpdateDisplays(new_display_info_list);
+ UpdateDisplays(new_displays);
}
void DisplayManager::UpdateDisplays(
- const std::vector<DisplayInfo>& updated_display_info_list) {
+ const std::vector<gfx::Display>& updated_displays) {
+ DisplayList new_displays = updated_displays;
#if defined(OS_CHROMEOS)
// Overscan is always enabled when not running on the device
// in order for unit tests to work.
@@ -246,15 +246,26 @@ void DisplayManager::UpdateDisplays(
!base::chromeos::IsRunningOnChromeOS() ||
(Shell::GetInstance()->output_configurator()->output_state() !=
chromeos::STATE_DUAL_MIRROR &&
- updated_display_info_list.size() == 1);
+ updated_displays.size() == 1);
#else
bool can_overscan = true;
#endif
- DisplayInfoList new_display_info_list = updated_display_info_list;
+ if (can_overscan) {
+ for (DisplayList::iterator iter = new_displays.begin();
+ iter != new_displays.end(); ++iter) {
+ std::map<int64, DisplayInfo>::const_iterator info =
+ display_info_.find(iter->id());
+ if (info != display_info_.end()) {
+ gfx::Rect bounds = info->second.original_bounds_in_pixel;
+ bounds.Inset(info->second.overscan_insets_in_dip.Scale(
+ iter->device_scale_factor()));
+ iter->SetScaleAndBounds(iter->device_scale_factor(), bounds);
+ }
+ }
+ }
+
std::sort(displays_.begin(), displays_.end(), DisplaySortFunctor());
- std::sort(new_display_info_list.begin(),
- new_display_info_list.end(),
- DisplayInfoSortFunctor());
+ std::sort(new_displays.begin(), new_displays.end(), DisplaySortFunctor());
DisplayList removed_displays;
std::vector<size_t> changed_display_indices;
std::vector<size_t> added_display_indices;
@@ -262,54 +273,44 @@ void DisplayManager::UpdateDisplays(
if (DisplayController::HasPrimaryDisplay())
current_primary = DisplayController::GetPrimaryDisplay();
- DisplayList::iterator curr_iter = displays_.begin();
- DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin();
-
- DisplayList new_displays;
- while (curr_iter != displays_.end() ||
- new_info_iter != new_display_info_list.end()) {
+ for (DisplayList::iterator curr_iter = displays_.begin(),
+ new_iter = new_displays.begin();
+ curr_iter != displays_.end() || new_iter != new_displays.end();) {
if (curr_iter == displays_.end()) {
// more displays in new list.
- added_display_indices.push_back(new_displays.size());
- InsertAndUpdateDisplayInfo(*new_info_iter, can_overscan);
- new_displays.push_back(
- CreateDisplayFromDisplayInfoById(new_info_iter->id()));
- ++new_info_iter;
- } else if (new_info_iter == new_display_info_list.end()) {
+ added_display_indices.push_back(new_iter - new_displays.begin());
+ ++new_iter;
+ } else if (new_iter == new_displays.end()) {
// more displays in current list.
removed_displays.push_back(*curr_iter);
++curr_iter;
- } else if (curr_iter->id() == new_info_iter->id()) {
+ } else if ((*curr_iter).id() == (*new_iter).id()) {
const gfx::Display& current_display = *curr_iter;
- // Copy the info because |CreateDisplayFromInfo| updates the instance.
- const DisplayInfo current_display_info = GetDisplayInfo(current_display);
- InsertAndUpdateDisplayInfo(*new_info_iter, can_overscan);
- gfx::Display new_display =
- CreateDisplayFromDisplayInfoById(new_info_iter->id());
- const DisplayInfo& new_display_info = GetDisplayInfo(new_display);
+ gfx::Display& new_display = *new_iter;
if (force_bounds_changed_ ||
- (current_display_info.bounds_in_pixel() !=
- new_display_info.bounds_in_pixel()) ||
- (current_display.device_scale_factor() !=
- new_display.device_scale_factor())) {
- changed_display_indices.push_back(new_displays.size());
+ current_display.bounds_in_pixel() != new_display.bounds_in_pixel() ||
+ current_display.device_scale_factor() !=
+ new_display.device_scale_factor()) {
+ changed_display_indices.push_back(new_iter - new_displays.begin());
}
+ // If the display is primary, then simpy set the origin to (0,0).
+ // The secondary display's bounds will be updated by
+ // |DisplayController::UpdateDisplayBoundsForLayout|, so no need
+ // to change there.
+ if ((*new_iter).id() == current_primary.id())
+ new_display.set_bounds(gfx::Rect(new_display.bounds().size()));
new_display.UpdateWorkAreaFromInsets(current_display.GetWorkAreaInsets());
- new_displays.push_back(new_display);
++curr_iter;
- ++new_info_iter;
- } else if (curr_iter->id() < new_info_iter->id()) {
+ ++new_iter;
+ } else if ((*curr_iter).id() < (*new_iter).id()) {
// more displays in current list between ids, which means it is deleted.
removed_displays.push_back(*curr_iter);
++curr_iter;
} else {
// more displays in new list between ids, which means it is added.
- added_display_indices.push_back(new_displays.size());
- InsertAndUpdateDisplayInfo(*new_info_iter, can_overscan);
- new_displays.push_back(
- CreateDisplayFromDisplayInfoById(new_info_iter->id()));
- ++new_info_iter;
+ added_display_indices.push_back(new_iter - new_displays.begin());
+ ++new_iter;
}
}
@@ -351,10 +352,10 @@ void DisplayManager::UpdateDisplays(
RootWindow* DisplayManager::CreateRootWindowForDisplay(
const gfx::Display& display) {
static int root_window_count = 0;
- const gfx::Rect& bounds_in_pixel = GetDisplayInfo(display).bounds_in_pixel();
- RootWindow::CreateParams params(bounds_in_pixel);
+
+ RootWindow::CreateParams params(display.bounds_in_pixel());
params.host = Shell::GetInstance()->root_window_host_factory()->
- CreateRootWindowHost(bounds_in_pixel);
+ CreateRootWindowHost(display.bounds_in_pixel());
aura::RootWindow* root_window = new aura::RootWindow(params);
root_window->SetName(StringPrintf("RootWindow-%d", root_window_count++));
@@ -370,30 +371,6 @@ gfx::Display* DisplayManager::GetDisplayAt(size_t index) {
return index < displays_.size() ? &displays_[index] : NULL;
}
-const gfx::Display* DisplayManager::GetPrimaryDisplayCandidate() const {
- const gfx::Display* primary_candidate = &displays_[0];
-#if defined(OS_CHROMEOS)
- if (base::chromeos::IsRunningOnChromeOS()) {
- // On ChromeOS device, root windows are stacked vertically, and
- // default primary is the one on top.
- int count = GetNumDisplays();
- int y = GetDisplayInfo(*primary_candidate).bounds_in_pixel().y();
- for (int i = 1; i < count; ++i) {
- const gfx::Display* display = &displays_[i];
- const DisplayInfo& display_info = GetDisplayInfo(*display);
- if (display->IsInternal()) {
- primary_candidate = display;
- break;
- } else if (display_info.bounds_in_pixel().y() < y) {
- primary_candidate = display;
- y = display_info.bounds_in_pixel().y();
- }
- }
- }
-#endif
- return primary_candidate;
-}
-
size_t DisplayManager::GetNumDisplays() const {
return displays_.size();
}
@@ -438,14 +415,6 @@ const gfx::Display& DisplayManager::GetDisplayMatching(
return matching ? *matching : DisplayController::GetPrimaryDisplay();
}
-const DisplayInfo& DisplayManager::GetDisplayInfo(
- const gfx::Display& display) const {
- std::map<int64, DisplayInfo>::const_iterator iter =
- display_info_.find(display.id());
- CHECK(iter != display_info_.end());
- return iter->second;
-}
-
std::string DisplayManager::GetDisplayNameFor(
const gfx::Display& display) {
if (!display.is_valid())
@@ -453,8 +422,8 @@ std::string DisplayManager::GetDisplayNameFor(
std::map<int64, DisplayInfo>::const_iterator iter =
display_info_.find(display.id());
- if (iter != display_info_.end() && !iter->second.name().empty())
- return iter->second.name();
+ if (iter != display_info_.end() && !iter->second.name.empty())
+ return iter->second.name;
return base::StringPrintf("Display %d", static_cast<int>(display.id()));
}
@@ -469,8 +438,6 @@ void DisplayManager::OnRootWindowResized(const aura::RootWindow* root,
gfx::Display& display = FindDisplayForRootWindow(root);
if (display.size() != root->GetHostSize()) {
display.SetSize(root->GetHostSize());
- display_info_[display.id()].UpdateBounds(
- gfx::Rect(root->GetHostOrigin(), root->GetHostSize()));
Shell::GetInstance()->screen()->NotifyBoundsChanged(display);
}
}
@@ -478,10 +445,23 @@ void DisplayManager::OnRootWindowResized(const aura::RootWindow* root,
void DisplayManager::Init() {
#if defined(OS_CHROMEOS)
- if (base::chromeos::IsRunningOnChromeOS())
- gfx::Display::SetInternalDisplayId(FindInternalDisplayID());
+ if (base::chromeos::IsRunningOnChromeOS()) {
+ std::vector<XID> outputs;
+ ui::GetOutputDeviceHandles(&outputs);
+ std::vector<std::string> output_names = ui::GetOutputNames(outputs);
+ for (size_t i = 0; i < output_names.size(); ++i) {
+ if (chromeos::OutputConfigurator::IsInternalOutputName(
+ output_names[i])) {
+ gfx::Display::SetInternalDisplayId(
+ GetDisplayIdForOutput(outputs[i], i));
+ break;
+ }
+ }
+ }
#endif
+ RefreshDisplayInfo();
+
// TODO(oshima): Move this logic to DisplayChangeObserver.
const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kAshHostWindowBounds);
@@ -497,32 +477,34 @@ void DisplayManager::Init() {
void DisplayManager::CycleDisplayImpl() {
DCHECK(!displays_.empty());
- std::vector<DisplayInfo> new_display_info_list;
- new_display_info_list.push_back(
- GetDisplayInfo(DisplayController::GetPrimaryDisplay()));
+ std::vector<gfx::Display> new_displays;
+ new_displays.push_back(DisplayController::GetPrimaryDisplay());
// Add if there is only one display.
if (displays_.size() == 1) {
// Layout the 2nd display below the primary as with the real device.
aura::RootWindow* primary = Shell::GetPrimaryRootWindow();
gfx::Rect host_bounds =
gfx::Rect(primary->GetHostOrigin(), primary->GetHostSize());
- new_display_info_list.push_back(DisplayInfo::CreateFromSpec(
+ new_displays.push_back(CreateDisplayFromSpec(
StringPrintf("%d+%d-500x400", host_bounds.x(), host_bounds.bottom())));
}
- OnNativeDisplaysChanged(new_display_info_list);
+ OnNativeDisplaysChanged(new_displays);
}
void DisplayManager::ScaleDisplayImpl() {
DCHECK(!displays_.empty());
- std::vector<DisplayInfo> new_display_info_list;
+ std::vector<gfx::Display> new_displays;
for (DisplayList::const_iterator iter = displays_.begin();
iter != displays_.end(); ++iter) {
- DisplayInfo display_info = GetDisplayInfo(*iter);
- display_info.set_device_scale_factor(
- display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f);
- new_display_info_list.push_back(display_info);
+ gfx::Display display = *iter;
+ float factor = display.device_scale_factor() == 1.0f ? 2.0f : 1.0f;
+ gfx::Point display_origin = display.bounds_in_pixel().origin();
+ gfx::Size display_size = gfx::ToFlooredSize(
+ gfx::ScaleSize(display.size(), factor));
+ display.SetScaleAndBounds(factor, gfx::Rect(display_origin, display_size));
+ new_displays.push_back(display);
}
- OnNativeDisplaysChanged(new_display_info_list);
+ OnNativeDisplaysChanged(new_displays);
}
gfx::Display& DisplayManager::FindDisplayForRootWindow(
@@ -546,12 +528,22 @@ gfx::Display& DisplayManager::FindDisplayForId(int64 id) {
}
void DisplayManager::AddDisplayFromSpec(const std::string& spec) {
- DisplayInfo display_info = DisplayInfo::CreateFromSpec(spec);
- InsertAndUpdateDisplayInfo(display_info, false);
- gfx::Display display = CreateDisplayFromDisplayInfoById(display_info.id());
+ gfx::Display display = CreateDisplayFromSpec(spec);
+
+ const gfx::Insets insets = display.GetWorkAreaInsets();
+ const gfx::Rect& native_bounds = display.bounds_in_pixel();
+ display.SetScaleAndBounds(display.device_scale_factor(), native_bounds);
+ display.UpdateWorkAreaFromInsets(insets);
displays_.push_back(display);
}
+int64 DisplayManager::SetFirstDisplayAsInternalDisplayForTest() {
+ gfx::Display::SetInternalDisplayId(displays_[0].id());
+ internal_display_.reset(new gfx::Display);
+ *internal_display_ = displays_[0];
+ return gfx::Display::InternalDisplayId();
+}
+
void DisplayManager::EnsurePointerInDisplays() {
// Don't try to move the pointer during the boot/startup.
if (!DisplayController::HasPrimaryDisplay())
@@ -590,35 +582,76 @@ void DisplayManager::EnsurePointerInDisplays() {
root_window->MoveCursorTo(target_location);
}
-void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info,
- bool can_overscan) {
- std::map<int64, DisplayInfo>::iterator info =
- display_info_.find(new_info.id());
- if (info != display_info_.end())
- info->second.CopyFromNative(new_info);
- else
- display_info_[new_info.id()] = new_info;
+DisplayManager::DisplayInfo::DisplayInfo()
+ : has_overscan(false),
+ has_custom_overscan_insets(false) {
+}
+
+void DisplayManager::RefreshDisplayInfo() {
+#if defined(OS_CHROMEOS)
+ if (!base::chromeos::IsRunningOnChromeOS())
+ return;
+#endif
+
+#if defined(USE_X11)
+ std::vector<XID> outputs;
+ if (!ui::GetOutputDeviceHandles(&outputs))
+ return;
+
+ for (size_t output_index = 0; output_index < outputs.size(); ++output_index) {
+ uint16 manufacturer_id = 0;
+ uint16 product_code = 0;
+ std::string name;
+ ui::GetOutputDeviceData(
+ outputs[output_index], &manufacturer_id, &product_code, &name);
+ int64 id = gfx::Display::GetID(manufacturer_id, product_code, output_index);
+ if (IsInternalDisplayId(id)) {
+ display_info_[id].name =
+ l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME);
+ } else if (!name.empty()) {
+ display_info_[id].name = name;
+ }
+
+ ui::GetOutputOverscanFlag(
+ outputs[output_index], &display_info_[id].has_overscan);
+ }
+#endif
+}
- display_info_[new_info.id()].UpdateOverscanInfo(can_overscan);
+void DisplayManager::SetDisplayIdsForTest(DisplayList* to_update) const {
+ DisplayList::iterator iter_to_update = to_update->begin();
+ DisplayList::const_iterator iter = displays_.begin();
+ for (; iter != displays_.end() && iter_to_update != to_update->end();
+ ++iter, ++iter_to_update) {
+ (*iter_to_update).set_id((*iter).id());
+ }
}
-gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) {
- DCHECK(display_info_.find(id) != display_info_.end());
- const DisplayInfo& display_info = display_info_[id];
+void DisplayManager::SetHasOverscanFlagForTest(int64 id, bool has_overscan) {
+ display_info_[id].has_overscan = has_overscan;
+}
- gfx::Display new_display(display_info.id());
- new_display.SetScaleAndBounds(
- display_info.device_scale_factor(), display_info.bounds_in_pixel());
+gfx::Display CreateDisplayFromSpec(const std::string& spec) {
+ static int64 synthesized_display_id = 1000;
- // If the display is primary, then simply set the origin to (0,0).
- // The secondary display's bounds will be updated by
- // |DisplayController::UpdateDisplayBoundsForLayout|, so no need
- // to change there.
- if (DisplayController::HasPrimaryDisplay() &&
- display_info.id() == DisplayController::GetPrimaryDisplay().id()) {
- new_display.set_bounds(gfx::Rect(new_display.bounds().size()));
+#if defined(OS_WIN)
+ gfx::Rect bounds(aura::RootWindowHost::GetNativeScreenSize());
+#else
+ gfx::Rect bounds(kDefaultHostWindowX, kDefaultHostWindowY,
+ kDefaultHostWindowWidth, kDefaultHostWindowHeight);
+#endif
+ int x = 0, y = 0, width, height;
+ float scale = 1.0f;
+ if (sscanf(spec.c_str(), "%dx%d*%f", &width, &height, &scale) >= 2 ||
+ sscanf(spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height,
+ &scale) >= 4) {
+ bounds.SetRect(x, y, width, height);
}
- return new_display;
+
+ gfx::Display display(synthesized_display_id++);
+ display.SetScaleAndBounds(scale, bounds);
+ DVLOG(1) << "Display bounds=" << bounds.ToString() << ", scale=" << scale;
+ return display;
}
} // namespace internal
diff --git a/ash/display/display_manager.h b/ash/display/display_manager.h
index 541ea4b..25be7c1 100644
--- a/ash/display/display_manager.h
+++ b/ash/display/display_manager.h
@@ -9,7 +9,6 @@
#include <vector>
#include "ash/ash_export.h"
-#include "ash/display/display_info.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "ui/aura/root_window_observer.h"
@@ -77,9 +76,6 @@ class ASH_EXPORT DisplayManager : public aura::RootWindowObserver {
// display's bounds change.
void SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip);
- // Clears the overscan insets
- void ClearCustomOverscanInsets(int64 display_id);
-
// Returns the current overscan insets for the specified |display_id|.
// Returns an empty insets (0, 0, 0, 0) if no insets are specified for
// the display.
@@ -88,11 +84,10 @@ class ASH_EXPORT DisplayManager : public aura::RootWindowObserver {
// Called when display configuration has changed. The new display
// configurations is passed as a vector of Display object, which
// contains each display's new infomration.
- void OnNativeDisplaysChanged(
- const std::vector<DisplayInfo>& display_info_list);
+ void OnNativeDisplaysChanged(const std::vector<gfx::Display>& displays);
// Updates the internal display data and notifies observers about the changes.
- void UpdateDisplays(const std::vector<DisplayInfo>& display_info_list);
+ void UpdateDisplays(const std::vector<gfx::Display>& displays);
// Create a root window for given |display|.
aura::RootWindow* CreateRootWindowForDisplay(const gfx::Display& display);
@@ -102,8 +97,6 @@ class ASH_EXPORT DisplayManager : public aura::RootWindowObserver {
// no longer considered "primary".
gfx::Display* GetDisplayAt(size_t index);
- const gfx::Display* GetPrimaryDisplayCandidate() const;
-
size_t GetNumDisplays() const;
// Returns the display object nearest given |window|.
@@ -118,9 +111,6 @@ class ASH_EXPORT DisplayManager : public aura::RootWindowObserver {
const gfx::Display& GetDisplayMatching(
const gfx::Rect& match_rect)const;
- // Retuns the display info associated with |display|.
- const DisplayInfo& GetDisplayInfo(const gfx::Display& display) const;
-
// Returns the human-readable name for the display specified by |display|.
std::string GetDisplayNameFor(const gfx::Display& display);
@@ -141,6 +131,29 @@ class ASH_EXPORT DisplayManager : public aura::RootWindowObserver {
typedef std::vector<gfx::Display> DisplayList;
+ // Metadata for each display.
+ struct DisplayInfo {
+ DisplayInfo();
+
+ // The cached name of the display.
+ std::string name;
+
+ // The original bounds_in_pixel for the display. This can be different from
+ // the current one in case of overscan insets.
+ gfx::Rect original_bounds_in_pixel;
+
+ // The overscan insets for the display.
+ gfx::Insets overscan_insets_in_dip;
+
+ // True if we detect that the display has overscan area. False if the
+ // display doesn't have it, or failed to detect it.
+ bool has_overscan;
+
+ // True if the |overscan_insets_in_dip| is specified. This is set because
+ // the user may specify an empty inset intentionally.
+ bool has_custom_overscan_insets;
+ };
+
void Init();
void CycleDisplayImpl();
void ScaleDisplayImpl();
@@ -151,26 +164,30 @@ class ASH_EXPORT DisplayManager : public aura::RootWindowObserver {
// Refer to |CreateDisplayFromSpec| API for the format of |spec|.
void AddDisplayFromSpec(const std::string& spec);
+ // Set the 1st display as an internal display and returns the display Id for
+ // the internal display.
+ int64 SetFirstDisplayAsInternalDisplayForTest();
+
// Checks if the mouse pointer is on one of displays, and moves to
// the center of the nearest display if it's outside of all displays.
void EnsurePointerInDisplays();
- // Inserts and update the DisplayInfo according to the overscan
- // state. Note that The DisplayInfo stored in the |internal_display_info_|
- // can be different from |new_info| (due to overscan state), so
- // you must use |GetDisplayInfo| to get the correct DisplayInfo for
- // a display.
- void InsertAndUpdateDisplayInfo(const DisplayInfo& new_info,
- bool can_overscan);
+ // Updates |display_info_| by calling platform-dependent functions.
+ void RefreshDisplayInfo();
+
+ // Update the display's id in the |display_list| to match the ones
+ // stored in this display manager's |displays_|. This is used to
+ // emulate display change behavior during the test byn creating the
+ // display list with the same display ids but with different bounds
+ void SetDisplayIdsForTest(DisplayList* display_list) const;
- // Creates a display object from the DisplayInfo for |display_id|.
- gfx::Display CreateDisplayFromDisplayInfoById(int64 display_id);
+ // Forcibly specify 'has_overscan' flag of the DisplayInfo for specified |id|.
+ void SetHasOverscanFlagForTest(int64 id, bool has_overscan);
DisplayList displays_;
- // An internal display info cache used when the internal display is
- // disconnectd.
- scoped_ptr<DisplayInfo> internal_display_info_;
+ // An internal display cache used when the internal display is disconnectd.
+ scoped_ptr<gfx::Display> internal_display_;
bool force_bounds_changed_;
@@ -180,6 +197,16 @@ class ASH_EXPORT DisplayManager : public aura::RootWindowObserver {
DISALLOW_COPY_AND_ASSIGN(DisplayManager);
};
+// Creates a display from string spec. 100+200-1440x800 creates display
+// whose size is 1440x800 at the location (100, 200) in screen's coordinates.
+// The location can be omitted and be just "1440x800", which creates
+// display at the origin of the screen. An empty string creates
+// the display with default size.
+// The device scale factor can be specified by "*", like "1280x780*2",
+// or will use the value of |gfx::Display::GetForcedDeviceScaleFactor()| if
+// --force-device-scale-factor is specified.
+ASH_EXPORT gfx::Display CreateDisplayFromSpec(const std::string& str);
+
extern const aura::WindowProperty<int64>* const kDisplayIdKey;
} // namespace internal
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc
index b3bba2c..43e2593 100644
--- a/ash/display/display_manager_unittest.cc
+++ b/ash/display/display_manager_unittest.cc
@@ -8,7 +8,6 @@
#include "ash/screen_ash.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
-#include "ash/test/display_manager_test_api.h"
#include "base/format_macros.h"
#include "base/stringprintf.h"
#include "ui/aura/env.h"
@@ -66,22 +65,10 @@ class DisplayManagerTest : public test::AshTestBase,
return root_window_destroyed_;
}
- const DisplayInfo& GetDisplayInfo(const gfx::Display& display) {
- return display_manager()->GetDisplayInfo(display);
- }
-
- const DisplayInfo& GetDisplayInfoAt(int index) {
- return GetDisplayInfo(*display_manager()->GetDisplayAt(index));
- }
-
const gfx::Display& FindDisplayForId(int64 id) {
return display_manager()->FindDisplayForId(id);
}
- const DisplayInfo& FindDisplayInfoForId(int64 id) {
- return GetDisplayInfo(display_manager()->FindDisplayForId(id));
- }
-
// aura::DisplayObserver overrides:
virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE {
changed_.push_back(display);
@@ -123,8 +110,7 @@ TEST_F(DisplayManagerTest, NativeDisplayTest) {
EXPECT_EQ("0,0 500x500", changed()[0].bounds().ToString());
// Secondary display is on right.
EXPECT_EQ("500,0 400x400", added()[0].bounds().ToString());
- EXPECT_EQ("0,501 400x400",
- GetDisplayInfo(added()[0]).bounds_in_pixel().ToString());
+ EXPECT_EQ("0,501 400x400", added()[0].bounds_in_pixel().ToString());
reset();
// Delete secondary.
@@ -146,8 +132,7 @@ TEST_F(DisplayManagerTest, NativeDisplayTest) {
EXPECT_EQ(display_manager()->GetDisplayAt(1)->id(), added()[0].id());
// Secondary display is on right.
EXPECT_EQ("1000,0 600x400", added()[0].bounds().ToString());
- EXPECT_EQ("1002,0 600x400",
- GetDisplayInfo(added()[0]).bounds_in_pixel().ToString());
+ EXPECT_EQ("1002,0 600x400", added()[0].bounds_in_pixel().ToString());
reset();
// Secondary removed, primary changed.
@@ -159,7 +144,7 @@ TEST_F(DisplayManagerTest, NativeDisplayTest) {
reset();
// # of display can go to zero when screen is off.
- const vector<DisplayInfo> empty;
+ const vector<gfx::Display> empty;
display_manager()->OnNativeDisplaysChanged(empty);
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
EXPECT_EQ("0 0 0", GetCountSummary());
@@ -175,8 +160,7 @@ TEST_F(DisplayManagerTest, NativeDisplayTest) {
EXPECT_EQ("1 0 0", GetCountSummary());
EXPECT_FALSE(root_window_destroyed());
EXPECT_EQ("0,0 500x400", changed()[0].bounds().ToString());
- EXPECT_EQ("100,100 500x400",
- GetDisplayInfo(changed()[0]).bounds_in_pixel().ToString());
+ EXPECT_EQ("100,100 500x400", changed()[0].bounds_in_pixel().ToString());
reset();
// Go back to zero and wake up with multiple displays.
@@ -194,7 +178,7 @@ TEST_F(DisplayManagerTest, NativeDisplayTest) {
EXPECT_EQ("1000,0 600x400",
display_manager()->GetDisplayAt(1)->bounds().ToString());
EXPECT_EQ("1000,1000 600x400",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
reset();
}
@@ -223,75 +207,74 @@ TEST_F(DisplayManagerTest, OverscanInsetsTest) {
UpdateDisplay("0+0-500x500,0+501-400x400");
reset();
ASSERT_EQ(2u, display_manager()->GetNumDisplays());
- const DisplayInfo& display_info1 = GetDisplayInfoAt(0);
- const DisplayInfo& display_info2 = GetDisplayInfoAt(1);
- display_manager()->SetOverscanInsets(
- display_info2.id(), gfx::Insets(13, 12, 11, 10));
+ gfx::Display display1(*display_manager()->GetDisplayAt(0));
+ gfx::Display display2(*display_manager()->GetDisplayAt(1));
+ display_manager()->SetOverscanInsets(
+ display2.id(), gfx::Insets(13, 12, 11, 10));
std::vector<gfx::Display> changed_displays = changed();
EXPECT_EQ(1u, changed_displays.size());
- EXPECT_EQ(display_info2.id(), changed_displays[0].id());
+ EXPECT_EQ(display2.id(), changed_displays[0].id());
EXPECT_EQ("0,0 500x500",
- GetDisplayInfoAt(0).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(0)->bounds_in_pixel().ToString());
EXPECT_EQ("12,514 378x376",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
// Make sure that SetOverscanInsets() is idempotent.
- display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets());
+ display_manager()->SetOverscanInsets(display1.id(), gfx::Insets());
display_manager()->SetOverscanInsets(
- display_info2.id(), gfx::Insets(13, 12, 11, 10));
+ display2.id(), gfx::Insets(13, 12, 11, 10));
EXPECT_EQ("0,0 500x500",
- GetDisplayInfoAt(0).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(0)->bounds_in_pixel().ToString());
EXPECT_EQ("12,514 378x376",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
display_manager()->SetOverscanInsets(
- display_info2.id(), gfx::Insets(10, 11, 12, 13));
+ display2.id(), gfx::Insets(10, 11, 12, 13));
EXPECT_EQ("0,0 500x500",
- GetDisplayInfoAt(0).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(0)->bounds_in_pixel().ToString());
EXPECT_EQ("11,511 376x378",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
// Recreate a new 2nd display. It won't apply the overscan inset because the
// new display has a different ID.
UpdateDisplay("0+0-500x500");
UpdateDisplay("0+0-500x500,0+501-400x400");
EXPECT_EQ("0,0 500x500",
- GetDisplayInfoAt(0).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(0)->bounds_in_pixel().ToString());
EXPECT_EQ("0,501 400x400",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
// Recreate the displays with the same ID. It should apply the overscan
// inset.
UpdateDisplay("0+0-500x500");
- std::vector<DisplayInfo> display_info_list;
- display_info_list.push_back(display_info1);
- display_info_list.push_back(display_info2);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
- EXPECT_EQ("1,1 500x500",
- GetDisplayInfoAt(0).bounds_in_pixel().ToString());
+ std::vector<gfx::Display> displays;
+ displays.push_back(display1);
+ displays.push_back(display2);
+ display_manager()->OnNativeDisplaysChanged(displays);
+ EXPECT_EQ("0,0 500x500",
+ display_manager()->GetDisplayAt(0)->bounds_in_pixel().ToString());
EXPECT_EQ("11,511 376x378",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
// HiDPI but overscan display. The specified insets size should be doubled.
+ UpdateDisplay("0+0-500x500");
UpdateDisplay("0+0-500x500,0+501-400x400*2");
display_manager()->SetOverscanInsets(
display_manager()->GetDisplayAt(1)->id(), gfx::Insets(4, 5, 6, 7));
EXPECT_EQ("0,0 500x500",
- GetDisplayInfoAt(0).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(0)->bounds_in_pixel().ToString());
EXPECT_EQ("10,509 376x380",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
EXPECT_EQ("188x190", display_manager()->GetDisplayAt(1)->size().ToString());
// Make sure switching primary display applies the overscan offset only once.
ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay(
ScreenAsh::GetSecondaryDisplay());
EXPECT_EQ("0,0 500x500",
- GetDisplayInfo(ScreenAsh::GetSecondaryDisplay()).
- bounds_in_pixel().ToString());
- EXPECT_EQ("10,509 376x380",
- GetDisplayInfo(gfx::Screen::GetNativeScreen()->GetPrimaryDisplay()).
- bounds_in_pixel().ToString());
+ ScreenAsh::GetSecondaryDisplay().bounds_in_pixel().ToString());
+ EXPECT_EQ("10,509 376x380", gfx::Screen::GetNativeScreen()->
+ GetPrimaryDisplay().bounds_in_pixel().ToString());
}
TEST_F(DisplayManagerTest, ZeroOverscanInsets) {
@@ -328,93 +311,84 @@ TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) {
Shell::GetPrimaryRootWindow()->bounds().size().ToString());
}
-DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
- DisplayInfo info(id, std::string(), false);
- info.SetBounds(bounds);
- return info;
-}
-
TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) {
const int64 internal_display_id =
- test::DisplayManagerTestApi(display_manager()).
- SetFirstDisplayAsInternalDisplay();
- const DisplayInfo native_display_info =
- CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
- const DisplayInfo external_display_info =
- CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
+ display_manager()->SetFirstDisplayAsInternalDisplayForTest();
+ const gfx::Display native_display(internal_display_id,
+ gfx::Rect(0, 0, 500, 500));
+ const gfx::Display external_display(10, gfx::Rect(1, 1, 100, 100));
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
std::string default_bounds =
display_manager()->GetDisplayAt(0)->bounds().ToString();
- std::vector<DisplayInfo> display_info_list;
+ std::vector<gfx::Display> displays;
// Primary disconnected.
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
EXPECT_EQ(default_bounds,
display_manager()->GetDisplayAt(0)->bounds().ToString());
// External connected while primary was disconnected.
- display_info_list.push_back(external_display_info);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ displays.push_back(external_display);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
-
EXPECT_EQ(default_bounds,
FindDisplayForId(internal_display_id).bounds().ToString());
EXPECT_EQ("1,1 100x100",
- FindDisplayInfoForId(10).bounds_in_pixel().ToString());
+ FindDisplayForId(10).bounds_in_pixel().ToString());
// Primary connected, with different bounds.
- display_info_list.clear();
- display_info_list.push_back(native_display_info);
- display_info_list.push_back(external_display_info);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ displays.clear();
+ displays.push_back(native_display);
+ displays.push_back(external_display);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
EXPECT_EQ("0,0 500x500",
FindDisplayForId(internal_display_id).bounds().ToString());
EXPECT_EQ("1,1 100x100",
- FindDisplayInfoForId(10).bounds_in_pixel().ToString());
+ FindDisplayForId(10).bounds_in_pixel().ToString());
// Turn off primary.
- display_info_list.clear();
- display_info_list.push_back(external_display_info);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ displays.clear();
+ displays.push_back(external_display);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
EXPECT_EQ("0,0 500x500",
FindDisplayForId(internal_display_id).bounds().ToString());
EXPECT_EQ("1,1 100x100",
- FindDisplayInfoForId(10).bounds_in_pixel().ToString());
+ FindDisplayForId(10).bounds_in_pixel().ToString());
// Emulate suspend.
- display_info_list.clear();
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ displays.clear();
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
EXPECT_EQ("0,0 500x500",
FindDisplayForId(internal_display_id).bounds().ToString());
EXPECT_EQ("1,1 100x100",
- FindDisplayInfoForId(10).bounds_in_pixel().ToString());
+ FindDisplayForId(10).bounds_in_pixel().ToString());
// External display has disconnected then resumed.
- display_info_list.push_back(native_display_info);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ displays.push_back(native_display);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
EXPECT_EQ("0,0 500x500",
FindDisplayForId(internal_display_id).bounds().ToString());
// External display was changed during suspend.
- display_info_list.push_back(external_display_info);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ displays.push_back(external_display);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
// suspend...
- display_info_list.clear();
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ displays.clear();
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
// and resume with different external display.
- display_info_list.push_back(native_display_info);
- display_info_list.push_back(CreateDisplayInfo(11, gfx::Rect(1, 1, 100, 100)));
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ displays.push_back(native_display);
+ displays.push_back(gfx::Display(11, gfx::Rect(1, 1, 100, 100)));
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
}
@@ -432,18 +406,17 @@ TEST_F(DisplayManagerTest, MAYBE_TestNativeDisplaysChangedNoInternal) {
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
// Don't change the display info if all displays are disconnected.
- std::vector<DisplayInfo> display_info_list;
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ std::vector<gfx::Display> displays;
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
// Connect another display which will become primary.
- const DisplayInfo external_display_info =
- CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
- display_info_list.push_back(external_display_info);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ const gfx::Display external_display(10, gfx::Rect(1, 1, 100, 100));
+ displays.push_back(external_display);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
EXPECT_EQ("1,1 100x100",
- FindDisplayInfoForId(10).bounds_in_pixel().ToString());
+ FindDisplayForId(10).bounds_in_pixel().ToString());
EXPECT_EQ("100x100",
ash::Shell::GetPrimaryRootWindow()->GetHostSize().ToString());
}
@@ -523,31 +496,29 @@ TEST_F(DisplayManagerTest, EnsurePointerInDisplays_2ndOnLeft) {
TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) {
const int64 internal_display_id =
- test::DisplayManagerTestApi(display_manager()).
- SetFirstDisplayAsInternalDisplay();
- const DisplayInfo native_display_info =
- CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
- const DisplayInfo secondary_display_info =
- CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
-
- std::vector<DisplayInfo> display_info_list;
- display_info_list.push_back(native_display_info);
- display_info_list.push_back(secondary_display_info);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ display_manager()->SetFirstDisplayAsInternalDisplayForTest();
+ const gfx::Display native_display(internal_display_id,
+ gfx::Rect(0, 0, 500, 500));
+ const gfx::Display secondary_display(10, gfx::Rect(1, 1, 100, 100));
+
+ std::vector<gfx::Display> displays;
+ displays.push_back(native_display);
+ displays.push_back(secondary_display);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
EXPECT_EQ("0,0 500x500",
FindDisplayForId(internal_display_id).bounds().ToString());
EXPECT_EQ("500,0 100x100", FindDisplayForId(10).bounds().ToString());
ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay(
- FindDisplayForId(secondary_display_info.id()));
+ secondary_display);
EXPECT_EQ("-500,0 500x500",
FindDisplayForId(internal_display_id).bounds().ToString());
EXPECT_EQ("0,0 100x100", FindDisplayForId(10).bounds().ToString());
// OnNativeDisplaysChanged may change the display bounds. Here makes sure
// nothing changed if the exactly same displays are specified.
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ("-500,0 500x500",
FindDisplayForId(internal_display_id).bounds().ToString());
EXPECT_EQ("0,0 100x100", FindDisplayForId(10).bounds().ToString());
@@ -556,35 +527,29 @@ TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) {
TEST_F(DisplayManagerTest, AutomaticOverscanInsets) {
UpdateDisplay("200x200,400x400");
- std::vector<DisplayInfo> display_info_list;
- display_info_list.push_back(GetDisplayInfoAt(0));
- display_info_list.push_back(GetDisplayInfoAt(1));
- display_info_list[1].set_has_overscan_for_test(true);
- int64 id = display_info_list[1].id();
- // SetDefaultOverscanInsets(&display_info_list[1]);
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ std::vector<gfx::Display> displays;
+ displays.push_back(*display_manager()->GetDisplayAt(0));
+ displays.push_back(*display_manager()->GetDisplayAt(1));
+ int64 id = displays[1].id();
+ display_manager()->SetHasOverscanFlagForTest(id, true);
+
+ display_manager()->OnNativeDisplaysChanged(displays);
// It has overscan insets, although SetOverscanInsets() isn't called.
EXPECT_EQ("11,211 380x380",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
// If custom overscan insets is specified, the specified value is used.
display_manager()->SetOverscanInsets(id, gfx::Insets(5, 6, 7, 8));
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ("7,206 386x388",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
// Do not overscan even though it has 'has_overscan' flag, if the custom
// insets is empty.
display_manager()->SetOverscanInsets(id, gfx::Insets());
- display_manager()->OnNativeDisplaysChanged(display_info_list);
+ display_manager()->OnNativeDisplaysChanged(displays);
EXPECT_EQ("1,201 400x400",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
-
- // Clearing the custom overscan should set the bounds to
- // original.
- display_manager()->ClearCustomOverscanInsets(id);
- EXPECT_EQ("11,211 380x380",
- GetDisplayInfoAt(1).bounds_in_pixel().ToString());
+ display_manager()->GetDisplayAt(1)->bounds_in_pixel().ToString());
}
} // namespace internal
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc
index 853cdff..980777e 100644
--- a/ash/test/ash_test_base.cc
+++ b/ash/test/ash_test_base.cc
@@ -161,6 +161,16 @@ aura::test::EventGenerator& AshTestBase::GetEventGenerator() {
return *event_generator_.get();
}
+void AshTestBase::ChangeDisplayConfig(float scale,
+ const gfx::Rect& bounds_in_pixel) {
+ gfx::Display display =
+ gfx::Display(Shell::GetScreen()->GetPrimaryDisplay().id());
+ display.SetScaleAndBounds(scale, bounds_in_pixel);
+ std::vector<gfx::Display> displays;
+ displays.push_back(display);
+ Shell::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays);
+}
+
void AshTestBase::UpdateDisplay(const std::string& display_specs) {
DisplayManagerTestApi display_manager_test_api(
Shell::GetInstance()->display_manager());
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h
index 3b4bd1d..2541c15 100644
--- a/ash/test/ash_test_base.h
+++ b/ash/test/ash_test_base.h
@@ -57,6 +57,10 @@ class AshTestBase : public testing::Test {
virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE;
+ // Change the primary display's configuration to use |bounds|
+ // and |scale|.
+ void ChangeDisplayConfig(float scale, const gfx::Rect& bounds);
+
// Update the display configuration as given in |display_specs|.
// See ash::test::DisplayManagerTestApi::UpdateDisplay for more details.
void UpdateDisplay(const std::string& display_specs);
diff --git a/ash/test/display_manager_test_api.cc b/ash/test/display_manager_test_api.cc
index 067bbc6..dbfb8495 100644
--- a/ash/test/display_manager_test_api.cc
+++ b/ash/test/display_manager_test_api.cc
@@ -6,7 +6,6 @@
#include <vector>
-#include "ash/display/display_info.h"
#include "ash/display/display_manager.h"
#include "ash/shell.h"
#include "base/string_split.h"
@@ -15,27 +14,18 @@
namespace ash {
namespace test {
-typedef std::vector<gfx::Display> DisplayList;
-typedef internal::DisplayInfo DisplayInfo;
-typedef std::vector<DisplayInfo> DisplayInfoList;
-
namespace {
-std::vector<DisplayInfo> CreateDisplayInfoListFromString(
- const std::string specs,
- internal::DisplayManager* display_manager) {
- std::vector<DisplayInfo> display_info_list;
+std::vector<gfx::Display> CreateDisplaysFromString(
+ const std::string specs) {
+ std::vector<gfx::Display> displays;
std::vector<std::string> parts;
base::SplitString(specs, ',', &parts);
- int index = 0;
for (std::vector<std::string>::const_iterator iter = parts.begin();
- iter != parts.end(); ++iter, ++index) {
- gfx::Display* display = display_manager->GetDisplayAt(index);
- int64 id = display ? display->id() : gfx::Display::kInvalidDisplayID;
- display_info_list.push_back(
- DisplayInfo::CreateFromSpecWithID(*iter, id));
+ iter != parts.end(); ++iter) {
+ displays.push_back(internal::CreateDisplayFromSpec(*iter));
}
- return display_info_list;
+ return displays;
}
} // namespace
@@ -49,12 +39,10 @@ DisplayManagerTestApi::~DisplayManagerTestApi() {}
void DisplayManagerTestApi::UpdateDisplay(
const std::string& display_specs) {
- std::vector<DisplayInfo> display_info_list =
- CreateDisplayInfoListFromString(display_specs, display_manager_);
+ std::vector<gfx::Display> displays = CreateDisplaysFromString(display_specs);
bool is_host_origin_set = false;
- for (size_t i = 0; i < display_info_list.size(); ++i) {
- const DisplayInfo& display_info = display_info_list[i];
- if (display_info.bounds_in_pixel().origin() != gfx::Point(0, 0)) {
+ for (size_t i = 0; i < displays.size(); ++i) {
+ if (displays[i].bounds_in_pixel().origin() != gfx::Point(0, 0)) {
is_host_origin_set = true;
break;
}
@@ -68,25 +56,18 @@ void DisplayManagerTestApi::UpdateDisplay(
// Sart from (1,1) so that windows won't overlap with native mouse cursor.
// See |AshTestBase::SetUp()|.
int next_y = 1;
- for (std::vector<DisplayInfo>::iterator iter = display_info_list.begin();
- iter != display_info_list.end(); ++iter) {
- gfx::Rect bounds(iter->bounds_in_pixel().size());
+ for (std::vector<gfx::Display>::iterator iter = displays.begin();
+ iter != displays.end(); ++iter) {
+ gfx::Rect bounds(iter->GetSizeInPixel());
bounds.set_x(1);
bounds.set_y(next_y);
next_y += bounds.height();
- iter->SetBounds(bounds);
+ iter->SetScaleAndBounds(iter->device_scale_factor(), bounds);
}
}
- display_manager_->OnNativeDisplaysChanged(display_info_list);
-}
-
-int64 DisplayManagerTestApi::SetFirstDisplayAsInternalDisplay() {
- const gfx::Display& internal = display_manager_->displays_[0];
- gfx::Display::SetInternalDisplayId(internal.id());
- display_manager_->internal_display_info_.reset(new DisplayInfo(
- display_manager_->GetDisplayInfo(internal)));
- return gfx::Display::InternalDisplayId();
+ display_manager_->SetDisplayIdsForTest(&displays);
+ display_manager_->OnNativeDisplaysChanged(displays);
}
} // namespace test
diff --git a/ash/test/display_manager_test_api.h b/ash/test/display_manager_test_api.h
index e6a83708..57e961d 100644
--- a/ash/test/display_manager_test_api.h
+++ b/ash/test/display_manager_test_api.h
@@ -27,10 +27,6 @@ class DisplayManagerTestApi {
// the format of the display spec.
void UpdateDisplay(const std::string& display_specs);
- // Set the 1st display as an internal display and returns the display Id for
- // the internal display.
- int64 SetFirstDisplayAsInternalDisplay();
-
private:
internal::DisplayManager* display_manager_; // not owned
diff --git a/ash/wm/system_gesture_event_filter_unittest.cc b/ash/wm/system_gesture_event_filter_unittest.cc
index 391cfbf..a5d345c 100644
--- a/ash/wm/system_gesture_event_filter_unittest.cc
+++ b/ash/wm/system_gesture_event_filter_unittest.cc
@@ -13,7 +13,6 @@
#include "ash/system/brightness/brightness_control_delegate.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/test/ash_test_base.h"
-#include "ash/test/display_manager_test_api.h"
#include "ash/test/shell_test_api.h"
#include "ash/test/test_launcher_delegate.h"
#include "ash/volume_control_delegate.h"
@@ -217,8 +216,8 @@ class SystemGestureEventFilterTest : public AshTestBase {
::switches::kEnableBezelTouch);
test::AshTestBase::SetUp();
// Enable brightness key.
- test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
- SetFirstDisplayAsInternalDisplay();
+ Shell::GetInstance()->display_manager()->
+ SetFirstDisplayAsInternalDisplayForTest();
}
private:
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 7ff474f..7305ca7 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -196,7 +196,6 @@ gfx::Size RootWindow::GetHostSize() const {
}
void RootWindow::SetHostBounds(const gfx::Rect& bounds_in_pixel) {
- DCHECK(!bounds_in_pixel.IsEmpty());
DispatchHeldMouseMove();
host_->SetBounds(bounds_in_pixel);
synthesize_mouse_move_ = false;
diff --git a/ui/base/x/events_x.cc b/ui/base/x/events_x.cc
index e4ca121..3fba257f0 100644
--- a/ui/base/x/events_x.cc
+++ b/ui/base/x/events_x.cc
@@ -718,10 +718,10 @@ gfx::Point CalibrateTouchCoordinates(
!top_border_touch_calibration && !bottom_border_touch_calibration)
return gfx::Point(x, y);
- gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
- gfx::Rect bounds = display.bounds();
- const int resolution_x = bounds.width() * display.device_scale_factor();
- const int resolution_y = bounds.height() * display.device_scale_factor();
+ gfx::Rect bounds =
+ gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().bounds_in_pixel();
+ const int resolution_x = bounds.width();
+ const int resolution_y = bounds.height();
// The "grace area" (10% in this case) is to make it easier for the user to
// navigate to the corner.
const double kGraceAreaFraction = 0.1;
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index ad59097..cb57e09 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -1488,6 +1488,16 @@ bool ParseOutputOverscanFlag(const unsigned char* prop,
return false;
}
+std::vector<std::string> GetDisplayNames(const std::vector<XID>& output_ids) {
+ std::vector<std::string> names;
+ for (size_t i = 0; i < output_ids.size(); ++i) {
+ std::string display_name;
+ if (GetOutputDeviceData(output_ids[i], NULL, NULL, &display_name))
+ names.push_back(display_name);
+ }
+ return names;
+}
+
std::vector<std::string> GetOutputNames(const std::vector<XID>& output_ids) {
std::vector<std::string> names;
Display* display = GetXDisplay();
diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h
index 1169f87..377dd41 100644
--- a/ui/base/x/x11_util.h
+++ b/ui/base/x/x11_util.h
@@ -303,9 +303,13 @@ UI_EXPORT bool ParseOutputOverscanFlag(const unsigned char* prop,
unsigned long nitems,
bool* flag);
-// Gets the name of outputs given by |output_ids|.
+// Gets the names of the all displays physically connected to the system.
+UI_EXPORT std::vector<std::string> GetDisplayNames(
+ const std::vector<XID>& output_id);
+
+// Gets the name of outputs given by |output_id|.
UI_EXPORT std::vector<std::string> GetOutputNames(
- const std::vector<XID>& output_ids);
+ const std::vector<XID>& output_id);
enum WindowManagerName {
WM_UNKNOWN,
diff --git a/ui/gfx/display.cc b/ui/gfx/display.cc
index 73f33b3..7aa1241 100644
--- a/ui/gfx/display.cc
+++ b/ui/gfx/display.cc
@@ -11,7 +11,6 @@
#include "ui/base/ui_base_switches.h"
#include "ui/base/win/dpi.h"
#include "ui/gfx/insets.h"
-#include "ui/gfx/point_f.h"
#include "ui/gfx/size_conversions.h"
namespace gfx {
@@ -104,19 +103,22 @@ void Display::SetScaleAndBounds(
device_scale_factor_ = device_scale_factor;
}
device_scale_factor_ = std::max(1.0f, device_scale_factor_);
+#if defined(USE_AURA)
+ bounds_in_pixel_ = bounds_in_pixel;
+#endif
bounds_ = gfx::Rect(gfx::ToFlooredSize(
gfx::ScaleSize(bounds_in_pixel.size(), 1.0f / device_scale_factor_)));
UpdateWorkAreaFromInsets(insets);
}
void Display::SetSize(const gfx::Size& size_in_pixel) {
- gfx::Point origin = bounds_.origin();
+ SetScaleAndBounds(
+ device_scale_factor_,
#if defined(USE_AURA)
- gfx::PointF origin_f = origin;
- origin_f.Scale(device_scale_factor_);
- origin.SetPoint(origin_f.x(), origin_f.y());
+ gfx::Rect(bounds_in_pixel_.origin(), size_in_pixel));
+#else
+ gfx::Rect(bounds_.origin(), size_in_pixel));
#endif
- SetScaleAndBounds(device_scale_factor_, gfx::Rect(origin, size_in_pixel));
}
void Display::UpdateWorkAreaFromInsets(const gfx::Insets& insets) {
diff --git a/ui/gfx/display.h b/ui/gfx/display.h
index 81963f2..4df69b7 100644
--- a/ui/gfx/display.h
+++ b/ui/gfx/display.h
@@ -88,6 +88,13 @@ class UI_EXPORT Display {
// Returns the display's size in pixel coordinates.
gfx::Size GetSizeInPixel() const;
+#if defined(USE_AURA)
+ // TODO(oshima|skuhne): Eliminate the use of bounds_in_pixel in events_x.cc
+ // and remove bounds_in_pixel from gfx::Display.
+ // Returns the display's bounds in pixel coordinates.
+ const Rect& bounds_in_pixel() const { return bounds_in_pixel_; }
+#endif
+
// Returns a string representation of the display;
std::string ToString() const;
@@ -107,6 +114,9 @@ class UI_EXPORT Display {
int64 id_;
Rect bounds_;
Rect work_area_;
+#if defined(USE_AURA)
+ Rect bounds_in_pixel_;
+#endif
float device_scale_factor_;
};