Skip to content

Commit 9e9d13f

Browse files
authored
Revert "Gets the DPI for all awareness mode and older Windows versions (flutter#15951)"
This reverts commit d0bb4cd.
1 parent fbeef19 commit 9e9d13f

File tree

4 files changed

+72
-52
lines changed

4 files changed

+72
-52
lines changed

shell/platform/windows/win32_dpi_helper.cc

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ namespace flutter {
44

55
namespace {
66

7-
constexpr UINT kDefaultDpi = 96;
8-
97
template <typename T>
108
bool AssignProcAddress(HMODULE comBaseModule, const char* name, T*& outProc) {
119
outProc = reinterpret_cast<T*>(GetProcAddress(comBaseModule, name));
@@ -15,57 +13,60 @@ bool AssignProcAddress(HMODULE comBaseModule, const char* name, T*& outProc) {
1513
} // namespace
1614

1715
Win32DpiHelper::Win32DpiHelper() {
16+
// TODO ensure that this helper works correctly on downlevel builds.
1817
user32_module_ = LoadLibraryA("User32.dll");
1918
if (user32_module_ == nullptr) {
2019
return;
2120
}
2221

23-
if (AssignProcAddress(user32_module_, "GetDpiForWindow",
24-
get_dpi_for_window_)) {
25-
dpi_for_window_supported_ = true;
22+
if (!AssignProcAddress(user32_module_, "EnableNonClientDpiScaling",
23+
enable_non_client_dpi_scaling_)) {
2624
return;
2725
}
2826

29-
shlib_module_ = LoadLibraryA("Shcore.dll");
30-
if (shlib_module_ == nullptr) {
27+
if (!AssignProcAddress(user32_module_, "GetDpiForWindow",
28+
get_dpi_for_window_)) {
3129
return;
3230
}
3331

34-
if (AssignProcAddress(shlib_module_, "GetDpiForMonitor",
35-
get_dpi_for_monitor_) &&
36-
AssignProcAddress(user32_module_, "MonitorFromWindow",
37-
monitor_from_window_)) {
38-
dpi_for_monitor_supported_ = true;
32+
if (!AssignProcAddress(user32_module_, "SetProcessDpiAwarenessContext",
33+
set_process_dpi_awareness_context_)) {
34+
return;
3935
}
36+
37+
permonitorv2_supported_ = true;
4038
}
4139

4240
Win32DpiHelper::~Win32DpiHelper() {
4341
if (user32_module_ != nullptr) {
4442
FreeLibrary(user32_module_);
4543
}
46-
if (shlib_module_ != nullptr) {
47-
FreeLibrary(shlib_module_);
48-
}
4944
}
5045

51-
UINT Win32DpiHelper::GetDpi(HWND hwnd) {
52-
// GetDpiForWindow returns the DPI for any awareness mode. If not available,
53-
// fallback to a per monitor, system, or default DPI.
54-
if (dpi_for_window_supported_) {
55-
return get_dpi_for_window_(hwnd);
46+
bool Win32DpiHelper::IsPerMonitorV2Available() {
47+
return permonitorv2_supported_;
48+
}
49+
50+
BOOL Win32DpiHelper::EnableNonClientDpiScaling(HWND hwnd) {
51+
if (!permonitorv2_supported_) {
52+
return false;
5653
}
54+
return enable_non_client_dpi_scaling_(hwnd);
55+
}
5756

58-
if (dpi_for_monitor_supported_) {
59-
HMONITOR monitor = monitor_from_window_(hwnd, MONITOR_DEFAULTTONEAREST);
60-
UINT dpi_x = 0, dpi_y = 0;
61-
HRESULT result =
62-
get_dpi_for_monitor_(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y);
63-
return SUCCEEDED(result) ? dpi_x : kDefaultDpi;
57+
UINT Win32DpiHelper::GetDpiForWindow(HWND hwnd) {
58+
if (!permonitorv2_supported_) {
59+
return false;
6460
}
61+
return get_dpi_for_window_(hwnd);
62+
}
6563

66-
HDC hdc = GetDC(hwnd);
67-
UINT dpi = GetDeviceCaps(hdc, LOGPIXELSX);
68-
ReleaseDC(hwnd, hdc);
69-
return dpi;
64+
BOOL Win32DpiHelper::SetProcessDpiAwarenessContext(
65+
DPI_AWARENESS_CONTEXT context) {
66+
if (!permonitorv2_supported_) {
67+
return false;
68+
}
69+
return set_process_dpi_awareness_context_(context);
7070
}
71+
7172
} // namespace flutter

shell/platform/windows/win32_dpi_helper.h

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,38 @@
1010

1111
namespace flutter {
1212

13-
/// A helper class for abstracting various Windows DPI related functions across
14-
/// Windows OS versions.
13+
// A helper class for abstracting various Windows DPI related functions across
14+
// Windows OS versions.
1515
class Win32DpiHelper {
1616
public:
1717
Win32DpiHelper();
1818

1919
~Win32DpiHelper();
2020

21-
/// Returns the current DPI. Supports all DPI awareness modes, and is backward
22-
/// compatible down to Windows Vista.
23-
UINT GetDpi(HWND);
21+
// Check if Windows Per Monitor V2 DPI scaling functionality is available on
22+
// current system.
23+
bool IsPerMonitorV2Available();
24+
25+
// Wrapper for OS functionality to turn on automatic window non-client scaling
26+
BOOL EnableNonClientDpiScaling(HWND);
27+
28+
// Wrapper for OS functionality to return the DPI for |HWND|
29+
UINT GetDpiForWindow(HWND);
30+
31+
// Sets the current process to a specified DPI awareness context.
32+
BOOL SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT);
2433

2534
private:
35+
using EnableNonClientDpiScaling_ = BOOL __stdcall(HWND);
2636
using GetDpiForWindow_ = UINT __stdcall(HWND);
27-
using GetDpiForMonitor_ = HRESULT __stdcall(HMONITOR hmonitor,
28-
MONITOR_DPI_TYPE dpiType,
29-
UINT* dpiX,
30-
UINT* dpiY);
31-
using MonitorFromWindow_ = HMONITOR __stdcall(HWND hwnd, DWORD dwFlags);
37+
using SetProcessDpiAwarenessContext_ = BOOL __stdcall(DPI_AWARENESS_CONTEXT);
3238

39+
EnableNonClientDpiScaling_* enable_non_client_dpi_scaling_ = nullptr;
3340
GetDpiForWindow_* get_dpi_for_window_ = nullptr;
34-
GetDpiForMonitor_* get_dpi_for_monitor_ = nullptr;
35-
MonitorFromWindow_* monitor_from_window_ = nullptr;
41+
SetProcessDpiAwarenessContext_* set_process_dpi_awareness_context_ = nullptr;
3642

3743
HMODULE user32_module_ = nullptr;
38-
HMODULE shlib_module_ = nullptr;
39-
bool dpi_for_window_supported_ = false;
40-
bool dpi_for_monitor_supported_ = false;
44+
bool permonitorv2_supported_ = false;
4145
};
4246

4347
} // namespace flutter

shell/platform/windows/win32_window.cc

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,16 @@
66

77
namespace flutter {
88

9-
Win32Window::Win32Window() {}
10-
9+
Win32Window::Win32Window() {
10+
// Assume Windows 10 1703 or greater for DPI handling. When running on a
11+
// older release of Windows where this context doesn't exist, DPI calls will
12+
// fail and Flutter rendering will be impacted until this is fixed.
13+
// To handle downlevel correctly, dpi_helper must use the most recent DPI
14+
// context available should be used: Windows 1703: Per-Monitor V2, 8.1:
15+
// Per-Monitor V1, Windows 7: System See
16+
// https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
17+
// for more information.
18+
}
1119
Win32Window::~Win32Window() {
1220
Destroy();
1321
}
@@ -18,7 +26,7 @@ void Win32Window::InitializeChild(const char* title,
1826
Destroy();
1927
std::wstring converted_title = NarrowToWide(title);
2028

21-
WNDCLASS window_class = RegisterWindowClass(converted_title);
29+
WNDCLASS window_class = ResgisterWindowClass(converted_title);
2230

2331
auto* result = CreateWindowEx(
2432
0, window_class.lpszClassName, converted_title.c_str(),
@@ -46,7 +54,7 @@ std::wstring Win32Window::NarrowToWide(const char* source) {
4654
return wideTitle;
4755
}
4856

49-
WNDCLASS Win32Window::RegisterWindowClass(std::wstring& title) {
57+
WNDCLASS Win32Window::ResgisterWindowClass(std::wstring& title) {
5058
window_class_name_ = title;
5159

5260
WNDCLASS window_class{};
@@ -74,7 +82,14 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window,
7482
reinterpret_cast<LONG_PTR>(cs->lpCreateParams));
7583

7684
auto that = static_cast<Win32Window*>(cs->lpCreateParams);
77-
that->current_dpi_ = that->dpi_helper_->GetDpi(window);
85+
86+
// Since the application is running in Per-monitor V2 mode, turn on
87+
// automatic titlebar scaling
88+
BOOL result = that->dpi_helper_->EnableNonClientDpiScaling(window);
89+
if (result != TRUE) {
90+
OutputDebugString(L"Failed to enable non-client area autoscaling");
91+
}
92+
that->current_dpi_ = that->dpi_helper_->GetDpiForWindow(window);
7893
that->window_handle_ = window;
7994
} else if (Win32Window* that = GetThisFromHandle(window)) {
8095
return that->MessageHandler(window, message, wparam, lparam);
@@ -267,7 +282,7 @@ Win32Window::HandleDpiChange(HWND hwnd,
267282
// The DPI is only passed for DPI change messages on top level windows,
268283
// hence call function to get DPI if needed.
269284
if (uDpi == 0) {
270-
uDpi = dpi_helper_->GetDpi(hwnd);
285+
uDpi = dpi_helper_->GetDpiForWindow(hwnd);
271286
}
272287
current_dpi_ = uDpi;
273288
window->OnDpiScale(uDpi);

shell/platform/windows/win32_window.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Win32Window {
5757

5858
// Registers a window class with default style attributes, cursor and
5959
// icon.
60-
WNDCLASS RegisterWindowClass(std::wstring& title);
60+
WNDCLASS ResgisterWindowClass(std::wstring& title);
6161

6262
// OS callback called by message pump. Handles the WM_NCCREATE message which
6363
// is passed when the non-client area is being created and enables automatic

0 commit comments

Comments
 (0)