diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-01-03 17:18:40 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-04-02 14:32:25 +0200 |
commit | b2ec0da95641d9cec006fa9699e6d082ad35db0b (patch) | |
tree | c6ceef7e1527b98f3eda33b6e525d65ee1d810a6 /src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp | |
parent | 8dfe1385b5f05b7242802a72897258a63af1ca1d (diff) |
Cache QAccessibleInterfaces.
Since there already is a one-to-one relationship
between QObject and QAccessibleInterface it makes
little sense to create and destroy the interfaces
on each call to queryAccessibleInterface.
Add a cache and keep created interfaces around for
the lifetime of the corresponding QObject.
This changes the memory management rules: accessible
interfaces must no longer be deleted. If you get an
QAccessibleIntrface pointer that pointer will stay
valid as long as the corresponding QObject is not
deleted.
This also re-enables accessibility for Mac.
We limit the range of the IDs so that they are
useable for Windows directly.
That means we can get rid of the event cache there.
This is based on: Iebf2f374916fc70a9dd29e95f45a6444b85f6cee
Change-Id: I9fe6531812c0dbc5b41101ac05830a6dd75e13a3
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Diffstat (limited to 'src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp')
-rw-r--r-- | src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp | 44 |
1 files changed, 6 insertions, 38 deletions
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index 79d0934ebb..f222deeeac 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -86,14 +86,8 @@ #include "../qtwindows_additional.h" - -// This stuff is used for widgets/items with no window handle: -typedef QMap<int, QPair<QPointer<QObject>,int> > NotifyMap; -Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents) - QT_BEGIN_NAMESPACE - /*! \!internal \class QWindowsAccessibility @@ -172,7 +166,6 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) if (!iface) // ### This should not happen, maybe make it an assert. return; QWindow *window = QWindowsAccessibility::windowHelper(iface); - delete iface; if (!window) { window = QGuiApplication::focusWindow(); @@ -185,27 +178,9 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) return; HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", window); - static int eventNum = 0; if (event->type() != QAccessible::MenuCommand && // MenuCommand is faked event->type() != QAccessible::ObjectDestroyed) { - /* In some rare occasions, the server (Qt) might get a ::get_accChild call with a - childId that references an entry in the cache where there was a dangling - QObject-pointer. Previously we crashed on this. - - There is no point in actually notifying the AT client that the object got destroyed, - because the AT client won't query for get_accChild if the event is ObjectDestroyed - anyway, and we have no other way of mapping the eventId argument to the actual - child/descendant object. (Firefox seems to simply completely ignore - EVENT_OBJECT_DESTROY). - - We therefore guard each QObject in the cache with a QPointer, and only notify the AT - client if the type is not ObjectDestroyed. - */ - eventNum %= 50; //[0..49] - int eventId = - (eventNum - 1); - qAccessibleRecentSentEvents()->insert(eventId, qMakePair(QPointer<QObject>(event->object()), event->child())); - ::NotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, eventId); - ++eventNum; + ::NotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, QAccessible::uniqueId(iface)); } #endif // Q_OS_WINCE } @@ -218,7 +193,6 @@ QWindow *QWindowsAccessibility::windowHelper(const QAccessibleInterface *iface) while (acc && acc->isValid() && !window) { window = acc->window(); QAccessibleInterface *par = acc->parent(); - delete acc; acc = par; } } @@ -233,6 +207,11 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) { if (!acc) return 0; + + // ### FIXME: maybe we should accept double insertions into the cache + if (!QAccessible::uniqueId(acc)) + QAccessible::registerAccessibleInterface(acc); + #ifdef Q_CC_MINGW QWindowsMsaaAccessible *wacc = new QWindowsMsaaAccessible(acc); #else @@ -243,15 +222,6 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) return iacc; } -/*! - \internal -*/ -QPair<QObject*, int> QWindowsAccessibility::getCachedObject(int entryId) -{ - QPair<QPointer<QObject>, int> pair = qAccessibleRecentSentEvents()->value(entryId); - return qMakePair(pair.first.data(), pair.second); -} - /* void QWindowsAccessibility::setRootObject(QObject *o) { @@ -304,8 +274,6 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W iface->Release(); // the client will release the object again, and then it will destroy itself } return true; - } else { - delete acc; } } } |