From 7f69f00ed25bd0c34eb2d9e4dba4b2b032e703dc Mon Sep 17 00:00:00 2001 From: aubymori Date: Mon, 2 Feb 2026 19:15:31 -0600 Subject: [PATCH] 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. --- src/qt/qt_main.cpp | 2 +- src/qt/qt_mainwindow.cpp | 2 +- src/qt/qt_progsettings.cpp | 56 ++++++++++++++++++++---------- src/qt/qt_progsettings.hpp | 2 +- src/qt/qt_vmmanager_details.cpp | 2 +- src/qt/qt_vmmanager_mainwindow.cpp | 2 +- 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 8a12dd441..fd4bc5610 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -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 diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f6195389c..1133b26c0 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -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(); diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 62b63bbcc..d3ebfa9e8 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -28,6 +28,8 @@ #ifdef Q_OS_WINDOWS # include # include +# define WIN32_LEAN_AND_MEAN +# include #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 diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index 2ada8c2bf..579c5abf7 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -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); diff --git a/src/qt/qt_vmmanager_details.cpp b/src/qt/qt_vmmanager_details.cpp index 40d0fb185..300e227e2 100644 --- a/src/qt/qt_vmmanager_details.cpp +++ b/src/qt/qt_vmmanager_details.cpp @@ -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(); diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index 17bd898bd..a52002653 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -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);