Revert "a11y: Do not cache classes that don't have a factory plugin"
This reverts commit 583668005d4d6399fc16d165dcb6a5af2b94323d, and provides an alternative fix for QTBUG-75106. Reason: This introduced QTBUG-103009, due to lack of caching. To fix the original issue, we still reduce the amount of caching we do, by only considering the first non-dynamic meta-object for QML related objects. Task-number: QTBUG-75106 Fixes: QTBUG-103009 Pick-to: 6.3 6.2 5.15 Change-Id: Ic76af26a719d1114208be9555286239c6c6df615 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
93125d3a05
commit
02c2ad6cbe
@ -54,6 +54,7 @@
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qmetaobject.h>
|
||||
#include <QtCore/private/qmetaobject_p.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <private/qfactoryloader_p.h>
|
||||
|
||||
@ -682,6 +683,25 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
|
||||
// Create a QAccessibleInterface for the object class. Start by the most
|
||||
// derived class and walk up the class hierarchy.
|
||||
const QMetaObject *mo = object->metaObject();
|
||||
const auto *objectPriv = QObjectPrivate::get(object);
|
||||
/*
|
||||
We do not want to cache each and every QML metaobject (Button_QMLTYPE_124,
|
||||
Button_QMLTYPE_125, etc.). Those dynamic metaobjects shouldn't have an
|
||||
accessible interface in any case. Instead, we start the whole checking
|
||||
with the first non-dynamic meta-object. To avoid potential regressions
|
||||
in other areas of Qt that also use dynamic metaobjects, we only do this
|
||||
for objects that are QML-related (approximated by checking whether they
|
||||
have ddata set).
|
||||
*/
|
||||
const bool qmlRelated = !objectPriv->isDeletingChildren &&
|
||||
objectPriv->declarativeData;
|
||||
while (qmlRelated && mo) {
|
||||
auto mop = QMetaObjectPrivate::get(mo);
|
||||
if (!mop || !(mop->flags & DynamicMetaObject))
|
||||
break;
|
||||
|
||||
mo = mo->superClass();
|
||||
};
|
||||
while (mo) {
|
||||
const QString cn = QLatin1StringView(mo->className());
|
||||
|
||||
@ -697,14 +717,15 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
|
||||
// Find a QAccessiblePlugin (factory) for the class name. If there's
|
||||
// no entry in the cache try to create it using the plugin loader.
|
||||
if (!qAccessiblePlugins()->contains(cn)) {
|
||||
QAccessiblePlugin *factory = nullptr; // 0 means "no plugin found". This is cached as well.
|
||||
const int index = loader()->indexOf(cn);
|
||||
if (index != -1) {
|
||||
QAccessiblePlugin *factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
|
||||
qAccessiblePlugins()->insert(cn, factory);
|
||||
}
|
||||
if (index != -1)
|
||||
factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
|
||||
qAccessiblePlugins()->insert(cn, factory);
|
||||
}
|
||||
|
||||
// At this point the cache should contain a valid factory pointer or 0:
|
||||
Q_ASSERT(qAccessiblePlugins()->contains(cn));
|
||||
QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn);
|
||||
if (factory) {
|
||||
QAccessibleInterface *result = factory->create(cn, object);
|
||||
|
Loading…
x
Reference in New Issue
Block a user