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 <timur.pocheptsov@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
bb10
Tor Arne Vestbø 2022-03-24 12:20:08 +01:00
parent c7280b3362
commit d84018616a
4 changed files with 31 additions and 0 deletions

View File

@ -60,6 +60,8 @@
#include <QtGui/private/qfontengine_ft_p.h>
#endif
#include <QtGui/qpa/qwindowsysteminterface.h>
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<QWindowSystemInterface::SynchronousDelivery>(nullptr);
}
struct FontDescription {

View File

@ -97,6 +97,10 @@ private:
QHash<QString, QList<QCFType<CTFontDescriptorRef>>> 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

View File

@ -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.

View File

@ -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);
};