Skip to content

Commit 3c8a019

Browse files
committed
win32: fix window hwnd_dpi leaks HDC handles
1 parent 27e17e3 commit 3c8a019

2 files changed

Lines changed: 10 additions & 5 deletions

File tree

winit-win32/src/dpi.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::sync::Once;
55
use windows_sys::Win32::Foundation::{HWND, S_OK};
66
use windows_sys::Win32::Graphics::Gdi::{
77
GetDC, GetDeviceCaps, HMONITOR, LOGPIXELSX, MONITOR_DEFAULTTONEAREST, MonitorFromWindow,
8+
ReleaseDC,
89
};
910
use windows_sys::Win32::UI::HiDpi::{
1011
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2,
@@ -72,10 +73,6 @@ pub fn dpi_to_scale_factor(dpi: u32) -> f64 {
7273
}
7374

7475
pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 {
75-
let hdc = unsafe { GetDC(hwnd) };
76-
if hdc.is_null() {
77-
panic!("[winit] `GetDC` returned null!");
78-
}
7976
if let Some(GetDpiForWindow) = *GET_DPI_FOR_WINDOW {
8077
// We are on Windows 10 Anniversary Update (1607) or later.
8178
match unsafe { GetDpiForWindow(hwnd) } {
@@ -99,9 +96,15 @@ pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 {
9996
} else {
10097
// We are on Vista or later.
10198
if unsafe { IsProcessDPIAware() } != false.into() {
99+
let hdc = unsafe { GetDC(hwnd) };
100+
if hdc.is_null() {
101+
panic!("[winit] `GetDC` returned null!");
102+
}
102103
// If the process is DPI aware, then scaling must be handled by the application using
103104
// this DPI value.
104-
unsafe { GetDeviceCaps(hdc, LOGPIXELSX as i32) as u32 }
105+
let dpi = unsafe { GetDeviceCaps(hdc, LOGPIXELSX as i32) as u32 };
106+
unsafe { ReleaseDC(hwnd, hdc) };
107+
dpi
105108
} else {
106109
// If the process is DPI unaware, then scaling is performed by the OS; we thus return
107110
// 96 (scale factor 1.0) to prevent the window from being re-scaled by both the

winit/src/changelog/unreleased.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ changelog entry.
6262
tools such as Punto Switcher. The `WM_INPUTLANGCHANGE` message is now handled
6363
to refresh the cached keyboard layout, while still deferring to
6464
`DefWindowProc` for normal propagation.
65+
- On Windows, fix getting the window's DPI internally leaks `HDC` handles.
66+
Also only call `GetDC` when on < Windows 8.1 which improves its performance.
6567
- On Redox, handle `EINTR` when reading from `event_socket` instead of panicking.
6668
- On Wayland, switch from using the `ahash` hashing algorithm to `foldhash`.
6769
- On macOS, fix borderless game presentation options not sticking after switching spaces.

0 commit comments

Comments
 (0)