Commit b479d9f7 authored by robliao's avatar robliao Committed by Commit bot
Browse files

Prepare ScreenWin To Use Per-Monitor DPI

This allows ScreenWin to switch between the global DPI and the per monitor DPI
for platforms where per monitor DPI is availble.

BUG=426656

Review-Url: https://codereview.chromium.org/2098993002
Cr-Commit-Position: refs/heads/master@{#402325}
parent d83f822f
......@@ -16,6 +16,7 @@
#include <roapi.h>
#include <sddl.h>
#include <setupapi.h>
#include <shellscalingapi.h>
#include <shlwapi.h>
#include <signal.h>
#include <stddef.h>
......@@ -597,5 +598,30 @@ void DisableFlicks(HWND hwnd) {
TABLET_DISABLE_FLICKFALLBACKKEYS));
}
bool IsProcessPerMonitorDpiAware() {
enum class PerMonitorDpiAware {
UNKNOWN = 0,
PER_MONITOR_DPI_UNAWARE,
PER_MONITOR_DPI_AWARE,
};
static PerMonitorDpiAware per_monitor_dpi_aware = PerMonitorDpiAware::UNKNOWN;
if (per_monitor_dpi_aware == PerMonitorDpiAware::UNKNOWN) {
per_monitor_dpi_aware = PerMonitorDpiAware::PER_MONITOR_DPI_UNAWARE;
HMODULE shcore_dll = ::LoadLibrary(L"shcore.dll");
if (shcore_dll) {
auto get_process_dpi_awareness_func =
reinterpret_cast<decltype(::GetProcessDpiAwareness)*>(
::GetProcAddress(shcore_dll, "GetProcessDpiAwareness"));
if (get_process_dpi_awareness_func) {
PROCESS_DPI_AWARENESS awareness;
if (SUCCEEDED(get_process_dpi_awareness_func(nullptr, &awareness)) &&
awareness == PROCESS_PER_MONITOR_DPI_AWARE)
per_monitor_dpi_aware = PerMonitorDpiAware::PER_MONITOR_DPI_AWARE;
}
}
}
return per_monitor_dpi_aware == PerMonitorDpiAware::PER_MONITOR_DPI_AWARE;
}
} // namespace win
} // namespace base
......@@ -176,6 +176,9 @@ BASE_EXPORT bool GetLoadedModulesSnapshot(HANDLE process,
BASE_EXPORT void EnableFlicks(HWND hwnd);
BASE_EXPORT void DisableFlicks(HWND hwnd);
// Returns true if the process is per monitor DPI aware.
BASE_EXPORT bool IsProcessPerMonitorDpiAware();
} // namespace win
} // namespace base
......
......@@ -38,7 +38,7 @@ gfx::Size GetDPI() {
float GetUnforcedDeviceScaleFactor() {
return g_device_scale_factor
? g_device_scale_factor
: static_cast<float>(GetDPI().width()) / kDefaultDPI;
: GetScalingFactorFromDPI(GetDPI().width());
}
} // namespace
......@@ -59,6 +59,10 @@ int GetDPIFromScalingFactor(float device_scaling_factor) {
return kDefaultDPI * device_scaling_factor;
}
float GetScalingFactorFromDPI(int dpi) {
return static_cast<float>(dpi) / kDefaultDPI;
}
int GetSystemMetricsInDIP(int metric) {
// The system metrics always reflect the system DPI, not whatever scale we've
// forced or decided to use.
......
......@@ -26,6 +26,9 @@ DISPLAY_EXPORT float GetDPIScale();
// Returns the equivalent DPI for |device_scaling_factor|.
DISPLAY_EXPORT int GetDPIFromScalingFactor(float device_scaling_factor);
// Returns the equivalent scaling factor for |dpi|.
DISPLAY_EXPORT float GetScalingFactorFromDPI(int dpi);
// Win32's GetSystemMetrics uses pixel measures. This function calls
// GetSystemMetrics for the given |metric|, then converts the result to DIP.
DISPLAY_EXPORT int GetSystemMetricsInDIP(int metric);
......
......@@ -5,11 +5,13 @@
#include "ui/display/win/screen_win.h"
#include <windows.h>
#include <shellscalingapi.h>
#include <algorithm>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/win/win_util.h"
#include "ui/display/display.h"
#include "ui/display/manager/display_layout.h"
#include "ui/display/manager/display_layout_builder.h"
......@@ -30,6 +32,31 @@ namespace {
// resolved with Desktop Aura and WindowTreeHost.
ScreenWin* g_screen_win_instance = nullptr;
float GetMonitorScaleFactor(HMONITOR monitor) {
DCHECK(monitor);
if (base::win::IsProcessPerMonitorDpiAware()) {
static auto get_dpi_for_monitor_func = [](){
using GetDpiForMonitorPtr = decltype(::GetDpiForMonitor)*;
HMODULE shcore_dll = ::LoadLibrary(L"shcore.dll");
if (shcore_dll) {
return reinterpret_cast<GetDpiForMonitorPtr>(
::GetProcAddress(shcore_dll, "GetDpiForMonitor"));
}
return static_cast<GetDpiForMonitorPtr>(nullptr);
}();
UINT dpi_x;
UINT dpi_y;
if (get_dpi_for_monitor_func &&
SUCCEEDED(get_dpi_for_monitor_func(monitor, MDT_EFFECTIVE_DPI,
&dpi_x, &dpi_y))) {
DCHECK_EQ(dpi_x, dpi_y);
return GetScalingFactorFromDPI(dpi_x);
}
}
return GetDPIScale();
}
std::vector<DisplayInfo> FindAndRemoveTouchingDisplayInfos(
const DisplayInfo& ref_display_info,
std::vector<DisplayInfo>* display_infos) {
......@@ -144,10 +171,8 @@ BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor,
std::vector<DisplayInfo>* display_infos =
reinterpret_cast<std::vector<DisplayInfo>*>(data);
DCHECK(display_infos);
// TODO(robliao): When ready, replace the GetDPIScale with GetDpiForMonitor
// to get the actual DPI for the HMONITOR.
display_infos->push_back(DisplayInfo(MonitorInfoFromHMONITOR(monitor),
GetDPIScale()));
GetMonitorScaleFactor(monitor)));
return TRUE;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment