#include "ash/display/display_manager.h"
+#include <algorithm>
#include <cmath>
#include <set>
#include <string>
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/display.h"
+#include "ui/gfx/display_observer.h"
+#include "ui/gfx/font_render_params.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/size_conversions.h"
#endif
#if defined(OS_CHROMEOS)
-#include "ash/display/output_configurator_animation.h"
+#include "ash/display/display_configurator_animation.h"
#include "base/sys_info.h"
-#include "chromeos/display/output_configurator.h"
#endif
#if defined(OS_WIN)
#endif
namespace ash {
-namespace internal {
typedef std::vector<gfx::Display> DisplayList;
typedef std::vector<DisplayInfo> DisplayInfoList;
// for the full list of resolutions.
const float kUIScalesFor2x[] =
{0.5f, 0.625f, 0.8f, 1.0f, 1.125f, 1.25f, 1.5f, 2.0f};
+const float kUIScalesFor1_25x[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.25f };
const float kUIScalesFor1280[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.125f };
const float kUIScalesFor1366[] = {0.5f, 0.6f, 0.75f, 1.0f, 1.125f };
}
};
-struct ResolutionMatcher {
- ResolutionMatcher(const gfx::Size& size) : size(size) {}
- bool operator()(const Resolution& resolution) {
- return resolution.size == size;
+struct DisplayModeMatcher {
+ DisplayModeMatcher(const DisplayMode& target_mode)
+ : target_mode(target_mode) {}
+ bool operator()(const DisplayMode& mode) {
+ return target_mode.IsEquivalent(mode);
}
- gfx::Size size;
+ DisplayMode target_mode;
};
struct ScaleComparator {
- ScaleComparator(float s) : scale(s) {}
+ explicit ScaleComparator(float s) : scale(s) {}
bool operator()(float s) const {
const float kEpsilon = 0.0001f;
force_bounds_changed_(false),
change_display_upon_host_resize_(false),
second_display_mode_(EXTENDED),
- mirrored_display_id_(gfx::Display::kInvalidDisplayID) {
+ mirrored_display_id_(gfx::Display::kInvalidDisplayID),
+ registered_internal_display_rotation_lock_(false),
+ registered_internal_display_rotation_(gfx::Display::ROTATE_0) {
+
#if defined(OS_CHROMEOS)
+ // Enable only on the device so that DisplayManagerFontTest passes.
+ if (base::SysInfo::IsRunningOnChromeOS())
+ DisplayInfo::SetUse125DSFForUIScaling(true);
+
change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS();
#endif
gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE,
}
DisplayManager::~DisplayManager() {
+#if defined(OS_CHROMEOS)
+ // Reset the font params.
+ gfx::SetFontRenderParamsDeviceScaleFactor(1.0f);
+#endif
}
// static
std::vector<float> DisplayManager::GetScalesForDisplay(
const DisplayInfo& info) {
+
+#define ASSIGN_ARRAY(v, a) v.assign(a, a + arraysize(a))
+
std::vector<float> ret;
if (info.device_scale_factor() == 2.0f) {
- ret.assign(kUIScalesFor2x, kUIScalesFor2x + arraysize(kUIScalesFor2x));
+ ASSIGN_ARRAY(ret, kUIScalesFor2x);
+ return ret;
+ } else if (info.device_scale_factor() == 1.25f) {
+ ASSIGN_ARRAY(ret, kUIScalesFor1_25x);
return ret;
}
switch (info.bounds_in_native().width()) {
case 1280:
- ret.assign(kUIScalesFor1280,
- kUIScalesFor1280 + arraysize(kUIScalesFor1280));
+ ASSIGN_ARRAY(ret, kUIScalesFor1280);
break;
case 1366:
- ret.assign(kUIScalesFor1366,
- kUIScalesFor1366 + arraysize(kUIScalesFor1366));
+ ASSIGN_ARRAY(ret, kUIScalesFor1366);
break;
default:
- ret.assign(kUIScalesFor1280,
- kUIScalesFor1280 + arraysize(kUIScalesFor1280));
+ ASSIGN_ARRAY(ret, kUIScalesFor1280);
#if defined(OS_CHROMEOS)
if (base::SysInfo::IsRunningOnChromeOS())
NOTREACHED() << "Unknown resolution:" << info.ToString();
for (vector<string>::const_iterator iter = parts.begin();
iter != parts.end(); ++iter) {
info_list.push_back(DisplayInfo::CreateFromSpec(*iter));
+ info_list.back().set_native(true);
}
MaybeInitInternalDisplay(info_list[0].id());
if (info_list.size() > 1 &&
void DisplayManager::InitDefaultDisplay() {
DisplayInfoList info_list;
info_list.push_back(DisplayInfo::CreateFromSpec(std::string()));
+ info_list.back().set_native(true);
MaybeInitInternalDisplay(info_list[0].id());
OnNativeDisplaysChanged(info_list);
}
+void DisplayManager::InitFontParams() {
+#if defined(OS_CHROMEOS)
+ if (!HasInternalDisplay())
+ return;
+ const DisplayInfo& display_info =
+ GetDisplayInfo(gfx::Display::InternalDisplayId());
+ gfx::SetFontRenderParamsDeviceScaleFactor(
+ display_info.GetEffectiveDeviceScaleFactor());
+#endif // OS_CHROMEOS
+}
+
// static
void DisplayManager::UpdateDisplayBoundsForLayoutById(
const DisplayLayout& layout,
// Primary's bounds stay the same. Just notify bounds change
// on the secondary.
- screen_ash_->NotifyBoundsChanged(
- ScreenUtil::GetSecondaryDisplay());
+ screen_ash_->NotifyMetricsChanged(
+ ScreenUtil::GetSecondaryDisplay(),
+ gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS |
+ gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
if (delegate_)
delegate_->PostDisplayConfigurationChange();
}
display_info_list.push_back(info);
}
AddMirrorDisplayInfoIfAny(&display_info_list);
- if (virtual_keyboard_root_window_enabled() &&
- display_id == non_desktop_display_.id()) {
- DisplayInfo info = GetDisplayInfo(display_id);
- info.set_rotation(rotation);
- display_info_list.push_back(info);
- }
UpdateDisplays(display_info_list);
}
return;
}
+ // TODO(mukai): merge this implementation into SetDisplayMode().
DisplayInfoList display_info_list;
for (DisplayList::const_iterator iter = displays_.begin();
iter != displays_.end(); ++iter) {
if (gfx::Display::InternalDisplayId() == display_id)
return;
const DisplayInfo& display_info = GetDisplayInfo(display_id);
- const std::vector<Resolution>& resolutions = display_info.resolutions();
- DCHECK_NE(0u, resolutions.size());
- std::vector<Resolution>::const_iterator iter =
- std::find_if(resolutions.begin(),
- resolutions.end(),
- ResolutionMatcher(resolution));
- if (iter == resolutions.end()) {
+ const std::vector<DisplayMode>& modes = display_info.display_modes();
+ DCHECK_NE(0u, modes.size());
+ DisplayMode target_mode;
+ target_mode.size = resolution;
+ std::vector<DisplayMode>::const_iterator iter =
+ std::find_if(modes.begin(), modes.end(), DisplayModeMatcher(target_mode));
+ if (iter == modes.end()) {
LOG(WARNING) << "Unsupported resolution was requested:"
<< resolution.ToString();
return;
- } else if (iter == resolutions.begin()) {
- // The best resolution was set, so forget it.
- resolutions_.erase(display_id);
- } else {
- resolutions_[display_id] = resolution;
}
-#if defined(OS_CHROMEOS) && defined(USE_X11)
+ display_modes_[display_id] = *iter;
+#if defined(OS_CHROMEOS)
if (base::SysInfo::IsRunningOnChromeOS())
- Shell::GetInstance()->output_configurator()->ScheduleConfigureOutputs();
+ Shell::GetInstance()->display_configurator()->OnConfigurationChanged();
+#endif
+}
+
+bool DisplayManager::SetDisplayMode(int64 display_id,
+ const DisplayMode& display_mode) {
+ if (IsInternalDisplayId(display_id)) {
+ SetDisplayUIScale(display_id, display_mode.ui_scale);
+ return false;
+ }
+
+ DisplayInfoList display_info_list;
+ bool display_property_changed = false;
+ bool resolution_changed = false;
+ for (DisplayList::const_iterator iter = displays_.begin();
+ iter != displays_.end(); ++iter) {
+ DisplayInfo info = GetDisplayInfo(iter->id());
+ if (info.id() == display_id) {
+ const std::vector<DisplayMode>& modes = info.display_modes();
+ std::vector<DisplayMode>::const_iterator iter =
+ std::find_if(modes.begin(),
+ modes.end(),
+ DisplayModeMatcher(display_mode));
+ if (iter == modes.end()) {
+ LOG(WARNING) << "Unsupported resolution was requested:"
+ << display_mode.size.ToString();
+ return false;
+ }
+ display_modes_[display_id] = *iter;
+ if (info.bounds_in_native().size() != display_mode.size)
+ resolution_changed = true;
+ if (info.device_scale_factor() != display_mode.device_scale_factor) {
+ info.set_device_scale_factor(display_mode.device_scale_factor);
+ display_property_changed = true;
+ }
+ }
+ display_info_list.push_back(info);
+ }
+ if (display_property_changed) {
+ AddMirrorDisplayInfoIfAny(&display_info_list);
+ UpdateDisplays(display_info_list);
+ }
+#if defined(OS_CHROMEOS)
+ if (resolution_changed && base::SysInfo::IsRunningOnChromeOS())
+ Shell::GetInstance()->display_configurator()->OnConfigurationChanged();
#endif
+ return resolution_changed;
}
void DisplayManager::RegisterDisplayProperty(
gfx::Display::Rotation rotation,
float ui_scale,
const gfx::Insets* overscan_insets,
- const gfx::Size& resolution_in_pixels) {
- if (display_info_.find(display_id) == display_info_.end()) {
- display_info_[display_id] =
- DisplayInfo(display_id, std::string(""), false);
- }
+ const gfx::Size& resolution_in_pixels,
+ float device_scale_factor,
+ ui::ColorCalibrationProfile color_profile) {
+ if (display_info_.find(display_id) == display_info_.end())
+ display_info_[display_id] = DisplayInfo(display_id, std::string(), false);
display_info_[display_id].set_rotation(rotation);
+ display_info_[display_id].SetColorProfile(color_profile);
// Just in case the preference file was corrupted.
+ // TODO(mukai): register |display_modes_| here as well, so the lookup for the
+ // default mode in GetActiveModeForDisplayId() gets much simpler.
if (0.5f <= ui_scale && ui_scale <= 2.0f)
display_info_[display_id].set_configured_ui_scale(ui_scale);
if (overscan_insets)
display_info_[display_id].SetOverscanInsets(*overscan_insets);
- if (!resolution_in_pixels.IsEmpty())
- resolutions_[display_id] = resolution_in_pixels;
+ if (!resolution_in_pixels.IsEmpty()) {
+ DCHECK(!IsInternalDisplayId(display_id));
+ // Default refresh rate, until OnNativeDisplaysChanged() updates us with the
+ // actual display info, is 60 Hz.
+ DisplayMode mode(resolution_in_pixels, 60.0f, false, false);
+ mode.device_scale_factor = device_scale_factor;
+ display_modes_[display_id] = mode;
+ }
}
-bool DisplayManager::GetSelectedResolutionForDisplayId(
- int64 id,
- gfx::Size* resolution_out) const {
- std::map<int64, gfx::Size>::const_iterator iter =
- resolutions_.find(id);
- if (iter == resolutions_.end())
+DisplayMode DisplayManager::GetActiveModeForDisplayId(int64 display_id) const {
+ DisplayMode selected_mode;
+ if (GetSelectedModeForDisplayId(display_id, &selected_mode))
+ return selected_mode;
+
+ // If 'selected' mode is empty, it should return the default mode. This means
+ // the native mode for the external display. Unfortunately this is not true
+ // for the internal display because restoring UI-scale doesn't register the
+ // restored mode to |display_mode_|, so it needs to look up the mode whose
+ // UI-scale value matches. See the TODO in RegisterDisplayProperty().
+ const DisplayInfo& info = GetDisplayInfo(display_id);
+ const std::vector<DisplayMode>& display_modes = info.display_modes();
+
+ if (IsInternalDisplayId(display_id)) {
+ for (size_t i = 0; i < display_modes.size(); ++i) {
+ if (info.configured_ui_scale() == display_modes[i].ui_scale)
+ return display_modes[i];
+ }
+ } else {
+ for (size_t i = 0; i < display_modes.size(); ++i) {
+ if (display_modes[i].native)
+ return display_modes[i];
+ }
+ }
+ return selected_mode;
+}
+
+void DisplayManager::RegisterDisplayRotationProperties(bool rotation_lock,
+ gfx::Display::Rotation rotation) {
+ if (delegate_)
+ delegate_->PreDisplayConfigurationChange(false);
+ registered_internal_display_rotation_lock_ = rotation_lock;
+ registered_internal_display_rotation_ = rotation;
+ if (delegate_)
+ delegate_->PostDisplayConfigurationChange();
+}
+
+bool DisplayManager::GetSelectedModeForDisplayId(int64 id,
+ DisplayMode* mode_out) const {
+ std::map<int64, DisplayMode>::const_iterator iter = display_modes_.find(id);
+ if (iter == display_modes_.end())
return false;
- *resolution_out = iter->second;
+ *mode_out = iter->second;
return true;
}
it->second.overscan_insets_in_dip() : gfx::Insets();
}
+void DisplayManager::SetColorCalibrationProfile(
+ int64 display_id,
+ ui::ColorCalibrationProfile profile) {
+#if defined(OS_CHROMEOS)
+ if (!display_info_[display_id].IsColorProfileAvailable(profile))
+ return;
+
+ if (delegate_)
+ delegate_->PreDisplayConfigurationChange(false);
+ // Just sets color profile if it's not running on ChromeOS (like tests).
+ if (!base::SysInfo::IsRunningOnChromeOS() ||
+ Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile(
+ display_id, profile)) {
+ display_info_[display_id].SetColorProfile(profile);
+ UMA_HISTOGRAM_ENUMERATION(
+ "ChromeOS.Display.ColorProfile", profile, ui::NUM_COLOR_PROFILES);
+ }
+ if (delegate_)
+ delegate_->PostDisplayConfigurationChange();
+#endif
+}
+
void DisplayManager::OnNativeDisplaysChanged(
const std::vector<DisplayInfo>& updated_displays) {
if (updated_displays.empty()) {
- VLOG(1) << "OnNativeDisplayChanged(0): # of current displays="
+ VLOG(1) << "OnNativeDisplaysChanged(0): # of current displays="
<< displays_.size();
// If the device is booted without display, or chrome is started
// without --ash-host-window-bounds on linux desktop, use the
new_display_info_list.push_back(*iter);
}
- const gfx::Size& resolution = iter->bounds_in_native().size();
- const std::vector<Resolution>& resolutions = iter->resolutions();
+ DisplayMode new_mode;
+ new_mode.size = iter->bounds_in_native().size();
+ new_mode.device_scale_factor = iter->device_scale_factor();
+ new_mode.ui_scale = iter->configured_ui_scale();
+ const std::vector<DisplayMode>& display_modes = iter->display_modes();
// This is empty the displays are initialized from InitFromCommandLine.
- if (!resolutions.size())
+ if (!display_modes.size())
continue;
- std::vector<Resolution>::const_iterator resolution_iter =
- std::find_if(resolutions.begin(),
- resolutions.end(),
- ResolutionMatcher(resolution));
+ std::vector<DisplayMode>::const_iterator display_modes_iter =
+ std::find_if(display_modes.begin(),
+ display_modes.end(),
+ DisplayModeMatcher(new_mode));
// Update the actual resolution selected as the resolution request may fail.
- if (resolution_iter == resolutions.begin())
- resolutions_.erase(iter->id());
- else if (resolutions_.find(iter->id()) != resolutions_.end())
- resolutions_[iter->id()] = resolution;
+ if (display_modes_iter == display_modes.end())
+ display_modes_.erase(iter->id());
+ else if (display_modes_.find(iter->id()) != display_modes_.end())
+ display_modes_[iter->id()] = *display_modes_iter;
}
if (HasInternalDisplay() &&
!internal_display_connected &&
void DisplayManager::UpdateDisplays(
const std::vector<DisplayInfo>& updated_display_info_list) {
#if defined(OS_WIN)
- if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
- DCHECK_EQ(1u, updated_display_info_list.size()) <<
- "Multiple display test does not work on Win8 bots. Please "
- "skip (don't disable) the test using SupportsMultipleDisplays()";
- }
+ DCHECK_EQ(1u, updated_display_info_list.size()) <<
+ ": Multiple display test does not work on Windows bots. Please "
+ "skip (don't disable) the test using SupportsMultipleDisplays()";
#endif
DisplayInfoList new_display_info_list = updated_display_info_list;
new_display_info_list.end(),
DisplayInfoSortFunctor());
DisplayList removed_displays;
- std::vector<size_t> changed_display_indices;
+ std::map<size_t, uint32_t> display_changes;
std::vector<size_t> added_display_indices;
DisplayList::iterator curr_iter = displays_.begin();
non_desktop_display_ =
CreateDisplayFromDisplayInfoById(non_desktop_display_id);
++new_info_iter;
- // Remove existing external dispaly if it is going to be used as
+ // Remove existing external display if it is going to be used as
// non desktop.
if (curr_iter != displays_.end() &&
curr_iter->id() == non_desktop_display_id) {
CreateDisplayFromDisplayInfoById(new_info_iter->id());
const DisplayInfo& new_display_info = GetDisplayInfo(new_display.id());
- bool host_window_bounds_changed =
- current_display_info.bounds_in_native() !=
- new_display_info.bounds_in_native();
+ uint32_t metrics = gfx::DisplayObserver::DISPLAY_METRIC_NONE;
- if (force_bounds_changed_ ||
- host_window_bounds_changed ||
- (current_display.device_scale_factor() !=
- new_display.device_scale_factor()) ||
+ // At that point the new Display objects we have are not entirely updated,
+ // they are missing the translation related to the Display disposition in
+ // the layout.
+ // Using display.bounds() and display.work_area() would fail most of the
+ // time.
+ if (force_bounds_changed_ || (current_display_info.bounds_in_native() !=
+ new_display_info.bounds_in_native()) ||
(current_display_info.size_in_pixel() !=
- new_display.GetSizeInPixel()) ||
- (current_display.rotation() != new_display.rotation())) {
+ new_display.GetSizeInPixel())) {
+ metrics |= gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS |
+ gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA;
+ }
+
+ if (current_display.device_scale_factor() !=
+ new_display.device_scale_factor()) {
+ metrics |= gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
+ }
+
+ if (current_display.rotation() != new_display.rotation())
+ metrics |= gfx::DisplayObserver::DISPLAY_METRIC_ROTATION;
- changed_display_indices.push_back(new_displays.size());
+ if (metrics != gfx::DisplayObserver::DISPLAY_METRIC_NONE) {
+ display_changes.insert(
+ std::pair<size_t, uint32_t>(new_displays.size(), metrics));
}
new_display.UpdateWorkAreaFromInsets(current_display.GetWorkAreaInsets());
scoped_ptr<NonDesktopDisplayUpdater> non_desktop_display_updater(
new NonDesktopDisplayUpdater(this, delegate_));
- // Do not update |displays_| if there's nothing to be updated. Without this,
- // it will not update the display layout, which causes the bug
- // http://crbug.com/155948.
- if (changed_display_indices.empty() && added_display_indices.empty() &&
- removed_displays.empty()) {
- return;
- }
// Clear focus if the display has been removed, but don't clear focus if
// the destkop has been moved from one display to another
// (mirror -> docked, docked -> single internal).
if (delegate_)
delegate_->PreDisplayConfigurationChange(clear_focus);
+ // Do not update |displays_| if there's nothing to be updated. Without this,
+ // it will not update the display layout, which causes the bug
+ // http://crbug.com/155948.
+ if (display_changes.empty() && added_display_indices.empty() &&
+ removed_displays.empty()) {
+ // When changing from software mirroring mode to sinlge display mode, it
+ // is possible there is no need to update |displays_| and we early out
+ // here. But we still want to run the PostDisplayConfigurationChange()
+ // cause there are some clients need to act on this, e.g.
+ // TouchTransformerController needs to adjust the TouchTransformer when
+ // switching from dual displays to single display.
+ if (delegate_)
+ delegate_->PostDisplayConfigurationChange();
+ return;
+ }
+
size_t updated_index;
if (UpdateSecondaryDisplayBoundsForLayout(&new_displays, &updated_index) &&
std::find(added_display_indices.begin(),
added_display_indices.end(),
- updated_index) == added_display_indices.end() &&
- std::find(changed_display_indices.begin(),
- changed_display_indices.end(),
- updated_index) == changed_display_indices.end()) {
- changed_display_indices.push_back(updated_index);
+ updated_index) == added_display_indices.end()) {
+ uint32_t metrics = gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS |
+ gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA;
+ if (display_changes.find(updated_index) != display_changes.end())
+ metrics |= display_changes[updated_index];
+
+ display_changes[updated_index] = metrics;
}
displays_ = new_displays;
// it can mirror the display newly added. This can happen when switching
// from dock mode to software mirror mode.
non_desktop_display_updater.reset();
- for (std::vector<size_t>::iterator iter = changed_display_indices.begin();
- iter != changed_display_indices.end(); ++iter) {
- screen_ash_->NotifyBoundsChanged(displays_[*iter]);
+ for (std::map<size_t, uint32_t>::iterator iter = display_changes.begin();
+ iter != display_changes.end();
+ ++iter) {
+ screen_ash_->NotifyMetricsChanged(displays_[iter->first], iter->second);
}
if (delegate_)
delegate_->PostDisplayConfigurationChange();
#if defined(USE_X11) && defined(OS_CHROMEOS)
- if (!changed_display_indices.empty() && base::SysInfo::IsRunningOnChromeOS())
+ if (!display_changes.empty() && base::SysInfo::IsRunningOnChromeOS())
ui::ClearX11DefaultRootWindow();
#endif
}
}
const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const {
+ DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id);
+
std::map<int64, DisplayInfo>::const_iterator iter =
display_info_.find(display_id);
CHECK(iter != display_info_.end()) << display_id;
#if defined(OS_CHROMEOS)
if (base::SysInfo::IsRunningOnChromeOS()) {
- chromeos::OutputState new_state = mirrored ?
- chromeos::STATE_DUAL_MIRROR : chromeos::STATE_DUAL_EXTENDED;
- Shell::GetInstance()->output_configurator()->SetDisplayMode(new_state);
+ ui::MultipleDisplayState new_state =
+ mirrored ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR :
+ ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED;
+ Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state);
return;
}
#endif
}
UpdateDisplays(display_info_list);
#if defined(OS_CHROMEOS)
- if (Shell::GetInstance()->output_configurator_animation()) {
- Shell::GetInstance()->output_configurator_animation()->
+ if (Shell::GetInstance()->display_configurator_animation()) {
+ Shell::GetInstance()->display_configurator_animation()->
StartFadeInAnimation();
}
#endif
#if defined(OS_CHROMEOS)
void DisplayManager::SetSoftwareMirroring(bool enabled) {
- // TODO(oshima|bshe): Support external display on the system
- // that has virtual keyboard display.
- if (second_display_mode_ == VIRTUAL_KEYBOARD)
- return;
SetSecondDisplayMode(enabled ? MIRRORING : EXTENDED);
}
+
+bool DisplayManager::SoftwareMirroringEnabled() const {
+ return software_mirroring_enabled();
+}
#endif
void DisplayManager::SetSecondDisplayMode(SecondDisplayMode mode) {
return false;
gfx::Display* display = FindDisplayForId(display_id);
display->SetSize(display_info_[display_id].size_in_pixel());
- screen_ash_->NotifyBoundsChanged(*display);
+ screen_ash_->NotifyMetricsChanged(
+ *display, gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
return true;
}
return false;
void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) {
std::map<int64, DisplayInfo>::iterator info =
display_info_.find(new_info.id());
- if (info != display_info_.end())
+ if (info != display_info_.end()) {
info->second.Copy(new_info);
- else {
+ } else {
display_info_[new_info.id()] = new_info;
display_info_[new_info.id()].set_native(false);
}
display_info_[new_info.id()].UpdateDisplaySize();
+
+ OnDisplayInfoUpdated(display_info_[new_info.id()]);
+}
+
+void DisplayManager::OnDisplayInfoUpdated(const DisplayInfo& display_info) {
+#if defined(OS_CHROMEOS)
+ ui::ColorCalibrationProfile color_profile = display_info.color_profile();
+ if (color_profile != ui::COLOR_PROFILE_STANDARD) {
+ Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile(
+ display_info.id(), color_profile);
+ }
+#endif
}
gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) {
gfx::Display new_display(display_info.id());
gfx::Rect bounds_in_native(display_info.size_in_pixel());
- float device_scale_factor = display_info.device_scale_factor();
- if (device_scale_factor == 2.0f && display_info.configured_ui_scale() == 2.0f)
- device_scale_factor = 1.0f;
+ float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor();
// Simply set the origin to (0,0). The primary display's origin is
// always (0,0) and the secondary display's bounds will be updated
(id_at_zero == first_display_id_ ||
id_at_zero == gfx::Display::InternalDisplayId()) ?
std::make_pair(id_at_zero, displays->at(1).id()) :
- std::make_pair(displays->at(1).id(), id_at_zero) ;
+ std::make_pair(displays->at(1).id(), id_at_zero);
DisplayLayout layout =
layout_store_->ComputeDisplayLayoutForDisplayIdPair(pair);
secondary_display->UpdateWorkAreaFromInsets(insets);
}
-} // namespace internal
} // namespace ash