Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d014bdf
Aria details test use content editable
feerrenrut Oct 25, 2021
eb3579a
Use has details property rather than state
feerrenrut Nov 29, 2021
33e3be9
Expose nvdaInProcUtils_getTextFromIAccessible
feerrenrut Nov 3, 2021
756abb1
Move textFromIAccessible
feerrenrut Nov 29, 2021
c92a805
fix reused variable name
feerrenrut Nov 29, 2021
509c4e4
Add fetching and summarizing details relation.
feerrenrut Nov 3, 2021
c8dfb43
fixup! Add fetching and summarizing details relation.
feerrenrut Dec 4, 2021
3fc4155
fixup! Add fetching and summarizing details relation.
feerrenrut Dec 4, 2021
c831868
add tests for link nested in container with details
feerrenrut Dec 4, 2021
39038e2
Clarify readme
feerrenrut Dec 7, 2021
547e0f6
remove useNewText arg from RPC interface
feerrenrut Dec 7, 2021
3d280d7
fixup! add tests for link nested in container with details
feerrenrut Dec 7, 2021
b2be6e4
Report summary works with reviewCursor follows caret is false
feerrenrut Dec 9, 2021
4a7213b
fix braille output
feerrenrut Dec 9, 2021
6690f0c
demonstrate difference in jump to link from same/diferent lines
feerrenrut Dec 9, 2021
daa1343
Don't use F6 to refocus document
feerrenrut Dec 9, 2021
4ac3d1e
more specific typing for helperLocalBindingHandle
feerrenrut Dec 9, 2021
eca83fb
fixup! Use has details property rather than state
feerrenrut Dec 21, 2021
10d9727
fixup! remove useNewText arg from RPC interface
feerrenrut Dec 21, 2021
93a999c
fixup! Expose nvdaInProcUtils_getTextFromIAccessible
feerrenrut Dec 21, 2021
23b6aed
fixup! Add fetching and summarizing details relation.
feerrenrut Dec 21, 2021
6723b78
users who disable review follow caret typically disable review follow…
feerrenrut Jan 5, 2022
6ece690
add caretPos and caretObj snapshot vars to pythonconsole
feerrenrut Jan 5, 2022
77e201a
add tests for noVbufNoTextInterface
feerrenrut Jan 6, 2022
4023d9e
update useNewText param docs
feerrenrut Jan 6, 2022
dd8b2f9
fix doc strings and category
feerrenrut Jan 7, 2022
35feaac
review actions
feerrenrut Jan 7, 2022
7233c9c
fix lint
feerrenrut Jan 8, 2022
cf0de45
clarify settings/userguide
feerrenrut Jan 10, 2022
a02c98e
Merge remote-tracking branch 'origin/master' into reportAriaDetailsIn…
feerrenrut Jan 10, 2022
a211f0f
update changes file for PR #13106
feerrenrut Jan 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion nvdaHelper/common/ia2utils.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is a part of the NVDA project.
URL: http://www.nvda-project.org/
Copyright 2007-2019 NV Access Limited, Mozilla Corporation
Copyright 2007-2021 NV Access Limited, Mozilla Corporation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2.0, as published by
the Free Software Foundation.
Expand All @@ -15,9 +15,21 @@ This license can be found at:
#include <string>
#include <map>
#include "ia2utils.h"
#include <ia2.h>

using namespace std;

bool fetchIA2Attributes(IAccessible2* pacc2, map<wstring, wstring>& attribsMap) {
BSTR attribs = NULL;
pacc2->get_attributes(&attribs);
if (!attribs) {
return false;
}
IA2AttribsToMap(attribs, attribsMap);
SysFreeString(attribs);
return true;
}

