Skip to content

Commit 7086b3e

Browse files
k-takatachrisbra
authored andcommitted
patch 9.0.1970: win32: high-dpi support can be improved
Problem: win32: high-dpi support can be improved Solution: implement WM_GETDPISCALEDSIZE win32: Better support of Per-Monitor V2 High DPI Implement WM_GETDPISCALEDSIZE. It is not so easy to calculate the new size without actually changing the size. So, this returns an approximate size. This doesn't work well when a bitmap font (e.g. FixedSys) is selected, but I think this is acceptable. closes: #11812 closes: #13252 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Ken Takata <[email protected]>
1 parent 3bd7fa1 commit 7086b3e

2 files changed

Lines changed: 58 additions & 10 deletions

File tree

src/gui_w32.c

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ gui_mch_set_rendering_options(char_u *s)
226226
# define WM_DPICHANGED 0x02E0
227227
#endif
228228

229+
#ifndef WM_GETDPISCALEDSIZE
230+
# define WM_GETDPISCALEDSIZE 0x02E4
231+
#endif
232+
229233
#ifndef WM_MOUSEHWHEEL
230234
# define WM_MOUSEHWHEEL 0x020E
231235
#endif
@@ -379,6 +383,7 @@ typedef enum DPI_AWARENESS {
379383
static int s_dpi = DEFAULT_DPI;
380384
static BOOL s_in_dpichanged = FALSE;
381385
static DPI_AWARENESS s_process_dpi_aware = DPI_AWARENESS_INVALID;
386+
static RECT s_suggested_rect;
382387

383388
static UINT (WINAPI *pGetDpiForSystem)(void) = NULL;
384389
static UINT (WINAPI *pGetDpiForWindow)(HWND hwnd) = NULL;
@@ -4734,13 +4739,32 @@ _OnMenuSelect(HWND hwnd, WPARAM wParam, LPARAM lParam)
47344739
}
47354740
#endif
47364741

4742+
static BOOL
4743+
_OnGetDpiScaledSize(HWND hwnd, UINT dpi, SIZE *size)
4744+
{
4745+
//TRACE("DPI: %d, SIZE=(%d,%d), s_dpi: %d", dpi, size->cx, size->cy, s_dpi);
4746+
4747+
// Calculate new approximate size.
4748+
// FIXME: If a bitmap font (e.g. FixedSys) is used, the font size may not
4749+
// be changed. In that case, the calculated size can be wrong.
4750+
size->cx = size->cx * dpi / s_dpi;
4751+
size->cy = size->cy * dpi / s_dpi;
4752+
//TRACE("New approx. SIZE=(%d,%d)", size->cx, size->cy);
4753+
4754+
return FALSE;
4755+
}
4756+
47374757
static LRESULT
4738-
_OnDpiChanged(HWND hwnd, UINT xdpi UNUSED, UINT ydpi, RECT *rc UNUSED)
4758+
_OnDpiChanged(HWND hwnd, UINT xdpi UNUSED, UINT ydpi, RECT *rc)
47394759
{
47404760
s_dpi = ydpi;
47414761
s_in_dpichanged = TRUE;
47424762
//TRACE("DPI: %d", ydpi);
47434763

4764+
s_suggested_rect = *rc;
4765+
//TRACE("Suggested pos&size: %d,%d %d,%d", rc->left, rc->top,
4766+
// rc->right - rc->left, rc->bottom - rc->top);
4767+
47444768
update_scrollbar_size();
47454769
update_toolbar_size();
47464770
set_tabline_font();
@@ -4893,6 +4917,8 @@ _WndProc(
48934917
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
48944918
return 1L;
48954919
#endif
4920+
case WM_GETDPISCALEDSIZE:
4921+
return _OnGetDpiScaledSize(hwnd, (UINT)wParam, (SIZE *)lParam);
48964922
case WM_DPICHANGED:
48974923
return _OnDpiChanged(hwnd, (UINT)LOWORD(wParam), (UINT)HIWORD(wParam),
48984924
(RECT*)lParam);
@@ -5550,7 +5576,12 @@ gui_mch_set_shellsize(
55505576
if (IsZoomed(s_hwnd) && starting == 0)
55515577
ShowWindow(s_hwnd, SW_SHOWNORMAL);
55525578

5553-
GetWindowRect(s_hwnd, &window_rect);
5579+
if (s_in_dpichanged)
5580+
// Use the suggested position when in WM_DPICHANGED.
5581+
window_rect = s_suggested_rect;
5582+
else
5583+
// Use current position.
5584+
GetWindowRect(s_hwnd, &window_rect);
55545585

55555586
// compute the size of the outside of the window
55565587
win_width = width + (pGetSystemMetricsForDpi(SM_CXFRAME, s_dpi) +
@@ -5567,21 +5598,36 @@ gui_mch_set_shellsize(
55675598
window_rect.bottom = window_rect.top + win_height;
55685599

55695600
// If the window is going off the screen, move it on to the screen.
5570-
if ((direction & RESIZE_HOR) && window_rect.right > workarea_rect.right)
5571-
OffsetRect(&window_rect, workarea_rect.right - window_rect.right, 0);
5601+
// Don't adjust the position when in WM_DPICHANGED.
5602+
if (!s_in_dpichanged)
5603+
{
5604+
if ((direction & RESIZE_HOR)
5605+
&& window_rect.right > workarea_rect.right)
5606+
OffsetRect(&window_rect,
5607+
workarea_rect.right - window_rect.right, 0);
55725608

5573-
if ((direction & RESIZE_HOR) && window_rect.left < workarea_rect.left)
5574-
OffsetRect(&window_rect, workarea_rect.left - window_rect.left, 0);
5609+
if ((direction & RESIZE_HOR)
5610+
&& window_rect.left < workarea_rect.left)
5611+
OffsetRect(&window_rect,
5612+
workarea_rect.left - window_rect.left, 0);
55755613

5576-
if ((direction & RESIZE_VERT) && window_rect.bottom > workarea_rect.bottom)
5577-
OffsetRect(&window_rect, 0, workarea_rect.bottom - window_rect.bottom);
5614+
if ((direction & RESIZE_VERT)
5615+
&& window_rect.bottom > workarea_rect.bottom)
5616+
OffsetRect(&window_rect,
5617+
0, workarea_rect.bottom - window_rect.bottom);
55785618

5579-
if ((direction & RESIZE_VERT) && window_rect.top < workarea_rect.top)
5580-
OffsetRect(&window_rect, 0, workarea_rect.top - window_rect.top);
5619+
if ((direction & RESIZE_VERT)
5620+
&& window_rect.top < workarea_rect.top)
5621+
OffsetRect(&window_rect,
5622+
0, workarea_rect.top - window_rect.top);
5623+
}
55815624

55825625
MoveWindow(s_hwnd, window_rect.left, window_rect.top,
55835626
win_width, win_height, TRUE);
55845627

5628+
//TRACE("New pos: %d,%d New size: %d,%d",
5629+
// window_rect.left, window_rect.top, win_width, win_height);
5630+
55855631
SetActiveWindow(s_hwnd);
55865632
SetFocus(s_hwnd);
55875633

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ static char *(features[]) =
704704

705705
static int included_patches[] =
706706
{ /* Add new patch number below this line */
707+
/**/
708+
1970,
707709
/**/
708710
1969,
709711
/**/

0 commit comments

Comments
 (0)