QWinRTUia*: remove anti-pattern passing new'ed QSharedPointer into lambdas
QSharedPointer is made for passing around by value. It is unclear why
in so many repeated cases a QSharedPointer is created on the stack,
then a copy of it is new'ed up, passed into a lambda to be deleted
inside it.
First, it requires an additional heap allocation. Because it's passed
as a raw pointer to QSharedPointer, however, there's also always the
danger that it's leaked by seemingly-innocuous changes such as adding
an early return from the lambda (and some of them could really use
one, with the ifs nesting several levels deep).
All this is not needed, though. It's perfectly ok to store a copy of a
QSharedPointer, by value, in a lambda, and keep one copy outside
it. Poor man's std::future, if you will.
So, do away with all that, just pass the shared pointer by value into
the lambda, and, as a drive-by, replace some ephemeral QLists with
QVLAs. In one case, replace a QPair<int, int> with a struct to make
the code using that type more accessible ('first' and 'second' are
really, really bad variable names if they, in fact, represent
'startOffset' and 'endOffset').
Also port directly to shared_ptr / make_shared. Saves one memory
allocation each, due to the co-allocation of payload and control
block, and even though there's QSharedPointer::create, which does
this, too, std::shared_ptr is simply much lighter on the use of
atomics (copying a QSP ups two ref counts, copying a std::shared_ptr
just one). Since these variables live behind the API boundary, there's
no reason not to prefer the more efficient alternative.
Change-Id: I4b9fe30e56df5106fc2ab7a0b55b2b8316cca5fe
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
bb10
parent
c0b3c06a7d
commit
b1698e9bc2
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -105,19 +107,17 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ContainingGrid(IIRawEle
|
|||
*value = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
|
||||
auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
|
||||
auto elementId = std::make_shared<QAccessible::Id>(0);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
|
||||
if (QAccessibleInterface *table = tableCellInterface->table()) {
|
||||
**ptrElementId = idForAccessible(table);
|
||||
QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
|
||||
*elementId = idForAccessible(table);
|
||||
QWinRTUiaMetadataCache::instance()->load(*elementId);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementId;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -104,21 +106,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::GetItem(INT32 row, INT32 column
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
|
||||
auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
|
||||
auto elementId = std::make_shared<QAccessible::Id>(0);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, ptrElementId]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, elementId]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
|
||||
if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) {
|
||||
if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) {
|
||||
**ptrElementId = idForAccessible(cell);
|
||||
QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
|
||||
*elementId = idForAccessible(cell);
|
||||
QWinRTUiaMetadataCache::instance()->load(*elementId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementId;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@
|
|||
#include <QtCore/qfunctions_winrt.h>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
|
|
@ -179,7 +181,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderForAccessibleId(QAccessible::Id elemen
|
|||
}
|
||||
|
||||
// Returns an array of IIRawElementProviderSimple instances for a list of accessible interface ids.
|
||||
HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds,
|
||||
HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds,
|
||||
UINT32 *returnValueSize,
|
||||
IIRawElementProviderSimple ***returnValue)
|
||||
{
|
||||
|
|
@ -190,7 +192,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<Q
|
|||
|
||||
QList<IIRawElementProviderSimple *> rawProviderList;
|
||||
|
||||
for (auto elementId : qAsConst(elementIds)) {
|
||||
for (auto elementId : elementIds) {
|
||||
IIRawElementProviderSimple *rawProvider;
|
||||
if (SUCCEEDED(rawProviderForAccessibleId(elementId, &rawProvider)))
|
||||
rawProviderList.append(rawProvider);
|
||||
|
|
@ -515,10 +517,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto children = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrChildren = new QSharedPointer<QList<QAccessible::Id>>(children);
|
||||
auto children = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrChildren]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, children]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
int childCount = accessible->childCount();
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
|
|
@ -526,11 +527,10 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
|
|||
QAccessible::Id childId = idForAccessible(childAcc);
|
||||
QWinRTUiaMetadataCache::instance()->load(childId);
|
||||
if (!childAcc->state().invisible)
|
||||
(*ptrChildren)->append(childId);
|
||||
children->append(childId);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrChildren;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -538,7 +538,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
|
|||
|
||||
ComPtr<IVector<AutomationPeer *>> peerVector = Make<QWinRTUiaPeerVector>();
|
||||
|
||||
for (auto childId : qAsConst(*children)) {
|
||||
for (auto childId : *children) {
|
||||
if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(childId)) {
|
||||
IAutomationPeer *peer;
|
||||
if (SUCCEEDED(provider.CopyTo(&peer)))
|
||||
|
|
@ -750,10 +750,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
|
|||
// Scale coordinates from High DPI screens?
|
||||
|
||||
auto accid = id();
|
||||
auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
|
||||
auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
|
||||
auto elementId = std::make_shared<QAccessible::Id>(0);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId, point]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId, point]() {
|
||||
// Controls can be embedded within grouping elements. By default returns the innermost control.
|
||||
QAccessibleInterface *target = accessibleForId(accid);
|
||||
while (QAccessibleInterface *tmpacc = target->childAt(point.X, point.Y)) {
|
||||
|
|
@ -761,9 +760,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
|
|||
// For accessibility tools it may be better to return the text element instead of its subcomponents.
|
||||
if (target->textInterface()) break;
|
||||
}
|
||||
**ptrElementId = idForAccessible(target);
|
||||
QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
|
||||
delete ptrElementId;
|
||||
*elementId = idForAccessible(target);
|
||||
QWinRTUiaMetadataCache::instance()->load(*elementId);
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public:
|
|||
virtual ~QWinRTUiaMainProvider();
|
||||
static QWinRTUiaMainProvider *providerForAccessibleId(QAccessible::Id id);
|
||||
static HRESULT rawProviderForAccessibleId(QAccessible::Id elementId, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue);
|
||||
static HRESULT rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
|
||||
static HRESULT rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
|
||||
static void notifyFocusChange(QAccessibleEvent *event);
|
||||
static void notifyVisibilityChange(QAccessibleEvent *event);
|
||||
static void notifyStateChange(QAccessibleStateChangeEvent *event);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -94,21 +96,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_SelectionContainer
|
|||
*value = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
|
||||
auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
|
||||
auto elementId = std::make_shared<QAccessible::Id>(0);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
// Radio buttons do not require a container.
|
||||
if (accessible->role() == QAccessible::ListItem) {
|
||||
if (QAccessibleInterface *parent = accessible->parent()) {
|
||||
if (parent->role() == QAccessible::List) {
|
||||
**ptrElementId = idForAccessible(parent);
|
||||
*elementId = idForAccessible(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementId;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -89,10 +91,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
|
|||
*value = false;
|
||||
|
||||
auto accid = id();
|
||||
auto selectionRequired = QSharedPointer<bool>(new bool(false));
|
||||
auto ptrSelectionRequired = new QSharedPointer<bool>(selectionRequired);
|
||||
auto selectionRequired = std::make_shared<bool>(false);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelectionRequired]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selectionRequired]() {
|
||||
// Initially returns false if none are selected. After the first selection, it may be required.
|
||||
bool anySelected = false;
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
|
|
@ -105,9 +106,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
|
|||
}
|
||||
}
|
||||
}
|
||||
**ptrSelectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
|
||||
*selectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
|
||||
}
|
||||
delete ptrSelectionRequired;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -128,10 +128,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
int childCount = accessible->childCount();
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
|
|
@ -139,12 +138,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
|
|||
if (childAcc->state().selected) {
|
||||
QAccessible::Id childId = idForAccessible(childAcc);
|
||||
QWinRTUiaMetadataCache::instance()->load(childId);
|
||||
(*ptrElementIds)->append(childId);
|
||||
elementIds->append(childId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -79,21 +81,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetColumnHeaderItems(UINT3
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
|
||||
QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
|
||||
for (auto header : qAsConst(headers)) {
|
||||
QAccessible::Id headerId = idForAccessible(header);
|
||||
QWinRTUiaMetadataCache::instance()->load(headerId);
|
||||
(*ptrElementIds)->append(headerId);
|
||||
elementIds->append(headerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -113,21 +113,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetRowHeaderItems(UINT32 *
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
|
||||
QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
|
||||
for (auto header : qAsConst(headers)) {
|
||||
QAccessible::Id headerId = idForAccessible(header);
|
||||
QWinRTUiaMetadataCache::instance()->load(headerId);
|
||||
(*ptrElementIds)->append(headerId);
|
||||
elementIds->append(headerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -91,10 +93,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
|
||||
for (int i = 0; i < tableInterface->columnCount(); ++i) {
|
||||
|
|
@ -105,14 +106,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
|
|||
for (auto header : qAsConst(headers)) {
|
||||
QAccessible::Id headerId = idForAccessible(header);
|
||||
QWinRTUiaMetadataCache::instance()->load(headerId);
|
||||
(*ptrElementIds)->append(headerId);
|
||||
elementIds->append(headerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -132,10 +132,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
|
||||
for (int i = 0; i < tableInterface->rowCount(); ++i) {
|
||||
|
|
@ -146,14 +145,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
|
|||
for (auto header : qAsConst(headers)) {
|
||||
QAccessible::Id headerId = idForAccessible(header);
|
||||
QWinRTUiaMetadataCache::instance()->load(headerId);
|
||||
(*ptrElementIds)->append(headerId);
|
||||
elementIds->append(headerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -104,26 +106,26 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
|
|||
*returnValueSize = 0;
|
||||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto selections = QSharedPointer<QList<QPair<int,int>>>(new QList<QPair<int,int>>);
|
||||
auto ptrSelections = new QSharedPointer<QList<QPair<int,int>>>(selections);
|
||||
struct Selection { int startOffset, endOffset; };
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelections]() {
|
||||
auto accid = id();
|
||||
auto selections = std::make_shared<QVarLengthArray<Selection>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selections]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
|
||||
for (int i = 0; i < textInterface->selectionCount(); ++i) {
|
||||
QPair<int,int> sel;
|
||||
textInterface->selection(i, &sel.first, &sel.second);
|
||||
(*ptrSelections)->append(sel);
|
||||
int startOffset, endOffset;
|
||||
textInterface->selection(i, &startOffset, &endOffset);
|
||||
selections->append({startOffset, endOffset});
|
||||
}
|
||||
if ((*ptrSelections)->size() == 0) {
|
||||
if (selections->size() == 0) {
|
||||
// If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
|
||||
QPair<int,int> sel(textInterface->cursorPosition(), textInterface->cursorPosition());
|
||||
(*ptrSelections)->append(sel);
|
||||
auto cur = textInterface->cursorPosition();
|
||||
selections->append({cur, cur});
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrSelections;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -137,9 +139,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
|
|||
if (!providerArray)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
for (int i = 0; i < selCount; ++i) {
|
||||
ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), (*selections)[i].first, (*selections)[i].second);
|
||||
textRangeProvider.CopyTo(&providerArray[i]);
|
||||
auto dst = providerArray;
|
||||
for (auto sel : *selections) {
|
||||
ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider
|
||||
= Make<QWinRTUiaTextRangeProvider>(id(), sel.startOffset, sel.endOffset);
|
||||
textRangeProvider.CopyTo(dst++);
|
||||
}
|
||||
*returnValueSize = selCount;
|
||||
*returnValue = providerArray;
|
||||
|
|
@ -184,14 +188,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromPoint(ABI::Windows::Fo
|
|||
|
||||
const QPoint pt(screenLocation.X, screenLocation.Y);
|
||||
auto accid = id();
|
||||
auto offset = QSharedPointer<int>(new int);
|
||||
auto ptrOffset = new QSharedPointer<int>(offset);
|
||||
auto offset = std::make_shared<int>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, ptrOffset]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, offset]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid))
|
||||
if (QAccessibleTextInterface *textInterface = accessible->textInterface())
|
||||
**ptrOffset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
|
||||
delete ptrOffset;
|
||||
*offset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -212,10 +214,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
|
|||
auto accid = id();
|
||||
auto startOffset = m_startOffset;
|
||||
auto endOffset = m_endOffset;
|
||||
auto rects = QSharedPointer<QList<QRect>>(new QList<QRect>);
|
||||
auto ptrRects = new QSharedPointer<QList<QRect>>(rects);
|
||||
auto rects = std::make_shared<QVarLengthArray<QRect>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, ptrRects]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, rects]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
|
||||
int len = textInterface->characterCount();
|
||||
|
|
@ -233,7 +234,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
|
|||
qMin(startRect.y(), endRect.y()),
|
||||
qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
|
||||
qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
|
||||
(*ptrRects)->append(lineRect);
|
||||
rects->append(lineRect);
|
||||
}
|
||||
if (end >= len) break;
|
||||
textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end);
|
||||
|
|
@ -241,7 +242,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
|
|||
}
|
||||
}
|
||||
}
|
||||
delete ptrRects;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -251,11 +251,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
|
|||
if (!doubleArray)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
for (int i = 0; i < rects->size(); ++i) {
|
||||
doubleArray[i*4] = (*rects)[i].left();
|
||||
doubleArray[i*4+1] = (*rects)[i].top();
|
||||
doubleArray[i*4+2] = (*rects)[i].width();
|
||||
doubleArray[i*4+3] = (*rects)[i].height();
|
||||
DOUBLE *dst = doubleArray;
|
||||
for (auto rect : *rects) {
|
||||
*dst++ = rect.left();
|
||||
*dst++ = rect.top();
|
||||
*dst++ = rect.width();
|
||||
*dst++ = rect.height();
|
||||
}
|
||||
*returnValue = doubleArray;
|
||||
*returnValueSize = 4 * rects->size();
|
||||
|
|
|
|||
Loading…
Reference in New Issue