From d84018616a24fa66502cf62f5ebbcf5ed4ca0742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 24 Mar 2022 12:20:08 +0100 Subject: [PATCH] macOS: Handle changes in the available fonts by invalidating font database The user may use the Font Book application to add or remove fonts, which affects the fonts that are available to Qt applications. As the cross platform QFontDatabase implementation currently doesn't support granular management (removal) of fonts, we need to invalidate the entire font database. Since the theme fonts on macOS (and iOS) are managed by the font database we also need to invalidate the theme fonts, and report this back to the application. Change-Id: I1f6a7900f76e0b6a1f059bd43638a04bc0808e20 Reviewed-by: Timur Pocheptsov Reviewed-by: Volker Hilsheimer --- src/gui/text/coretext/qcoretextfontdatabase.mm | 13 +++++++++++++ src/gui/text/coretext/qcoretextfontdatabase_p.h | 4 ++++ src/gui/text/qplatformfontdatabase.cpp | 12 ++++++++++++ src/gui/text/qplatformfontdatabase.h | 2 ++ 4 files changed, 31 insertions(+) diff --git a/src/gui/text/coretext/qcoretextfontdatabase.mm b/src/gui/text/coretext/qcoretextfontdatabase.mm index 043272b4c2..88316850e1 100644 --- a/src/gui/text/coretext/qcoretextfontdatabase.mm +++ b/src/gui/text/coretext/qcoretextfontdatabase.mm @@ -60,6 +60,8 @@ #include #endif +#include + QT_BEGIN_NAMESPACE // this could become a list of all languages used for each writing @@ -105,6 +107,12 @@ enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) } QCoreTextFontDatabase::QCoreTextFontDatabase() : m_hasPopulatedAliases(false) { +#if defined(Q_OS_MACOS) + m_fontSetObserver = QMacNotificationObserver(nil, NSFontSetChangedNotification, [] { + qCDebug(lcQpaFonts) << "Fonts have changed"; + handleAvailableFontsChanged(); + }); +#endif } QCoreTextFontDatabase::~QCoreTextFontDatabase() @@ -223,7 +231,12 @@ void QCoreTextFontDatabase::populateFamily(const QString &familyName) void QCoreTextFontDatabase::invalidate() { + qCDebug(lcQpaFonts) << "Invalidating font database"; m_hasPopulatedAliases = false; + + qDeleteAll(m_themeFonts); + m_themeFonts.clear(); + QWindowSystemInterface::handleThemeChange(nullptr); } struct FontDescription { diff --git a/src/gui/text/coretext/qcoretextfontdatabase_p.h b/src/gui/text/coretext/qcoretextfontdatabase_p.h index b8fa87996d..12f55bd8ad 100644 --- a/src/gui/text/coretext/qcoretextfontdatabase_p.h +++ b/src/gui/text/coretext/qcoretextfontdatabase_p.h @@ -97,6 +97,10 @@ private: QHash>> m_systemFontDescriptors; bool m_hasPopulatedAliases; + +#if defined(Q_OS_MACOS) + QMacNotificationObserver m_fontSetObserver; +#endif }; // Split out into separate template class so that the compiler doesn't have diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp index 9063075a66..ff678da322 100644 --- a/src/gui/text/qplatformfontdatabase.cpp +++ b/src/gui/text/qplatformfontdatabase.cpp @@ -613,6 +613,18 @@ void QPlatformFontDatabase::registerAliasToFontFamily(const QString &familyName, qt_registerAliasToFontFamily(familyName, alias); } +/*! + Inform the Qt font database that the platform's available fonts have changed. + + This will result in invalidating the entire font database. + + \since 6.4 +*/ +void QPlatformFontDatabase::handleAvailableFontsChanged() +{ + QFontDatabasePrivate::instance()->invalidate(); +} + /*! Helper function that returns true if the font family has already been registered and populated. diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h index 74b9e1ba12..0e3d18ffe2 100644 --- a/src/gui/text/qplatformfontdatabase.h +++ b/src/gui/text/qplatformfontdatabase.h @@ -139,6 +139,8 @@ public: static void registerFontFamily(const QString &familyName); static void registerAliasToFontFamily(const QString &familyName, const QString &alias); + static void handleAvailableFontsChanged(); + static bool isFamilyPopulated(const QString &familyName); };