void IA2AttribsToMap(const wstring &attribsString, map<wstring, wstring> &attribsMap) {
wstring str, key;
bool inEscape = false;
Expand Down
4 changes: 3 additions & 1 deletion nvdaHelper/common/ia2utils.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is a part of the NVDA project.
URL: http://www.nvda-project.org/
Copyright 2007-2019 NV Access Limited, Mozilla Corporation
Copyright 2007-2021 NV Access Limited, Mozilla Corporation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2.0, as published by
the Free Software Foundation.
Expand All @@ -21,6 +21,8 @@ This license can be found at:
#include <memory>
#include <ia2.h>

bool fetchIA2Attributes(IAccessible2* pacc2, std::map<std::wstring, std::wstring>& attribsMap);

/**
* Convert an IAccessible2 attributes string to a map of attribute keys and values.
* An IAccessible2 attributes string is of the form "name:value;name:value;...;"
Expand Down
3 changes: 2 additions & 1 deletion nvdaHelper/interfaces/nvdaInProcUtils/nvdaInProcUtils.acf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is a part of the NVDA project.
URL: http://www.nvda-project.org/
Copyright 2006-2010 NVDA contributers.
Copyright 2006-2021 NV Access Limited, Leonard de Ruijter
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2.0, as published by
the Free Software Foundation.
Expand All @@ -24,6 +24,7 @@ interface NvdaInProcUtils {
[fault_status,comm_status] getActiveObject();
[fault_status,comm_status] dumpOnCrash();
[fault_status,comm_status] IA2Text_findContentDescendant();
[fault_status,comm_status] getTextFromIAccessible();
[fault_status,comm_status] outlook_getMAPIProp();

[fault_status,comm_status] excel_getCellInfos();
Expand Down
19 changes: 17 additions & 2 deletions nvdaHelper/interfaces/nvdaInProcUtils/nvdaInProcUtils.idl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is a part of the NVDA project.
URL: http://www.nvda-project.org/
Copyright 2006-2020 NV Access Limited, Leonard de Ruijter.
Copyright 2006-2021 NV Access Limited, Leonard de Ruijter.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2.0, as published by
the Free Software Foundation.
Expand All @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
cpp_quote("/*")
cpp_quote("This file is a part of the NVDA project.")
cpp_quote("URL: http://www.nvda-project.org/")
cpp_quote("Copyright 2006-2020 NV Access Limited, Leonard de Ruijter.")
cpp_quote("Copyright 2006-2021 NV Access Limited, Leonard de Ruijter.")
cpp_quote("This program is free software: you can redistribute it and/or modify")
cpp_quote("it under the terms of the GNU General Public License version 2.0, as published by")
cpp_quote("the Free Software Foundation.")
Expand Down Expand Up @@ -74,6 +74,21 @@ interface NvdaInProcUtils {

error_status_t IA2Text_findContentDescendant([in] handle_t bindingHandle, [in] const unsigned long hwnd, [in] long parentID, [in] long what, [out] long* descendantID, [out] long* descendantOffset);


cpp_quote("/* Actually maps to nvdaInProcUtils_getTextFromIAccessible")
cpp_quote("*/")
error_status_t getTextFromIAccessible(
[in] handle_t bindingHandle,
[in] const unsigned long hwnd,
[in] long parentID,
// Params for getTextFromIAccessible
[out, string] BSTR* textBuf,
[in, defaultvalue(TRUE)] const boolean recurse,
[in, defaultvalue(TRUE)] const boolean includeTopLevelText
);



/*
* Fetches the requested property from the given MAPIProp object.
* @param threadID the threadID of the Outlook GUI thread where the MAPI object came from.
Expand Down
1 change: 1 addition & 0 deletions nvdaHelper/local/nvdaHelperLocal.def
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ EXPORTS
nvdaInProcUtils_sysListView32_getColumnContent
nvdaInProcUtils_dumpOnCrash
nvdaInProcUtils_IA2Text_findContentDescendant
nvdaInProcUtils_getTextFromIAccessible
nvdaInProcUtils_getActiveObject
nvdaInProcUtils_winword_expandToLine
nvdaInProcUtils_winword_getTextInRange
Expand Down
26 changes: 26 additions & 0 deletions nvdaHelper/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ This cache is called a virtual buffer.
While virtual buffers apply to several different application types, it may first be easiest to think about how they
work with browsers, the rest of this document will take a web browser centric view unless specified otherwise.

### Output
Internal code is built into three DLLs:
- `nvdaHelperLocal.dll`
- `nvdaHelperLocalWin10.dll`
- `nvdaHelperRemote.dll`

Several COM Proxy DLLs are built from IDL files. A COM Proxy tells windows how to marshal data over COM when calling
the target API interface.
For instance:
- IAccessible2 IDL files are built into `IAccessible2Proxy.dll`
- ISimpleDOM IDL files are built into `ISimpleDOM.dll`

The `*local*.dll`'s are built for x86 (ie to match NVDA's arch), others are built for x86, x64, and arm64.

### Configuring Visual Studio
The following steps won't prepare a buildable solution, but it will enable intellisense.
You should still build on the command line to verify errors.
Expand Down Expand Up @@ -71,3 +85,15 @@ When `fillVBuf` is called, it recursively descends through the child elements th
`controlFieldNode`s or `textFieldNode`s for them.
This code is responsible for interacting with the IA2 accessibility API, these calls should be minimised for
performance reasons.


### Overview of calling to remote code.

- NVDA's python code calls into the local DLL (`NVDAHelperLocal.dll`).
- Generated RPC Wrappers are called
- The RPC Wrappers call through to the "remote in-process DLL" (ie `nvdaHelperRemote.dll`)

#### Build notes
IDL/ACF files are input to MSRPCStubs to generate headers in `build/<arch>`
- See `MSRPCStubs` in `*scons*` files.
- Note these set a prefix, making whole word searches for methods difficult.
118 changes: 100 additions & 18 deletions nvdaHelper/remote/IA2Support.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is a part of the NVDA project.
URL: http://www.nvda-project.org/
Copyright 2006-2010 NVDA contributers.
Copyright 2006-2021 NV Access Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2.0, as published by
the Free Software Foundation.
Expand All @@ -26,6 +26,8 @@ This license can be found at:
#include <remote/nvdaInProcUtils.h>
#include "COMProxyRegistration.h"
#include "IA2Support.h"
#include <atlcomcli.h>
#include "textFromIAccessible.h"

using namespace std;

Expand Down Expand Up @@ -251,26 +253,106 @@ bool findContentDescendant(IAccessible2* pacc2, long what, long* descendantID, l
return foundDescendant;
}


CComPtr<IAccessible2> getIA2(const HWND hwnd, const long parentID) {
VARIANT varChild;
CComPtr<IAccessible> pacc;
AccessibleObjectFromEvent(
hwnd,
OBJID_CLIENT,
parentID,
&pacc.p,
&varChild
);

if (!pacc) {
return nullptr;
};

CComQIPtr<IServiceProvider, &IID_IServiceProvider> pserv(pacc);
if (!pserv) {
return nullptr;
}

CComPtr<IAccessible2> pacc2;
{ // scoping for: ppvObject
void** ppvObject = reinterpret_cast<void**>(&pacc2.p);
pserv->QueryService(IID_IAccessible, IID_IAccessible2, ppvObject);
}

return pacc2;
}

error_status_t nvdaInProcUtils_IA2Text_findContentDescendant(handle_t bindingHandle, const unsigned long windowHandle, long parentID, long what, long* descendantID, long* descendantOffset) {
HWND hwnd=(HWND)UlongToHandle(windowHandle);
HWND hwnd = static_cast<HWND>(UlongToHandle(windowHandle));
auto func=[&] {
IAccessible* pacc=NULL;
VARIANT varChild;
AccessibleObjectFromEvent((HWND)hwnd,OBJID_CLIENT,parentID,&pacc,&varChild);
if(!pacc) return;
IAccessible2* pacc2=NULL;
IServiceProvider* pserv=NULL;
pacc->QueryInterface(IID_IServiceProvider,(void**)&pserv);
pacc->Release();
if(!pserv) return;
pserv->QueryService(IID_IAccessible,IID_IAccessible2,(void**)&pacc2);
pserv->Release();
if(!pacc2) return;
findContentDescendant(pacc2,what,descendantID,descendantOffset);
pacc2->Release();
auto pacc2 = getIA2(hwnd, parentID);
if (!pacc2) {
return;
}
findContentDescendant(pacc2, what, descendantID, descendantOffset);
};

auto windowThreadProcId = GetWindowThreadProcessId(hwnd, nullptr);
auto res = execInThread(windowThreadProcId, func);
if(!res) {
LOG_DEBUGWARNING(L"Could not execute findContentDescendant in UI thread");
}
return 0;
}


error_status_t nvdaInProcUtils_getTextFromIAccessible(
handle_t bindingHandle,
const unsigned long windowHandle,
long parentID,
// Params for getTextFromIAccessible
BSTR* outBuf,
const boolean recurse,
const boolean includeTopLevelText
) {
LOG_DEBUG(L"Called nvdaInProcUtils_getTextFromIAccessible");
if (outBuf == nullptr) {
LOG_ERROR(L"outBuff is null.");
return 0;
}
HWND hwnd = static_cast<HWND>(UlongToHandle(windowHandle));
auto func = [&] () -> void{
auto pacc2 = getIA2(hwnd, parentID);
if (!pacc2) {
return;
}
wstring textBuf;
const auto gotText = getTextFromIAccessible(
textBuf,
pacc2,
false, // useNewText, only valid in response to an event (indicating changing text)
recurse,
includeTopLevelText
);
if (!gotText) {
LOG_DEBUGWARNING(L"Unable to get text.");
return;
}
if (textBuf.empty()) {
LOG_DEBUGWARNING(L"textBuf empty.");
return;
}
auto copySize = size_t(std::numeric_limits<UINT>::max);
if (copySize < textBuf.size()) {
LOG_ERROR(L"Size of buffer larger than can be allocated with SysAllocStringLen, buffer will be truncated.");
}
else {
copySize = textBuf.size();
}
*outBuf = SysAllocStringLen(textBuf.data(), UINT(copySize));
return;
};
if(!execInThread(GetWindowThreadProcessId(hwnd,NULL),func)) {
LOG_DEBUGWARNING(L"Could not execute findContentDescendant in UI thread");

auto windowThreadProcId = GetWindowThreadProcessId(hwnd, nullptr);
auto res = execInThread(windowThreadProcId, func);
if (!res) {
LOG_DEBUGWARNING(L"Could not execute getTextFromIAccessible in UI thread");
}
return 0;
}
Loading