Merge branch 'win32-native-dialogs-pmdpi' of https://github.com/MaartenBent/wxWidgets
Improve native MSW dialog DPI awareness. See #24196.
This commit is contained in:
commit
5ae3b771ad
3 changed files with 50 additions and 36 deletions
|
|
@ -15,6 +15,8 @@
|
|||
#endif
|
||||
|
||||
#include "wx/dynlib.h"
|
||||
#include "wx/display.h"
|
||||
#include "wx/sysopt.h"
|
||||
|
||||
namespace wxMSWImpl
|
||||
{
|
||||
|
|
@ -35,6 +37,9 @@ public:
|
|||
AutoSystemDpiAware()
|
||||
: m_prevContext(WXDPI_AWARENESS_CONTEXT_UNAWARE)
|
||||
{
|
||||
if ( !Needed() )
|
||||
return;
|
||||
|
||||
if ( ms_pfnSetThreadDpiAwarenessContext == (SetThreadDpiAwarenessContext_t)-1)
|
||||
{
|
||||
wxLoadedDLL dllUser32("user32.dll");
|
||||
|
|
@ -62,6 +67,20 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
static bool Needed()
|
||||
{
|
||||
// use system-dpi-aware context when:
|
||||
// - the user did not set an option to force per-monitor context
|
||||
// - there are displays with different DPI
|
||||
if ( wxSystemOptions::GetOptionInt("msw.native-dialogs-pmdpi") == 1 )
|
||||
return false;
|
||||
|
||||
bool diferentDPI = false;
|
||||
for ( unsigned i = 1; i < wxDisplay::GetCount() && !diferentDPI; ++i )
|
||||
diferentDPI = wxDisplay(0u).GetPPI() != wxDisplay(i).GetPPI();
|
||||
return diferentDPI;
|
||||
}
|
||||
|
||||
private:
|
||||
WXDPI_AWARENESS_CONTEXT m_prevContext;
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,12 @@
|
|||
using it, i.e. this has the same effect as calling
|
||||
wxApp::MSWEnableDarkMode(). If set to 2, use dark mode unconditionally,
|
||||
as if this function were called with wxApp::DarkMode_Always argument.
|
||||
@flag{msw.native-dialogs-pmdpi}
|
||||
Some native win32 dialogs (like the font and colour pickers) are not
|
||||
per-monitor DPI aware, and wxWidgets will forcefully show them as
|
||||
system DPI aware when there are monitors with different DPI connected.
|
||||
If set to 1, these dialogs will always be shown as per-monitor DPI
|
||||
aware (when enabled in the manifest).
|
||||
@endFlagTable
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -126,21 +126,22 @@ int wxFontDialog::ShowModal()
|
|||
chooseFontStruct.lpfnHook = wxFontDialogHookProc;
|
||||
}
|
||||
|
||||
// The native font dialog does not support moving between displays with
|
||||
// different DPIs. Check if it will be shown system-dpi-aware.
|
||||
const bool useSystemDPI = wxMSWImpl::AutoSystemDpiAware::Needed();
|
||||
|
||||
// When the font dialog is system-dpi-aware, it expects the font at 96DPI/100% scaling.
|
||||
// When the font dialog is per-monitor-dpi-aware, it expects a font with the system DPI.
|
||||
const int fontdlgDPI = useSystemDPI ? wxDisplay::GetStdPPIValue() : wxGetDPIofHDC(ScreenHDC()).y;
|
||||
|
||||
if ( m_fontData.m_initialFont.IsOk() )
|
||||
{
|
||||
flags |= CF_INITTOLOGFONTSTRUCT;
|
||||
logFont = m_fontData.m_initialFont.GetNativeFontInfo()->lf;
|
||||
|
||||
// The standard dialog seems to always use the default DPI for
|
||||
// converting LOGFONT height to the value in points shown in the
|
||||
// dialog (and this happens even when not using AutoSystemDpiAware),
|
||||
// so we need to convert it to standard (not even system, because the
|
||||
// dialog doesn't take it into account either) DPI.
|
||||
logFont.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI
|
||||
(
|
||||
m_fontData.m_initialFont.GetFractionalPointSize(),
|
||||
wxDisplay::GetStdPPIValue()
|
||||
);
|
||||
// Convert the DPI of the font to the DPI of the font dialog.
|
||||
const double fPointSize = m_fontData.m_initialFont.GetFractionalPointSize();
|
||||
logFont.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI(fPointSize, fontdlgDPI);
|
||||
}
|
||||
|
||||
if ( m_fontData.m_fontColour.IsOk() )
|
||||
|
|
@ -180,33 +181,21 @@ int wxFontDialog::ShowModal()
|
|||
// Don't trust the LOGFONT height returned by the native dialog because
|
||||
// it doesn't use the correct DPI.
|
||||
//
|
||||
// Note that we must use our parent and not this window itself, as it
|
||||
// doesn't have any valid HWND and so its DPI can't be determined.
|
||||
if ( parent )
|
||||
{
|
||||
// We can't just adjust lfHeight directly to the correct DPI here
|
||||
// as doing this would introduce rounding problems, e.g. 8pt font
|
||||
// corresponds to lfHeight == 11px and scaling this up for 150% DPI
|
||||
// would result in 17px height which would then map to 8.5pt at
|
||||
// 150% DPI and end up being rounded to 9pt, which would be wrong.
|
||||
//
|
||||
// So find the point size itself first:
|
||||
const int pointSize = wxRound(wxNativeFontInfo::GetPointSizeAtPPI
|
||||
(
|
||||
logFont.lfHeight,
|
||||
wxDisplay::GetStdPPIValue()
|
||||
));
|
||||
// We can't just adjust lfHeight directly to the correct DPI here
|
||||
// as doing this would introduce rounding problems, e.g. 8pt font
|
||||
// corresponds to lfHeight == 11px and scaling this up for 150% DPI
|
||||
// would result in 17px height which would then map to 8.5pt at
|
||||
// 150% DPI and end up being rounded to 9pt, which would be wrong.
|
||||
//
|
||||
// Convert from the DPI of the font dialog to the DPI the
|
||||
// wxNativeFontInfo constructor will use to determine the font size.
|
||||
const double fPointSize = wxNativeFontInfo::GetPointSizeAtPPI(logFont.lfHeight, fontdlgDPI);
|
||||
const int fontDPI = wxGetDPIofHDC(ScreenHDC()).y;
|
||||
logFont.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI(wxRound(fPointSize), fontDPI);
|
||||
|
||||
// And then compute the pixel height that results in this point
|
||||
// size at the actual DPI being used.
|
||||
logFont.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI
|
||||
(
|
||||
pointSize,
|
||||
parent->GetDPI().y
|
||||
);
|
||||
}
|
||||
|
||||
wxFont f(wxNativeFontInfo(logFont, parent));
|
||||
// Use nullptr, so the pointSize calculation in wxNativeFontInfo will
|
||||
// use the same fontDPI as is used above for lfHeight.
|
||||
wxFont f(wxNativeFontInfo(logFont, nullptr));
|
||||
|
||||
// The native dialog allows selecting only integer font sizes in
|
||||
// points, but converting them to pixel height loses precision and so
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue