Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Unified Diff: chrome/browser/ui/webui/options/chromeos/display_options_handler.cc

Issue 417113012: Introduce user customization of external HighDPI mode for 4K monitor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());

Powered by Google App Engine
This is Rietveld 408576698