Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwindowsuiaprovidercache.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtGui/qtguiglobal.h>
5#if QT_CONFIG(accessibility)
6
7#include "qwindowsuiaprovidercache.h"
8#include "qwindowsuiautils.h"
9#include "qwindowscontext.h"
10
11QT_BEGIN_NAMESPACE
12
13using namespace QWindowsUiAutomation;
14
15
16// Private constructor
17QWindowsUiaProviderCache::QWindowsUiaProviderCache()
18{
19}
20
21// shared instance
22QWindowsUiaProviderCache *QWindowsUiaProviderCache::instance()
23{
24 static QWindowsUiaProviderCache providerCache;
25 return &providerCache;
26}
27
28// Returns the provider instance associated with the ID, or nullptr.
29ComPtr<QWindowsUiaMainProvider> QWindowsUiaProviderCache::providerForId(QAccessible::Id id) const
30{
31 QMutexLocker guard{ &m_tableMutex };
32
33 // Make sure lifetime is extended while holding the mutex
34 ComPtr<QWindowsUiaMainProvider> provider = m_providerTable.value(id);
35
36 return provider;
37}
38
39// Inserts a provider in the cache and associates it with an accessibility ID.
40void QWindowsUiaProviderCache::insert(QAccessible::Id id, QWindowsUiaMainProvider *provider)
41{
42 QMutexLocker guard{ &m_tableMutex };
43 // Remove id if it already exists
44 m_inverseTable.remove(m_providerTable.value(id));
45 m_providerTable.remove(id);
46
47 // Add new provider
48 if (provider) {
49 m_providerTable[id] = provider;
50 m_inverseTable[provider] = id;
51 guard.unlock();
52 // Connects the destroyed signal to our slot, to remove deleted objects from the cache.
53 QObject::connect(provider, &QObject::destroyed, this, &QWindowsUiaProviderCache::remove, Qt::DirectConnection);
54 }
55}
56
57// Removes deleted provider objects from the cache.
58void QWindowsUiaProviderCache::remove(QObject *obj)
59{
60 // We have to use the inverse table to map the object address back to its ID,
61 // since at this point (called from QObject destructor), it has already been
62 // partially destroyed and we cannot treat it as a provider.
63 QMutexLocker guard{ &m_tableMutex };
64 auto it = m_inverseTable.find(obj);
65 if (it != m_inverseTable.end()) {
66 m_providerTable.remove(*it);
67 m_inverseTable.remove(obj);
68 }
69}
70
71QT_END_NAMESPACE
72
73#endif // QT_CONFIG(accessibility)