| Index: chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
|
| diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
|
| index 52a5e238d54b84717626fbb058d3b0412eea3455..b0aad022b86cc09783d45c2543b05ed7cd631dfe 100644
|
| --- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
|
| +++ b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
|
| @@ -54,10 +54,37 @@ int64 GetDisplayId(const base::ListValue* args) {
|
| return display_id;
|
| }
|
|
|
| -bool CompareDisplayMode(ash::DisplayMode d1, ash::DisplayMode d2) {
|
| - if (d1.size.GetArea() == d2.size.GetArea())
|
| - return d1.refresh_rate < d2.refresh_rate;
|
| - return d1.size.GetArea() < d2.size.GetArea();
|
| +bool CompareResolution(base::Value* v1, base::Value* v2) {
|
| + base::DictionaryValue* r1 = NULL;
|
| + base::DictionaryValue* r2 = NULL;
|
| + if (!v1->GetAsDictionary(&r1))
|
| + return true;
|
| + if (!v2->GetAsDictionary(&r2))
|
| + return false;
|
| + int width1 = 0, height1 = 0, width2 = 0, height2 = 0;
|
| + if (!r1->GetInteger("width", &width1) || !r1->GetInteger("height", &height1))
|
| + return true;
|
| + if (!r2->GetInteger("width", &width2) || !r2->GetInteger("height", &height2))
|
| + return false;
|
| +
|
| + if (width1 * height1 != width2 * height2)
|
| + return width1 * height1 < width2 * height2;
|
| +
|
| + double dsf1 = 0, dsf2 = 0;
|
| + if (!r1->GetDouble("deviceScaleFactor", &dsf1))
|
| + return true;
|
| + if (!r2->GetDouble("deviceScaleFactor", &dsf2))
|
| + return false;
|
| + return dsf1 < dsf2;
|
| +
|
| + double refresh1 = 0, refresh2 = 0;
|
| + if (!r1->GetDouble("refreshRate", &refresh1))
|
| + return true;
|
| + if (!r2->GetDouble("refreshRate", &refresh2))
|
| + return false;
|
| + // Higher refresh rate should appear first.
|
| + if (refresh1 != refresh2)
|
| + return refresh1 > refresh2;
|
| }
|
|
|
| base::string16 GetColorProfileName(ui::ColorCalibrationProfile profile) {
|
| @@ -82,6 +109,102 @@ base::string16 GetColorProfileName(ui::ColorCalibrationProfile profile) {
|
| return base::string16();
|
| }
|
|
|
| +base::ListValue* CreateResolutionsForUIScale(
|
| + const ash::DisplayInfo& display_info) {
|
| + std::vector<float> ui_scales =
|
| + DisplayManager::GetScalesForDisplay(display_info);
|
| + gfx::SizeF base_size = display_info.bounds_in_native().size();
|
| + base::ListValue* result = new base::ListValue();
|
| +
|
| + base_size.Scale(1.0f / display_info.device_scale_factor());
|
| + if (display_info.rotation() == gfx::Display::ROTATE_90 ||
|
| + display_info.rotation() == gfx::Display::ROTATE_270) {
|
| + float tmp = base_size.width();
|
| + base_size.set_width(base_size.height());
|
| + base_size.set_height(tmp);
|
| + }
|
| + for (size_t i = 0; i < ui_scales.size(); ++i) {
|
| + base::DictionaryValue* resolution_info = new base::DictionaryValue();
|
| + resolution_info->SetDouble("scale", ui_scales[i]);
|
| + if (ui_scales[i] == 1.0f)
|
| + resolution_info->SetBoolean("isBest", true);
|
| + resolution_info->SetBoolean(
|
| + "selected", display_info.configured_ui_scale() == ui_scales[i]);
|
| + resolution_info->SetInteger("width", base_size.width() * ui_scales[i]);
|
| + resolution_info->SetInteger("height", base_size.height() * ui_scales[i]);
|
| + result->Append(resolution_info);
|
| + }
|
| +
|
| + return result;
|
| +}
|
| +
|
| +base::ListValue* CreateResolutionsForExternalDisplay(
|
| + const ash::DisplayInfo& display_info) {
|
| + base::ListValue* result = new base::ListValue();
|
| + gfx::Size current_size = display_info.bounds_in_native().size();
|
| +
|
| + const std::vector<ash::DisplayMode>& display_modes =
|
| + display_info.display_modes();
|
| + base::DictionaryValue* largest_resolution_info = NULL;
|
| + gfx::Size largest_resolution;
|
| + bool largest_is_selected = false;
|
| + for (size_t i = 0; i < display_modes.size(); ++i) {
|
| + base::DictionaryValue* resolution_info = new base::DictionaryValue();
|
| + gfx::Size resolution = display_modes[i].size;
|
| + // Picks the largest one as the "best", which is the last element
|
| + // because |display_modes| is sorted by its area.
|
| + if (largest_resolution.GetArea() < resolution.GetArea()) {
|
| + if (largest_resolution_info)
|
| + largest_resolution_info->SetBoolean("isBest", false);
|
| + resolution_info->SetBoolean("isBest", true);
|
| + largest_resolution_info = resolution_info;
|
| + largest_resolution = resolution;
|
| + largest_is_selected = (resolution == current_size);
|
| + }
|
| + resolution_info->SetBoolean("selected", (resolution == current_size));
|
| + resolution_info->SetInteger("width", resolution.width());
|
| + resolution_info->SetInteger("height", resolution.height());
|
| + if (display_modes[i].refresh_rate > 0.0f) {
|
| + resolution_info->SetDouble("refreshRate",
|
| + display_modes[i].refresh_rate);
|
| + }
|
| + result->Append(resolution_info);
|
| + }
|
| +
|
| + // Add other scale factors for larger external displays.
|
| + std::vector<float> device_scale_factors =
|
| + DisplayManager::GetDeviceScaleFactorsForDisplay(display_info);
|
| + if (device_scale_factors.size() > 1) {
|
| + for (size_t i = 0; i < device_scale_factors.size(); ++i) {
|
| + if (device_scale_factors[i] == 1.0f)
|
| + continue;
|
| + base::DictionaryValue* resolution_info =
|
| + largest_resolution_info->DeepCopy();
|
| + resolution_info->SetBoolean("isBest", false);
|
| + if (largest_is_selected &&
|
| + display_info.device_scale_factor() == device_scale_factors[i]) {
|
| + resolution_info->SetBoolean("selected", true);
|
| + largest_resolution_info->SetBoolean("selected", false);
|
| + } else {
|
| + resolution_info->SetBoolean("selected", false);
|
| + }
|
| + resolution_info->SetDouble(
|
| + "deviceScaleFactor", device_scale_factors[i]);
|
| + resolution_info->SetInteger(
|
| + "originalWidth", largest_resolution.width());
|
| + resolution_info->SetInteger(
|
| + "originalHeight", largest_resolution.height());
|
| + resolution_info->SetInteger(
|
| + "width", largest_resolution.width() / device_scale_factors[i]);
|
| + resolution_info->SetInteger(
|
| + "height", largest_resolution.height() / device_scale_factors[i]);
|
| + result->Append(resolution_info);
|
| + }
|
| + largest_resolution_info->SetDouble("deviceScaleFactor", 1.0);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| } // namespace
|
|
|
| DisplayOptionsHandler::DisplayOptionsHandler() {
|
| @@ -167,6 +290,10 @@ void DisplayOptionsHandler::RegisterMessages() {
|
| base::Bind(&DisplayOptionsHandler::HandleSetResolution,
|
| base::Unretained(this)));
|
| web_ui()->RegisterMessageCallback(
|
| + "setDeviceScaleFactor",
|
| + base::Bind(&DisplayOptionsHandler::HandleSetDeviceScaleFactor,
|
| + base::Unretained(this)));
|
| + web_ui()->RegisterMessageCallback(
|
| "setOrientation",
|
| base::Bind(&DisplayOptionsHandler::HandleSetOrientation,
|
| base::Unretained(this)));
|
| @@ -219,54 +346,11 @@ void DisplayOptionsHandler::SendDisplayInfo(
|
| static_cast<int>(display_info.rotation()));
|
| std::vector<ash::DisplayMode> display_modes;
|
| std::vector<float> ui_scales;
|
| - if (display.IsInternal()) {
|
| - ui_scales = DisplayManager::GetScalesForDisplay(display_info);
|
| - gfx::SizeF base_size = display_info.bounds_in_native().size();
|
| - base_size.Scale(1.0f / display_info.device_scale_factor());
|
| - if (display_info.rotation() == gfx::Display::ROTATE_90 ||
|
| - display_info.rotation() == gfx::Display::ROTATE_270) {
|
| - float tmp = base_size.width();
|
| - base_size.set_width(base_size.height());
|
| - base_size.set_height(tmp);
|
| - }
|
| - for (size_t i = 0; i < ui_scales.size(); ++i) {
|
| - gfx::SizeF new_size = base_size;
|
| - new_size.Scale(ui_scales[i]);
|
| - display_modes.push_back(ash::DisplayMode(
|
| - gfx::ToFlooredSize(new_size), -1.0f, false, false));
|
| - }
|
| - } else {
|
| - for (size_t i = 0; i < display_info.display_modes().size(); ++i)
|
| - display_modes.push_back(display_info.display_modes()[i]);
|
| - }
|
| - std::sort(display_modes.begin(), display_modes.end(), CompareDisplayMode);
|
| -
|
| - base::ListValue* js_resolutions = new base::ListValue();
|
| - gfx::Size current_size = display_info.bounds_in_native().size();
|
| - for (size_t i = 0; i < display_modes.size(); ++i) {
|
| - base::DictionaryValue* resolution_info = new base::DictionaryValue();
|
| - gfx::Size resolution = display_modes[i].size;
|
| - if (!ui_scales.empty()) {
|
| - resolution_info->SetDouble("scale", ui_scales[i]);
|
| - if (ui_scales[i] == 1.0f)
|
| - resolution_info->SetBoolean("isBest", true);
|
| - resolution_info->SetBoolean(
|
| - "selected", display_info.configured_ui_scale() == ui_scales[i]);
|
| - } else {
|
| - // Picks the largest one as the "best", which is the last element
|
| - // because |display_modes| is sorted by its area.
|
| - if (i == display_modes.size() - 1)
|
| - resolution_info->SetBoolean("isBest", true);
|
| - resolution_info->SetBoolean("selected", (resolution == current_size));
|
| - }
|
| - resolution_info->SetInteger("width", resolution.width());
|
| - resolution_info->SetInteger("height", resolution.height());
|
| - if (display_modes[i].refresh_rate > 0.0f) {
|
| - resolution_info->SetDouble("refreshRate",
|
| - display_modes[i].refresh_rate);
|
| - }
|
| - js_resolutions->Append(resolution_info);
|
| - }
|
| + base::ListValue* js_resolutions = display.IsInternal() ?
|
| + CreateResolutionsForUIScale(display_info) :
|
| + CreateResolutionsForExternalDisplay(display_info);
|
| + std::sort(js_resolutions->begin(), js_resolutions->end(),
|
| + CompareResolution);
|
| js_display->Set("resolutions", js_resolutions);
|
|
|
| js_display->SetInteger("colorProfile", display_info.color_profile());
|
| @@ -381,8 +465,6 @@ void DisplayOptionsHandler::HandleSetResolution(const base::ListValue* args) {
|
| if (display_id == gfx::Display::kInvalidDisplayID)
|
| return;
|
|
|
| - content::RecordAction(
|
| - base::UserMetricsAction("Options_DisplaySetResolution"));
|
| double width = 0.0f;
|
| double height = 0.0f;
|
| if (!args->GetDouble(1, &width) || width == 0.0f) {
|
| @@ -398,6 +480,9 @@ void DisplayOptionsHandler::HandleSetResolution(const base::ListValue* args) {
|
| GetDisplayManager()->GetDisplayInfo(display_id);
|
| gfx::Size new_resolution = gfx::ToFlooredSize(gfx::SizeF(width, height));
|
| gfx::Size old_resolution = display_info.bounds_in_native().size();
|
| + if (new_resolution == old_resolution)
|
| + return;
|
| +
|
| bool has_new_resolution = false;
|
| bool has_old_resolution = false;
|
| for (size_t i = 0; i < display_info.display_modes().size(); ++i) {
|
| @@ -418,12 +503,44 @@ void DisplayOptionsHandler::HandleSetResolution(const base::ListValue* args) {
|
| return;
|
| }
|
|
|
| + content::RecordAction(
|
| + base::UserMetricsAction("Options_DisplaySetResolution"));
|
| +
|
| + if (display_info.device_scale_factor() != 1.0f)
|
| + GetDisplayManager()->SetDisplayDeviceScaleFactor(display_id, 1.0f);
|
| +
|
| ash::Shell::GetInstance()->resolution_notification_controller()->
|
| SetDisplayResolutionAndNotify(
|
| display_id, old_resolution, new_resolution,
|
| base::Bind(&StoreDisplayPrefs));
|
| }
|
|
|
| +void DisplayOptionsHandler::HandleSetDeviceScaleFactor(
|
| + const base::ListValue* args) {
|
| + DCHECK(!args->empty());
|
| + int64 display_id = GetDisplayId(args);
|
| + if (display_id == gfx::Display::kInvalidDisplayID)
|
| + return;
|
| +
|
| + double device_scale_factor = 0.0f;
|
| + if (!args->GetDouble(1, &device_scale_factor) ||
|
| + device_scale_factor == 0.0f) {
|
| + LOG(ERROR) << "Can't find new device scale factor";
|
| + return;
|
| + }
|
| +
|
| + const ash::DisplayInfo& display_info =
|
| + GetDisplayManager()->GetDisplayInfo(display_id);
|
| + if (display_info.device_scale_factor() == device_scale_factor)
|
| + return;
|
| +
|
| + content::RecordAction(
|
| + base::UserMetricsAction("Options_DisplaySetExternalDeviceScaleFactor"));
|
| +
|
| + GetDisplayManager()->SetDisplayDeviceScaleFactor(
|
| + display_id, device_scale_factor);
|
| +}
|
| +
|
| void DisplayOptionsHandler::HandleSetOrientation(const base::ListValue* args) {
|
| DCHECK(!args->empty());
|
|
|
|
|