Query UI font from system on Windows

Previously, we determined the UI font from a predefined set of fonts
each mapped to a language. This works well if the user doesn't change
their Windows UI font, but if one does, they will get the default UI
font associated with their language instead of the one the set.

This commit replaces ProgSettings::getFontName with
ProgSettings::getUIFont, which uses the SystemParametersInfo API to
query the message font from the system, which will allow users to have a
custom font. It will also not interfere with different languages, as the
message font will be appropriately set by default there.
This commit is contained in:
aubymori
2026-02-02 19:15:31 -06:00
parent b7075922ac
commit 7f69f00ed2
6 changed files with 42 additions and 24 deletions

View File

@@ -622,7 +622,7 @@ main(int argc, char *argv[])
fprintf(stderr, "Qt: version %s, platform \"%s\"\n", qVersion(), QApplication::platformName().toUtf8().data());
ProgSettings::loadTranslators(&app);
#ifdef Q_OS_WINDOWS
QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9));
QApplication::setFont(ProgSettings::getUIFont());
SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box");
#endif

View File

@@ -2431,7 +2431,7 @@ MainWindow::changeEvent(QEvent *event)
#ifdef Q_OS_WINDOWS
if (event->type() == QEvent::LanguageChange) {
auto size = this->centralWidget()->size();
QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9));
QApplication::setFont(ProgSettings::getUIFont());
QApplication::processEvents();
main_window->centralWidget()->setFixedSize(size);
QApplication::processEvents();

View File

@@ -28,6 +28,8 @@
#ifdef Q_OS_WINDOWS
# include <QSysInfo>
# include <QVersionNumber>
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
extern "C" {
@@ -158,26 +160,42 @@ ProgSettings::~ProgSettings()
}
#ifdef Q_OS_WINDOWS
/* Return the standard font name on Windows, which is overridden per-language
to prevent CJK fonts with embedded bitmaps being chosen as a fallback. */
QString
ProgSettings::getFontName(int langId)
/* Returns the standard UI font for Windows, which by default varies for different
languages. It can also be changed via external tools, if the user wants that.
We use the message font here since that is what most Windows components and
other third-party programs use. */
QFont
ProgSettings::getUIFont()
{
QString langCode = languageIdToCode(lang_id);
if (langCode == "ja-JP") {
/* Check for Windows 10 or later to choose the appropriate system font */
if (QVersionNumber::fromString(QSysInfo::kernelVersion()).majorVersion() >= 10)
return "Yu Gothic UI";
else
return "Meiryo UI";
} else if (langCode == "ko-KR")
return "Malgun Gothic";
else if (langCode == "zh-CN")
return "Microsoft YaHei";
else if (langCode == "zh-TW")
return "Microsoft JhengHei";
else
return "Segoe UI";
// Get the system (primary monitor) DPI. The font returned by
// SystemParametersInfo is scaled according to this and we need
// to get the font size in points to pass into QFont's constructor.
HDC hdc = GetDC(NULL);
int systemDpi = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(NULL, hdc);
// Get the font metrics.
NONCLIENTMETRICSW ncm = {};
ncm.cbSize = sizeof(ncm);
// This should never happen, but just to be safe, return Segoe UI if
// SPI fails.
if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
{
return QFont("Segoe UI", 9);
}
QString fontName = QString::fromWCharArray(ncm.lfMessageFont.lfFaceName);
// Windows' conversion from points to pixels goes as follows:
//
// -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72)
//
// (source: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createfontw)
//
// Let's reverse that calculation to get the point size from the message font.
int fontSize = -MulDiv(ncm.lfMessageFont.lfHeight, 72, systemDpi);
return QFont(fontName, fontSize);
}
#endif

View File

@@ -15,7 +15,7 @@ public:
explicit ProgSettings(QWidget *parent = nullptr);
~ProgSettings();
#ifdef Q_OS_WINDOWS
static QString getFontName(int langId);
static QFont getUIFont();
#endif
static int languageCodeToId(QString langCode);
static QString languageIdToCode(int id);

View File

@@ -165,7 +165,7 @@ VMManagerDetails::VMManagerDetails(QWidget *parent)
connect(this, &VMManagerDetails::styleUpdated, portsSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, otherSection, &VMManagerDetailSection::updateStyle);
QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9));
QApplication::setFont(ProgSettings::getUIFont());
#endif
sysconfig = new VMManagerSystem();

View File

@@ -269,7 +269,7 @@ VMManagerMainWindow::changeEvent(QEvent *event)
{
#ifdef Q_OS_WINDOWS
if (event->type() == QEvent::LanguageChange) {
QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9));
QApplication::setFont(QFont(ProgSettings::getUIFont()));
}
#endif
QWidget::changeEvent(event);