summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRealDolos <dolos@cock.li>2018-11-17 21:56:56 +0100
committerJames Ross-Gowan <rossy@jrg.systems>2020-05-08 21:46:45 +1000
commit8bce6d0b8905fae81792ec547a10c40f4bc84de5 (patch)
tree312f33d6b4c67f59bc0e1b344799206c4a6b3b91
parent326c55a5713b9aa54317873554c1d11e4dfffe9f (diff)
downloadmpv-8bce6d0b8905fae81792ec547a10c40f4bc84de5.tar.bz2
mpv-8bce6d0b8905fae81792ec547a10c40f4bc84de5.tar.xz
w32_common: Support HiDPI on Windows
-rw-r--r--DOCS/man/options.rst4
-rw-r--r--osdep/mpv.exe.manifest5
-rw-r--r--video/out/w32_common.c32
3 files changed, 29 insertions, 12 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index bd00d16fb4..0a96d18baf 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -3117,10 +3117,10 @@ Window
- ``--monitoraspect=16:9`` or ``--monitoraspect=1.7777``
``--hidpi-window-scale``, ``--no-hidpi-window-scale``
- (OS X, X11, and Wayland only)
+ (OS X, Windows, X11, and Wayland only)
Scale the window size according to the backing scale factor (default: yes).
On regular HiDPI resolutions the window opens with double the size but appears
- as having the same size as on none-HiDPI resolutions. This is the default OS X
+ as having the same size as on non-HiDPI resolutions. This is the default OS X
behavior.
``--native-fs``, ``--no-native-fs``
diff --git a/osdep/mpv.exe.manifest b/osdep/mpv.exe.manifest
index 31386e8ab1..accc2eddc8 100644
--- a/osdep/mpv.exe.manifest
+++ b/osdep/mpv.exe.manifest
@@ -8,8 +8,9 @@
/>
<description>mpv - The Movie Player</description>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
- <windowsSettings xmlns:ws="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
- <ws:dpiAware>True/PM</ws:dpiAware>
+ <windowsSettings>
+ <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
+ <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
</windowsSettings>
</application>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
diff --git a/video/out/w32_common.c b/video/out/w32_common.c
index 4965324d38..6f927d7f28 100644
--- a/video/out/w32_common.c
+++ b/video/out/w32_common.c
@@ -69,6 +69,7 @@ typedef enum MONITOR_DPI_TYPE {
struct w32_api {
HRESULT (WINAPI *pGetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
BOOL (WINAPI *pImmDisableIME)(DWORD);
+ BOOL (WINAPI *pAdjustWindowRectExForDpi)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi);
};
struct vo_w32_state {
@@ -110,6 +111,7 @@ struct vo_w32_state {
uint32_t o_dheight;
int dpi;
+ double dpi_scale;
bool disable_screensaver;
bool cursor_visible;
@@ -148,16 +150,22 @@ struct vo_w32_state {
HANDLE avrt_handle;
};
-static void add_window_borders(HWND hwnd, RECT *rc)
+static void add_window_borders(struct vo_w32_state *w32, HWND hwnd, RECT *rc)
{
- AdjustWindowRect(rc, GetWindowLongPtrW(hwnd, GWL_STYLE), 0);
+ if (w32->api.pAdjustWindowRectExForDpi) {
+ w32->api.pAdjustWindowRectExForDpi(rc,
+ GetWindowLongPtrW(hwnd, GWL_STYLE), 0,
+ GetWindowLongPtrW(hwnd, GWL_EXSTYLE), w32->dpi);
+ } else {
+ AdjustWindowRect(rc, GetWindowLongPtrW(hwnd, GWL_STYLE), 0);
+ }
}
// basically a reverse AdjustWindowRect (win32 doesn't appear to have this)
-static void subtract_window_borders(HWND hwnd, RECT *rc)
+static void subtract_window_borders(struct vo_w32_state *w32, HWND hwnd, RECT *rc)
{
RECT b = { 0, 0, 0, 0 };
- add_window_borders(hwnd, &b);
+ add_window_borders(w32, hwnd, &b);
rc->left -= b.left;
rc->top -= b.top;
rc->right -= b.right;
@@ -523,16 +531,19 @@ static void update_dpi(struct vo_w32_state *w32)
if (w32->api.pGetDpiForMonitor && w32->api.pGetDpiForMonitor(w32->monitor,
MDT_EFFECTIVE_DPI, &dpiX, &dpiY) == S_OK) {
w32->dpi = (int)dpiX;
+ w32->dpi_scale = w32->opts->hidpi_window_scale ? w32->dpi / 96.0 : 1.0;
MP_VERBOSE(w32, "DPI detected from the new API: %d\n", w32->dpi);
return;
}
HDC hdc = GetDC(NULL);
if (hdc) {
w32->dpi = GetDeviceCaps(hdc, LOGPIXELSX);
+ w32->dpi_scale = w32->opts->hidpi_window_scale ? w32->dpi / 96.0 : 1.0;
ReleaseDC(NULL, hdc);
MP_VERBOSE(w32, "DPI detected from the old API: %d\n", w32->dpi);
} else {
w32->dpi = 96;
+ w32->dpi_scale = 1.0;
MP_VERBOSE(w32, "Couldn't determine DPI, falling back to %d\n", w32->dpi);
}
}
@@ -818,7 +829,7 @@ static void fit_window_on_screen(struct vo_w32_state *w32)
RECT screen = get_working_area(w32);
if (w32->opts->border && w32->opts->fit_border)
- subtract_window_borders(w32->window, &screen);
+ subtract_window_borders(w32, w32->window, &screen);
if (fit_rect(&w32->windowrc, &screen)) {
MP_VERBOSE(w32, "adjusted window bounds: %d:%d:%d:%d\n",
@@ -924,7 +935,7 @@ static void update_window_state(struct vo_w32_state *w32)
return;
RECT wr = w32->windowrc;
- add_window_borders(w32->window, &wr);
+ add_window_borders(w32, w32->window, &wr);
SetWindowPos(w32->window, w32->opts->ontop ? HWND_TOPMOST : HWND_NOTOPMOST,
wr.left, wr.top, rect_w(wr), rect_h(wr),
@@ -1088,7 +1099,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
// get client area of the windows if it had the rect rc
// (subtracting the window borders)
RECT r = *rc;
- subtract_window_borders(w32->window, &r);
+ subtract_window_borders(w32, w32->window, &r);
int c_w = rect_w(r), c_h = rect_h(r);
float aspect = w32->o_dwidth / (float) MPMAX(w32->o_dheight, 1);
int d_w = c_h * aspect - c_w;
@@ -1384,7 +1395,7 @@ static void gui_thread_reconfig(void *ptr)
struct mp_rect screen = { r.left, r.top, r.right, r.bottom };
struct vo_win_geometry geo;
- vo_calc_window_geometry(vo, &screen, &geo);
+ vo_calc_window_geometry2(vo, &screen, w32->dpi_scale, &geo);
vo_apply_window_geometry(vo, &geo);
bool reset_size = w32->o_dwidth != vo->dwidth ||
@@ -1440,6 +1451,11 @@ static void w32_api_load(struct vo_w32_state *w32)
w32->api.pGetDpiForMonitor = !shcore_dll ? NULL :
(void *)GetProcAddress(shcore_dll, "GetDpiForMonitor");
+ HMODULE user32_dll = LoadLibraryW(L"user32.dll");
+ // Available since Win10
+ w32->api.pAdjustWindowRectExForDpi = !user32_dll ? NULL :
+ (void *)GetProcAddress(user32_dll, "AdjustWindowRectExForDpi");
+
// imm32.dll must be loaded dynamically
// to account for machines without East Asian language support
HMODULE imm32_dll = LoadLibraryW(L"imm32.dll");