Skip to content

Commit

Permalink
Use Segoe UI font on Windows.
Browse files Browse the repository at this point in the history
Qt uses "MS Shell Dlg 2" as the default font, which resolves to
Tahoma and not Segoe UI, which is the actual Windows 10 default font.
  • Loading branch information
phoerious committed May 21, 2020
1 parent a1b4a3f commit 0c800b6
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/core/Bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "gui/MessageBox.h"

#ifdef Q_OS_WIN
#include "gui/osutils/OSUtils.h"

#include <aclapi.h> // for createWindowsDACL()
#include <windows.h> // for Sleep(), SetDllDirectoryA(), SetSearchPathMode(), ...
#undef MessageBox
Expand Down Expand Up @@ -74,6 +76,10 @@ namespace Bootstrap
setupSearchPaths();
applyEarlyQNetworkAccessManagerWorkaround();
Translator::installTranslators();

#ifdef Q_OS_WIN
winUtils()->fixDefaultUIFont();
#endif
}

/**
Expand Down
42 changes: 42 additions & 0 deletions src/gui/osutils/winutils/WinUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
#include "WinUtils.h"
#include <QAbstractNativeEventFilter>
#include <QApplication>
#include <QFontDatabase>
#include <QSettings>

#include <windows.h>

#include <cmath>

QPointer<WinUtils> WinUtils::m_instance = nullptr;
QScopedPointer<WinUtils::DWMEventFilter> WinUtils::m_eventFilter;

Expand Down Expand Up @@ -105,3 +108,42 @@ bool WinUtils::isCapslockEnabled()
{
return GetKeyState(VK_CAPITAL) == 1;
}

/**
* Convert binary UTF-16 string to QByteArray.
*
* This is useful for reading REG_BINARY registry keys, which are incorrectly
* read as UTF16-encoded QStrings. See QTBUG-98.
*
* @param binaryString UTF-16 REG_BINARY string
* @return properly encoded QByteArray
*/
QByteArray WinUtils::convertRegBinary(const QString& binaryString) const
{
return QByteArray(reinterpret_cast<const char*>(binaryString.utf16()), binaryString.length() * 2);
}


/**
* Replace application default font with Window's actual default UI font.
*
* The default app font retrieved by Qt on Windows is "MS Shell Dlg 2", which translates to Tahoma
* even though the default Windows 10 font is actually Segoe UI.
* @return default font
*/
void WinUtils::fixDefaultUIFont() const
{
QSettings windowMetrics(R"(HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics)", QSettings::NativeFormat);
auto captionFont = winUtils()->convertRegBinary(windowMetrics.value("CaptionFont").toString());
if (captionFont.size() > 0x1C && captionFont[captionFont.size() - 1] == '\0') {
// Font size is the inverted first byte as device-dependent pixels
int pointSize = std::ceil(~captionFont[0] * 72.0 / windowMetrics.value("AppliedDPI", 96.0).toDouble());

// Font name starts at 0x1C and is a null-terminated UTF-16 string
auto font = QString::fromUtf16(reinterpret_cast<const ushort*>(captionFont.constData() + 0x1C));

qApp->setFont(QFontDatabase().font(font, "Regular", pointSize));
}

// If we're here, then something or somebody messed with WindowMetrics, do nothing.
}
4 changes: 4 additions & 0 deletions src/gui/osutils/winutils/WinUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "gui/osutils/OSUtilsBase.h"

#include <QAbstractNativeEventFilter>
#include <QFont>
#include <QPointer>
#include <QScopedPointer>

Expand All @@ -37,6 +38,9 @@ class WinUtils : public OSUtilsBase
void setLaunchAtStartup(bool enable) override;
bool isCapslockEnabled() override;

QByteArray convertRegBinary(const QString& binaryString) const;
void fixDefaultUIFont() const;

protected:
explicit WinUtils(QObject* parent = nullptr);
~WinUtils() override;
Expand Down

0 comments on commit 0c800b6

Please sign in to comment.