Skip to content

Commit

Permalink
Scale window content with screen DPI on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
lampy committed Jan 11, 2025
1 parent cbec0f6 commit d5dd6dc
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
22 changes: 21 additions & 1 deletion os/win/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ WindowWin::Touch::Touch() : fingers(0), canBeMouse(false), asMouse(false), timer
WindowWin::WindowWin(const WindowSpec& spec)
: m_clientSize(1, 1)
, m_scale(spec.scale())
, m_baseScale(spec.scale())
, m_isCreated(false)
, m_adjustShadow(true)
, m_translateDeadKeys(false)
Expand Down Expand Up @@ -263,6 +264,9 @@ WindowWin::WindowWin(const WindowSpec& spec)

SetWindowLongPtr(m_hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));

if (winApi.GetWindowDpiAwarenessContext)
m_scale = MulDiv(m_baseScale, winApi.GetDpiForWindow(m_hwnd), USER_DEFAULT_SCREEN_DPI);

// This flag is used to avoid calling T::resizeImpl() when we
// add the scrollbars to the window. (As the T type could not be
// fully initialized yet.)
Expand Down Expand Up @@ -361,7 +365,9 @@ os::ColorSpaceRef WindowWin::colorSpace() const

void WindowWin::setScale(int scale)
{
m_scale = scale;
double scaleFactor = m_scale / (double) m_baseScale;
m_baseScale = scale;
m_scale = scale * scaleFactor;

// Align window size to new scale
{
Expand Down Expand Up @@ -966,6 +972,20 @@ LRESULT WindowWin::wndProc(UINT msg, WPARAM wparam, LPARAM lparam)
}
break;

case WM_DPICHANGED: {
m_scale = MulDiv(m_baseScale, HIWORD(wparam), USER_DEFAULT_SCREEN_DPI);

RECT* prcNewWindow = (RECT*)lparam;
SetWindowPos(m_hwnd,
nullptr,
prcNewWindow ->left,
prcNewWindow ->top,
prcNewWindow->right - prcNewWindow->left,
prcNewWindow->bottom - prcNewWindow->top,
SWP_NOZORDER | SWP_NOACTIVATE);
break;
}

case WM_SETCURSOR:
// We set our custom cursor if we are in the client area, or in
// the case of windows with custom frames (borderless), we
Expand Down
2 changes: 2 additions & 0 deletions os/win/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class WindowWin : public Window {
os::ScreenRef screen() const override;
os::ColorSpaceRef colorSpace() const override;
int scale() const override { return m_scale; }
int baseScale() const override { return m_baseScale; }
void setScale(int scale) override;
bool isVisible() const override;
void setVisible(bool visible) override;
Expand Down Expand Up @@ -144,6 +145,7 @@ class WindowWin : public Window {
std::unique_ptr<DragTargetAdapter> m_dragTargetAdapter = nullptr;

int m_scale;
int m_baseScale;
bool m_isCreated;
// Since Windows Vista, it looks like Microsoft decided to change
// the meaning of the window position to the shadow position (when
Expand Down
4 changes: 4 additions & 0 deletions os/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ class Window : public RefCount {
// The window size will be a multiple of the scale.
virtual void setScale(int scale) = 0;

// Returns the current window scale for default DPI value.
// It is constant across different displays.
virtual int baseScale() const { return scale(); }

// Returns true if the window is visible in the screen.
virtual bool isVisible() const = 0;

Expand Down

0 comments on commit d5dd6dc

Please sign in to comment.