Hi, I am the original creator of the ticket, and have been following it. So, was this e-mail sent to the NVDA Addons list by mistake, I think it should have been sent to NVDA Devel. Or is #4354 being implemented as an addon and will not be implementd in NVDA itself? Am I missing anything? On 10/27/14, Joseph Lee <joseph.lee22590@xxxxxxxxx> wrote: > Hi Noelia, > I've merged latest master branch code from NV Access server, so you can work > from latest revisions. > Cheers, > Joseph > > -----Original Message----- > From: nvda-addons-commits-bounce@xxxxxxxxxxxxx > [mailto:nvda-addons-commits-bounce@xxxxxxxxxxxxx] On Behalf Of > commits-noreply@xxxxxxxxxxxxx > Sent: Sunday, October 26, 2014 3:28 PM > To: nvda-addons-commits@xxxxxxxxxxxxx > Subject: commit/nvda: josephsl: Merge branch 'master' into t4354 > > 1 new commit in nvda: > > https://bitbucket.org/nvdaaddonteam/nvda/commits/ddd4982e4dfe/ > Changeset: ddd4982e4dfe > Branch: t4354 > User: josephsl > Date: 2014-10-26 22:27:58+00:00 > Summary: Merge branch 'master' into t4354 > > Affected #: 34 files > > diff --git a/contributors.txt b/contributors.txt > index 615b079..51d90a1 100644 > --- a/contributors.txt > +++ b/contributors.txt > @@ -146,3 +146,6 @@ Dr. Mireia Ribera > Ruben Alcaraz > Nikos Demetriou > Daniel Johansson > +Manish Agrawal > +Aaron Cannon > +derek riemer > > diff --git a/include/liblouis b/include/liblouis > index 1e1e758..5f9c03f 160000 > --- a/include/liblouis > +++ b/include/liblouis > @@ -1 +1 @@ > -Subproject commit 1e1e7587cfbc263b351644e52fdaf2684103d6c8 > +Subproject commit 5f9c03f2a3478561deb6ae4798175094be8a26c2 > > diff --git a/include/minhook b/include/minhook > index e21b54a..ed5b511 160000 > --- a/include/minhook > +++ b/include/minhook > @@ -1 +1 @@ > -Subproject commit e21b54a88190ca477ed73fb7ab24203dfaef28a0 > +Subproject commit ed5b5119afb4127dd66905e2899c3265d8040aea > > diff --git a/miscDeps b/miscDeps > index 6fbd449..eee6560 160000 > --- a/miscDeps > +++ b/miscDeps > @@ -1 +1 @@ > -Subproject commit 6fbd44904c8debe4cf5a73e62a91ac8a00d1860c > +Subproject commit eee6560e4ae4de5455e94dfb99ba596f36bb21f5 > > diff --git a/nvdaHelper/archBuild_sconscript > b/nvdaHelper/archBuild_sconscript > index 1c63dcc..fd45e07 100644 > --- a/nvdaHelper/archBuild_sconscript > +++ b/nvdaHelper/archBuild_sconscript > @@ -26,6 +26,7 @@ Import( > TARGET_ARCH=env['TARGET_ARCH'] > debug=env['nvdaHelperDebugFlags'] > release=env['release'] > +signExec=env['signExec'] if env['certFile'] else None > > #Some defines and includes for the environment > env.Append(CPPDEFINES=['UNICODE','_CRT_SECURE_NO_DEPRECATE',('LOGLEVEL','${nvdaHelperLogLevel}'),('_WIN32_WINNT','_WIN32_WINNT_WINXP')]) > @@ -66,6 +67,8 @@ if TARGET_ARCH=='x86': > > ia2RPCStubs=env.SConscript('ia2_sconscript') > Export('ia2RPCStubs') > +if signExec: > + env.AddPostAction(ia2RPCStubs[0],[signExec]) > env.Install(libInstallDir,ia2RPCStubs[0]) #proxy dll > if TARGET_ARCH=='x86': > env.Install(sourceTypelibDir,ia2RPCStubs[1]) #typelib > @@ -73,43 +76,65 @@ if TARGET_ARCH=='x86': > if TARGET_ARCH=='x86': > localLib=env.SConscript('local/sconscript') > Export('localLib') > + if signExec: > + env.AddPostAction(localLib[0],[signExec]) > env.Install(libInstallDir,localLib) > > clientLib=env.SConscript('client/sconscript') > Export('clientLib') > +if signExec: > + env.AddPostAction(clientLib[0],[signExec]) > env.Install(clientInstallDir,clientLib) > > minHookLib=env.SConscript('minHook/sconscript') > Export('minHookLib') > +if signExec: > + env.AddPostAction(minHookLib[0],[signExec]) > env.Install(libInstallDir,minHookLib) > > remoteLib=env.SConscript('remote/sconscript') > Export('remoteLib') > +if signExec: > + env.AddPostAction(remoteLib[0],[signExec]) > env.Install(libInstallDir,remoteLib) > > if TARGET_ARCH=='x86_64': > remoteLoaderProgram=env.SConscript('remoteLoader/sconscript') > + if signExec: > + env.AddPostAction(remoteLoaderProgram,[signExec]) > env.Install(libInstallDir,remoteLoaderProgram) > > vbufBaseStaticLib=env.SConscript('vbufBase/sconscript') > Export('vbufBaseStaticLib') > > adobeAcrobatVBufBackend=env.SConscript('vbufBackends/adobeAcrobat/sconscript') > +if signExec: > + env.AddPostAction(adobeAcrobatVBufBackend[0],[signExec]) > env.Install(libInstallDir,adobeAcrobatVBufBackend) > > adobeFlashVBufBackend=env.SConscript('vbufBackends/adobeFlash/sconscript') > +if signExec: > + env.AddPostAction(adobeFlashVBufBackend[0],[signExec]) > env.Install(libInstallDir,adobeFlashVBufBackend) > > lotusNotesRichTextVBufBackend=env.SConscript('vbufBackends/lotusNotesRichText/sconscript') > +if signExec: > + env.AddPostAction(lotusNotesRichTextVBufBackend[0],[signExec]) > env.Install(libInstallDir,lotusNotesRichTextVBufBackend) > > geckoVBufBackend=env.SConscript('vbufBackends/gecko_ia2/sconscript') > +if signExec: > + env.AddPostAction(geckoVBufBackend[0],[signExec]) > env.Install(libInstallDir,geckoVBufBackend) > > mshtmlVBufBackend=env.SConscript('vbufBackends/mshtml/sconscript') > +if signExec: > + env.AddPostAction(mshtmlVBufBackend[0],[signExec]) > env.Install(libInstallDir,mshtmlVBufBackend) > > webKitVBufBackend=env.SConscript('vbufBackends/webKit/sconscript') > +if signExec: > + env.AddPostAction(webKitVBufBackend[0],[signExec]) > env.Install(libInstallDir,webKitVBufBackend) > > if TARGET_ARCH=='x86': > > diff --git a/nvdaHelper/building.txt b/nvdaHelper/building.txt > deleted file mode 100644 > index 09cc81f..0000000 > --- a/nvdaHelper/building.txt > +++ /dev/null > @@ -1,45 +0,0 @@ > -Build Instructions > - > -Prerequisites: > - > -NVDAHelper needs The Microsoft Windows SDK, version 6.1 or later. You can > find it here: > -http://msdn.microsoft.com/en-us/windows/bb980924.aspx > - > - The gecko_ia2 virtual buffer backend requires the IAccessible2 IDL, > version 1.2 or later. You can obtain it here: > -http://www.linuxfoundation.org/en/Accessibility/IAccessible2 > -Download the merged IDL and copy it to ..\include\ia2\ia2.idl. > - > -The adobeAcrobat virtual buffer backend requires the Adobe Acrobat > accessibility IDL, version 9.1 or later. This can be found in the client > files archive available from > http://www.adobe.com/devnet/acrobat/interapplication_communication.html > -The archive is named something like Acrobat_Accessibility_9.1.zip. > -Extract the AcrobatAccess.idl file into ..\include\AcrobatAccess. > - > -The apiHook module requires MinHook 1.1.0 or later: > http://www.codeproject.com/KB/winsdk/LibMinHook.aspx > - * Download the source archive. The file name is something like > MinHook_110_src.zip depending on exact version. > - * You will need an account on CodeProject to download from there. > - * extract the source archive, and from it copy the libMinHook directory > to > NVDA's source/include directory. > - > -minHook (and possibly in future nvdaHelper) depends on the Boost c++ > library 1.42 or later: > - * you can download the latest Windows installer from > http://www.boostpro.com/download > - * On the components page of the installer, make sure to install all the > defaults (what ever is already checked), along with anything else you may > wish to have for other projects. > - * So far only boost headers are used, none of the pre-compiled libraries > are necessary for nvda/minHook. > - > -The NVDAHelper build is managed by the SCons build system, version 1.3.0 or > later: http://www.scons.org/ > - > -Building the library: > - > -There is no need to use the MSVC environment command prompt when building, > as scons will locate what it needs automatically in any standard > environment. > - > -To build and install the library and all virtual buffer backends, open a > command prompt, cd to the top-level directory of nvdaHelper and run the > command: > -scons install > -By default a version with debugging symbols will be generated. To build a > release version, provide release=1 on the command line when running scons: > -scons install release=1 > - > -Note that now both x86 and x64 versions of the libraries are automatically > built, there is no need to supply any target arch variables by default. > - > -However, if you specifically only want to build certain architectures, you > can provide a comma separated list of the required architectures to the > targetArchitectures variable on the commandline, like so: > -scons targetArchitectures=x86 > -or > -scons targetArchitectures=x86_64 > -or > -scons targetArchitectures=x86,x86_64 > - > \ No newline at end of file > > diff --git a/nvdaHelper/contributors.txt b/nvdaHelper/contributors.txt > deleted file mode 100755 > index 5c0a415..0000000 > --- a/nvdaHelper/contributors.txt > +++ /dev/null > @@ -1,3 +0,0 @@ > -Michael Curran <mick@xxxxxxxxxx> > -James Teh <jamie@xxxxxxxxxxx> > -Aleksey Sadovoy <lex@xxxxxx> > > diff --git a/nvdaHelper/liblouis/sconscript > b/nvdaHelper/liblouis/sconscript > index 72cdef4..1050407 100644 > --- a/nvdaHelper/liblouis/sconscript > +++ b/nvdaHelper/liblouis/sconscript > @@ -24,7 +24,7 @@ louisRootDir = env.Dir("#include/liblouis") > louisSourceDir = louisRootDir.Dir("liblouis") > outDir = sourceDir.Dir("louis") > > -RE_AC_INIT = re.compile(r"^AC_INIT\((?P<name>.*), (?P<version>.*), > (?P<maintainer>.*)\)") > +RE_AC_INIT = re.compile(r"^AC_INIT\(\[(?P<package>.*)\], > \[(?P<version>.*)\], \[(?P<bugReport>.*)\], \[(?P<tarName>.*)\], > \[(?P<url>.*)\]\)") > def getLouisVersion(): > # Get the version from configure.ac. > with file(louisRootDir.File("configure.ac").abspath) as f: > @@ -50,6 +50,7 @@ sourceFiles = [ > "lou_translateString.c", > "lou_backTranslateString.c", > "wrappers.c", > + "logging.c", > ] > objs = [env.Object("%s.obj" % f, louisSourceDir.File(f)) for f in > sourceFiles] > louisLib = env.SharedLibrary("liblouis", objs + ["liblouis.def"]) > > diff --git a/nvdaHelper/minHook/dllmain.cpp > b/nvdaHelper/minHook/dllmain.cpp > index 25d6823..07a9e41 100644 > --- a/nvdaHelper/minHook/dllmain.cpp > +++ b/nvdaHelper/minHook/dllmain.cpp > @@ -18,7 +18,7 @@ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html > BOOL WINAPI DllMain(HINSTANCE hModule,DWORD reason,LPVOID lpReserved) { > //Process exiting, we must clean up any pending hooks > if(reason==DLL_PROCESS_DETACH&&lpReserved) { > - if(MH_DisableAllHooks()!=MH_ERROR_NOT_INITIALIZED) { > + if(MH_DisableHook(MH_ALL_HOOKS)!=MH_ERROR_NOT_INITIALIZED) { > //Give enough time for all hook functions to complete. > Sleep(250); > MH_Uninitialize(); > > diff --git a/nvdaHelper/minHook/sconscript b/nvdaHelper/minHook/sconscript > index 497a242..886b606 100644 > --- a/nvdaHelper/minHook/sconscript > +++ b/nvdaHelper/minHook/sconscript > @@ -19,10 +19,11 @@ sourceFiles=[ > > objFiles=[env.Object('_minHook_%s.obj'%x.replace('/','_'),minhookPath.File('src/%s'%x)) > for x in sourceFiles] > objFiles.append('dllmain.cpp') > +resFile=env.RES('_minHook',minhookPath.File('dll_resources/minHook.rc')) > > minHookLib=env.SharedLibrary( > target='minHook', > - source=objFiles+[minhookPath.File('dll_resources/minHook.def')], > + source=objFiles+[resFile,minhookPath.File('dll_resources/minHook.def')], > ) > > Return('minHookLib') > > diff --git a/nvdaHelper/remote/apiHook.cpp b/nvdaHelper/remote/apiHook.cpp > index 0a3430b..4c9848e 100644 > --- a/nvdaHelper/remote/apiHook.cpp > +++ b/nvdaHelper/remote/apiHook.cpp > @@ -39,8 +39,6 @@ typedef MH_STATUS(WINAPI *MH_Uninitialize_funcType)(); > typedef MH_STATUS(WINAPI *MH_CreateHook_funcType)(void*,void*,void**); > typedef MH_STATUS(WINAPI *MH_EnableHook_funcType)(void*); > typedef MH_STATUS(WINAPI *MH_DisableHook_funcType)(void*); > -typedef MH_STATUS(*MH_EnableAllHooks_funcType)(); > -typedef MH_STATUS(*MH_DisableAllHooks_funcType)(); > > #define defMHFP(funcName) funcName##_funcType funcName##_fp=NULL > > @@ -55,8 +53,8 @@ typedef MH_STATUS(*MH_DisableAllHooks_funcType)(); > defMHFP(MH_Initialize); > defMHFP(MH_Uninitialize); > defMHFP(MH_CreateHook); > -defMHFP(MH_EnableAllHooks); > -defMHFP(MH_DisableAllHooks); > +defMHFP(MH_EnableHook); > +defMHFP(MH_DisableHook); > > bool apiHook_initialize() { > LOG_DEBUG("calling MH_Initialize"); > @@ -71,8 +69,8 @@ defMHFP(MH_DisableAllHooks); > setMHFP(MH_Initialize); > setMHFP(MH_Uninitialize); > setMHFP(MH_CreateHook); > - setMHFP(MH_EnableAllHooks); > - setMHFP(MH_DisableAllHooks); > + setMHFP(MH_EnableHook); > + setMHFP(MH_DisableHook); > if(error_setNHFP) { > LOG_ERROR(L"Error setting minHook function pointers"); > FreeLibrary(minhookLibHandle); > @@ -124,7 +122,7 @@ bool apiHook_enableHooks() { > LOG_ERROR(L"apiHooks not initialized"); > return false; > } > - res=MH_EnableAllHooks_fp(); > + res=MH_EnableHook_fp(MH_ALL_HOOKS); > nhAssert(res==MH_OK); > return TRUE; > } > @@ -137,7 +135,7 @@ bool apiHook_terminate() { > LOG_ERROR(L"apiHooks not initialized"); > return false; > } > - res=MH_DisableAllHooks_fp(); > + res=MH_DisableHook_fp(MH_ALL_HOOKS); > nhAssert(res==MH_OK); > g_hookedFunctions.clear(); > //Give enough time for all hook functions to complete. > > diff --git a/nvdaHelper/remote/ia2LiveRegions.cpp > b/nvdaHelper/remote/ia2LiveRegions.cpp > index a3c584d..df389fe 100644 > --- a/nvdaHelper/remote/ia2LiveRegions.cpp > +++ b/nvdaHelper/remote/ia2LiveRegions.cpp > @@ -23,6 +23,17 @@ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html > > 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; > +} > + > IAccessible2* findAriaAtomic(IAccessible2* pacc2,map<wstring,wstring>& > attribsMap) { > map<wstring,wstring>::iterator i=attribsMap.find(L"atomic"); > bool atomic=(i!=attribsMap.end()&&i->second.compare(L"true")==0); > @@ -38,12 +49,8 @@ IAccessible2* findAriaAtomic(IAccessible2* > pacc2,map<wstring,wstring>& attribsMa > if(pdispParent) { > IAccessible2* pacc2Parent=NULL; > > if(pdispParent->QueryInterface(IID_IAccessible2,(void**)&pacc2Parent)==S_OK&&pacc2Parent) > { > - BSTR parentAttribs=NULL; > - > pacc2Parent->get_attributes(&parentAttribs); > - if(parentAttribs) { > - map<wstring,wstring> > parentAttribsMap; > - > IA2AttribsToMap(parentAttribs,parentAttribsMap); > - SysFreeString(parentAttribs); > + map<wstring,wstring> parentAttribsMap; > + > if(fetchIA2Attributes(pacc2Parent,parentAttribsMap)) { > > pacc2Atomic=findAriaAtomic(pacc2Parent,parentAttribsMap); > } > pacc2Parent->Release(); > @@ -71,8 +78,13 @@ bool getTextFromIAccessible(wstring& textBuf, > IAccessible2* pacc2, bool useNewTe > if(varChildren[i].vt==VT_DISPATCH) { > IAccessible2* pacc2Child=NULL; > > if(varChildren[i].pdispVal&&varChildren[i].pdispVal->QueryInterface(IID_IAccessible2,(void**)&pacc2Child)==S_OK) > { > - > if(getTextFromIAccessible(textBuf,pacc2Child)) { > - gotText=true; > + map<wstring,wstring> > childAttribsMap; > + > fetchIA2Attributes(pacc2Child,childAttribsMap); > + auto > i=childAttribsMap.find(L"live"); > + > if(i==childAttribsMap.end()||i->second.compare(L"off")!=0) { > + > if(getTextFromIAccessible(textBuf,pacc2Child)) { > + gotText=true; > + } > } > pacc2Child->Release(); > } > @@ -110,8 +122,13 @@ bool getTextFromIAccessible(wstring& textBuf, > IAccessible2* pacc2, bool useNewTe > > if(paccHypertext->get_hyperlink(hyperlinkIndex,&paccHyperlink)==S_OK) > { > IAccessible2* > pacc2Child=NULL; > > if(paccHyperlink->QueryInterface(IID_IAccessible2,(void**)&pacc2Child)==S_OK) > { > - > if(getTextFromIAccessible(textBuf,pacc2Child)) { > - > gotText=true; > + > map<wstring,wstring> childAttribsMap; > + > fetchIA2Attributes(pacc2Child,childAttribsMap); > + auto > i=childAttribsMap.find(L"live"); > + > if(i==childAttribsMap.end()||i->second.compare(L"off")!=0) { > + > if(getTextFromIAccessible(textBuf,pacc2Child)) { > + > gotText=true; > + } > } > charAdded=true; > > pacc2Child->Release(); > @@ -217,19 +234,12 @@ void CALLBACK winEventProcHook(HWINEVENTHOOK hookID, > DWORD eventID, HWND hwnd, l > pserv->Release(); > if(!pacc2) return; > //Retreave the IAccessible2 attributes, and if the object is not a live > region then ignore the event. > - BSTR attribs=NULL; > - pacc2->get_attributes(&attribs); > - if(!attribs) { > + map<wstring,wstring> attribsMap; > + if(!fetchIA2Attributes(pacc2,attribsMap)) { > pacc2->Release(); > return; > } > - map<wstring,wstring> attribsMap; > - IA2AttribsToMap(attribs,attribsMap); > - SysFreeString(attribs); > - map<wstring,wstring>::iterator i; > - i=attribsMap.find(L"live"); > - bool isRegionRoot=(i!=attribsMap.end()); > - i=attribsMap.find(L"container-live"); > + auto i=attribsMap.find(L"container-live"); > bool > live=(i!=attribsMap.end()&&(i->second.compare(L"polite")==0||i->second.compare(L"assertive")==0||i->second.compare(L"rude")==0)); > if(!live) { > pacc2->Release(); > @@ -251,23 +261,41 @@ void CALLBACK winEventProcHook(HWINEVENTHOOK hookID, > DWORD eventID, HWND hwnd, l > allowText=(i->second.find(L"text",0)!=wstring::npos); > allowAdditions=(i->second.find(L"additions",0)!=wstring::npos); > } > - //Only handle show events if additions are allowed and this is not the > root of a region. > - if(eventID==EVENT_OBJECT_SHOW&&(!allowAdditions||isRegionRoot)) { > + attribsMap.clear(); > + //Only handle show events if additions are allowed > + if(eventID==EVENT_OBJECT_SHOW&&!allowAdditions) { > pacc2->Release(); > return; > } > // If this is a show event and this is not the root of the region and > there is a text parent, > // We can ignore this event as there will be text events which can > handle > this better > if(eventID==EVENT_OBJECT_SHOW) { > - bool ignoreShowEvent=false; > + bool ignoreShowEvent=false; > IDispatch* pdispParent=NULL; > pacc2->get_accParent(&pdispParent); > if(pdispParent) { > + // check for text on parent > IAccessibleText* paccTextParent=NULL; > > if(pdispParent->QueryInterface(IID_IAccessibleText,(void**)&paccTextParent)==S_OK&&paccTextParent) > { > ignoreShowEvent=true; > paccTextParent->Release(); > } > + if(!ignoreShowEvent) { > + // Check for useful container-live on parent, > as if missing or off, > then child must be the root > + // Firstly, we assume we are the root of the > region and therefore > should ignore the event > + ignoreShowEvent=true; > + IAccessible2* pacc2Parent=NULL; > + > if(pdispParent->QueryInterface(IID_IAccessible2,(void**)&pacc2Parent)==S_OK) > { > + > if(fetchIA2Attributes(pacc2Parent,attribsMap)) { > + > i=attribsMap.find(L"container-live"); > + > if(i!=attribsMap.end()&&(i->second.compare(L"polite")==0||i->second.compare(L"assertive")==0||i->second.compare(L"rude")==0)) > { > + // There is a valid > container-live that is not off, so therefore the > child is definitly not the root > + ignoreShowEvent=false; > + } > + } > + pacc2Parent->Release(); > + } > + } > pdispParent->Release(); > } > if(ignoreShowEvent) { > > diff --git a/nvdaHelper/vbufBackends/mshtml/node.cpp > b/nvdaHelper/vbufBackends/mshtml/node.cpp > index 7bd5a9a..3e42b09 100755 > --- a/nvdaHelper/vbufBackends/mshtml/node.cpp > +++ b/nvdaHelper/vbufBackends/mshtml/node.cpp > @@ -385,9 +385,17 @@ void > MshtmlVBufStorage_controlFieldNode_t::reportLiveText(wstring& text) { > } > } > > +bool isNodeInLiveRegion(VBufStorage_fieldNode_t* node) { > + if(!node) return false; > + if(node->getFirstChild()) { > + return > ((MshtmlVBufStorage_controlFieldNode_t*)node)->ariaLiveNode!=NULL; > + } > + return true; > +} > + > void MshtmlVBufStorage_controlFieldNode_t::reportLiveAddition() { > wstring text; //=(this->ariaLiveAtomicNode==this)?L"atomic: > ":L"additions: > "; > - this->getTextInRange(0,this->getLength(),text,false); > + this->getTextInRange(0,this->getLength(),text,false,isNodeInLiveRegion); > this->reportLiveText(text); > } > > > diff --git a/nvdaHelper/vbufBase/storage.cpp > b/nvdaHelper/vbufBase/storage.cpp > index ed7fbd3..d99dfb8 100644 > --- a/nvdaHelper/vbufBase/storage.cpp > +++ b/nvdaHelper/vbufBase/storage.cpp > @@ -239,7 +239,7 @@ void > VBufStorage_fieldNode_t::generateMarkupClosingTag(std::wstring& text) { > text+=L">"; > } > > -void VBufStorage_fieldNode_t::getTextInRange(int startOffset, int > endOffset, std::wstring& text, bool useMarkup) { > +void VBufStorage_fieldNode_t::getTextInRange(int startOffset, int > endOffset, std::wstring& text, bool useMarkup, > bool(*filter)(VBufStorage_fieldNode_t*)) { > if(this->length==0) { > LOG_DEBUG(L"node has 0 length, not collecting text"); > return; > @@ -260,9 +260,9 @@ void VBufStorage_fieldNode_t::getTextInRange(int > startOffset, int endOffset, std > nhAssert(childLength>=0); //length can't be negative > childEnd+=childLength; > LOG_DEBUG(L"child with offsets of "<<childStart<<L" and > "<<childEnd); > - if(childEnd>startOffset&&endOffset>childStart) { > + > if(childEnd>startOffset&&endOffset>childStart&&(!filter||filter(child))) > { > LOG_DEBUG(L"child offsets overlap requested offsets"); > - > child->getTextInRange(max(startOffset,childStart)-childStart,min(endOffset-childStart,childLength),text,useMarkup); > + > child->getTextInRange(max(startOffset,childStart)-childStart,min(endOffset-childStart,childLength),text,useMarkup,filter); > } > childStart+=childLength; > LOG_DEBUG(L"childStart is now "<<childStart); > @@ -358,7 +358,7 @@ void > VBufStorage_textFieldNode_t::generateMarkupTagName(std::wstring& text) { > text+=L"text"; > } > > -void VBufStorage_textFieldNode_t::getTextInRange(int startOffset, int > endOffset, std::wstring& text, bool useMarkup) { > +void VBufStorage_textFieldNode_t::getTextInRange(int startOffset, int > endOffset, std::wstring& text, bool useMarkup, > bool(*filter)(VBufStorage_fieldNode_t*)) { > LOG_DEBUG(L"getting text between offsets "<<startOffset<<L" and > "<<endOffset); > if(useMarkup) { > this->generateMarkupOpeningTag(text,startOffset,endOffset); > > diff --git a/nvdaHelper/vbufBase/storage.h b/nvdaHelper/vbufBase/storage.h > index 3456584..795d9f4 100644 > --- a/nvdaHelper/vbufBase/storage.h > +++ b/nvdaHelper/vbufBase/storage.h > @@ -286,9 +286,10 @@ class VBufStorage_fieldNode_t { > * @param endOffset the offset to end at. Use -1 to mean node's end offset. > > * @param text a string in whish to append the text. > * @param useMarkup if true then markup indicating opening and closing of > fields will be included. > + * @param filter: a function that takes the current recursive node and > returns true if text should be fetched and false if it should be skipped. > * @return true if successfull, false otherwize. > */ > - virtual void getTextInRange(int startOffset, int endOffset, > std::wstring& > text, bool useMarkup=false); > + virtual void getTextInRange(int startOffset, int endOffset, > std::wstring& > text, bool useMarkup=false,bool(*filter)(VBufStorage_fieldNode_t*)=NULL); > > /** > * @return a string providing information about this node's type, and its > state. > @@ -359,7 +360,7 @@ class VBufStorage_textFieldNode_t : public > VBufStorage_fieldNode_t { > > virtual void generateMarkupTagName(std::wstring& text); > > - virtual void getTextInRange(int startOffset, int endOffset, > std::wstring& > text, bool useMarkup=false); > + virtual void getTextInRange(int startOffset, int endOffset, > std::wstring& > text, bool useMarkup=false,bool(*filter)(VBufStorage_fieldNode_t*)=NULL); > > /** > * constructor. > > diff --git a/readme.txt b/readme.txt > index e667fe3..d5b79d3 100644 > --- a/readme.txt > +++ b/readme.txt > @@ -27,18 +27,19 @@ The following dependencies are included in Git > submodules: > * eSpeak, version 1.48.03: http://espeak.sourceforge.net/ > * IAccessible2, version 1.3: > http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2 > * ConfigObj, version 4.6.0: > http://www.voidspace.org.uk/python/configobj.html > -* liblouis, version 2.5.4: http://www.liblouis.org/ > +* liblouis, version 2.6.0: http://www.liblouis.org/ > * NVDA images and sounds > * System dlls not present on many systems: mfc90.dll, msvcp90.dll, > msvcr90.dll, Microsoft.VC90.CRT.manifest > * Adobe Acrobat accessibility interface, version XI: > http://download.macromedia.com/pub/developer/acrobat/AcrobatAccess.zip > * Adobe FlashAccessibility interface typelib > * txt2tags, version 2.5: http://txt2tags.sourceforge.net/ > -* MinHook, rev e21b54a: https://github.com/RaMMicHaeL/minhook > -* SCons, version 2.3.0: http://www.scons.org/ > +* MinHook, tagged version 1.2.2: https://github.com/RaMMicHaeL/minhook > +* SCons, version 2.3.2: http://www.scons.org/ > * brlapi Python bindings, version 0.5.7 or later, distributed with BRLTTY > for Windows, version 4.2-2: http://brl.thefreecat.org/brltty/ > * ALVA BC6 generic dll, version 3.0.4.1 > * lilli.dll, version 2.1.0.0 > * Handy Tech Braille SDK, version 1.4.2.0: > ftp://ftp.handytech.de/public/Software/BrailleDriver/HTBrailleSDK_1420a.zip > +* Updated Handy Tech sbsupport.dll and dealers.dat received on 2014-09-09 > * pyserial, version 2.5: http://pypi.python.org/pypi/pyserial > * HanSoneConnect.dll, version 2.0.0.1 > * SyncBraille.dll, version 1.0.0.1 > > diff --git a/sconstruct b/sconstruct > index c79a5e0..87d9934 100755 > --- a/sconstruct > +++ b/sconstruct > @@ -14,6 +14,7 @@ > > import sys > import os > +import time > import _winreg > from glob import glob > > @@ -112,12 +113,35 @@ outFilePrefix = "nvda{type}_{version}".format(type="" > if release else "_snapshot > outputDir=Dir(env['outputDir']) > devDocsOutputDir=outputDir.Dir('devDocs') > > +# An action to sign an executable with certFile. > +signExecCmd = ["signtool", "sign", "/f", certFile] > +if certPassword: > + signExecCmd.extend(("/p", certPassword)) > +if certTimestampServer: > + signExecCmd.extend(("/t", certTimestampServer)) > +def signExec(target,source,env): > + print [str(x) for x in target] > + #sys.exit(1) > + # #3795: signtool can quite commonly fail with timestamping, so allow it > to try up to 3 times with a 1 second delay between each try. > + res=0 > + for count in xrange(3): > + res=env.Execute([signExecCmd+[target[0].abspath]]) > + if not res: > + return 0 # success > + time.sleep(1) > + return res # failed > +#Export via scons environment so other libraries can be signed > +env['signExec']=signExec > + > #architecture-specific environments > archTools=['default','windowsSdk','midl','msrpc'] > env32=env.Clone(TARGET_ARCH='x86',tools=archTools) > env64=env.Clone(TARGET_ARCH='x86_64',tools=archTools) > -env=env32 > +# Hack around odd bug where some tool [after] msvc states that static and > shared objects are different > +env32['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 > +env64['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 > > +env=env32 > > #Fill sourceDir with anything provided for it by miscDeps > env.recursiveCopy(sourceDir,Dir('miscdeps/source')) > @@ -195,8 +219,8 @@ def NVDADistGenerator(target, source, env, > for_signature): > if env.get("uiAccess"): > buildCmd.append("--enable-uiAccess") > if certFile: > - for prog in "nvda_noUIAccess", "nvda_uiAccess", "nvda_slave", > "nvda_service": > - action.append(signExec[:-1] + > [os.path.join(target[0].path, "%s.exe" % > prog)]) > + for prog in "nvda_noUIAccess.exe", "nvda_uiAccess.exe", > "nvda_slave.exe", > "nvda_service.exe": > + action.append(lambda target,source,env, progByVal=prog: > signExec([target[0].File(progByVal)],source,env)) > > for ext in "", "c", "o": > action.append(Delete(buildVersionFn + ext)) > @@ -247,14 +271,6 @@ def ZipArchiveAction(target, source, env): > > env["BUILDERS"]["ZipArchive"] = Builder(action=ZipArchiveAction) > > -# An action to sign an executable with certFile. > -signExec = ["signtool", "sign", "/f", certFile] > -if certPassword: > - signExec.extend(("/p", certPassword)) > -if certTimestampServer: > - signExec.extend(("/t", certTimestampServer)) > -signExec.append("$TARGET") > - > uninstFile=File("dist/uninstall.exe") > uninstGen = env.Command(File("uninstaller/uninstGen.exe"), > "uninstaller/uninst.nsi", > [[makensis, "/V2", > > diff --git a/source/NVDAObjects/IAccessible/MSHTML.py > b/source/NVDAObjects/IAccessible/MSHTML.py > index a6bf4ee..a8e6ffb 100644 > --- a/source/NVDAObjects/IAccessible/MSHTML.py > +++ b/source/NVDAObjects/IAccessible/MSHTML.py > @@ -386,7 +386,12 @@ class MSHTML(IAccessible): > if nodeName=="SELECT" and > self.windowStyle&winUser.WS_POPUP: > clsList.append(PopupList) > elif nodeNamesToNVDARoles.get(nodeName) == > controlTypes.ROLE_DOCUMENT: > - clsList.append(Body) > + try: > + > isBodyNode=self.HTMLNodeUniqueNumber==self.HTMLNode.document.body.uniqueNumber > + except (COMError,NameError): > + isBodyNode=False > + if isBodyNode: > + clsList.append(Body) > elif nodeName == "OBJECT": > clsList.append(Object) > elif nodeName=="FIELDSET": > @@ -879,11 +884,12 @@ class Fieldset(MSHTML): > class Body(MSHTML): > > def _get_parent(self): > - # The parent of the body accessible is an irrelevant client > object > (description: MSAAHTML Registered Handler). > + # The parent of the body accessible may be an irrelevant client > object > (description: MSAAHTML Registered Handler). > # This object isn't returned when requesting OBJID_CLIENT, nor > is it > returned as a child of its parent. > # Therefore, eliminate it from the ancestry completely. > + # However it is possible that this body is a child document of > a parent > frame. In this case don't skip it. > parent = super(Body, self).parent > - if parent: > + if parent and not isinstance(parent,MSHTML): > return parent.parent > else: > return parent > > diff --git a/source/NVDAObjects/IAccessible/__init__.py > b/source/NVDAObjects/IAccessible/__init__.py > index 7214a75..4826b01 100644 > --- a/source/NVDAObjects/IAccessible/__init__.py > +++ b/source/NVDAObjects/IAccessible/__init__.py > @@ -511,14 +511,15 @@ the NVDAObject for IAccessible > > clsList.append(IAccessible) > > - > - if self.event_objectID==winUser.OBJID_CLIENT and > self.event_childID==0: > + if self.event_objectID==winUser.OBJID_CLIENT and > self.event_childID==0 > and not isinstance(self.IAccessibleObject,IAccessibleHandler.IAccessible2): > # This is the main (client) area of the window, so we > can use other > classes at the window level. > + # #3872: However, don't do this for IAccessible2 because > + # IA2 supersedes window level APIs and might conflict > with them. > super(IAccessible,self).findOverlayClasses(clsList) > #Generic client IAccessibles with no children should be > classed as > content and should use displayModel > if clsList[0]==IAccessible and len(clsList)==3 and > self.IAccessibleRole==oleacc.ROLE_SYSTEM_CLIENT and self.childCount==0: > clsList.insert(0,ContentGenericClient) > - > + > def > __init__(self,windowHandle=None,IAccessibleObject=None,IAccessibleChildID=None,event_windowHandle=None,event_objectID=None,event_childID=None): > """ > @param pacc: a pointer to an IAccessible object > > diff --git a/source/NVDAObjects/window/__init__.py > b/source/NVDAObjects/window/__init__.py > index 1b95c3d..e7afcee 100644 > --- a/source/NVDAObjects/window/__init__.py > +++ b/source/NVDAObjects/window/__init__.py > @@ -114,7 +114,7 @@ An NVDAObject for a window > from .edit import Edit as newCls > elif windowClassName=="RichEdit": > from .edit import RichEdit as newCls > - elif windowClassName=="RichEdit20": > + elif windowClassName in ("RichEdit20","REComboBox20W"): > from .edit import RichEdit20 as newCls > elif windowClassName=="RICHEDIT50W": > from .edit import RichEdit50 as newCls > > diff --git a/source/NVDAObjects/window/winword.py > b/source/NVDAObjects/window/winword.py > index 61078f2..c66e7ef 100755 > --- a/source/NVDAObjects/window/winword.py > +++ b/source/NVDAObjects/window/winword.py > @@ -477,7 +477,6 @@ class WordDocumentTextInfo(textInfos.TextInfo): > elif which=="startToEnd": > self._rangeObj.Start=other._rangeObj.End > elif which=="endToStart": > - print "start %s, end %s, otherStart %s, otherEnd > %s"%(self._rangeObj.start,self._rangeObj.end,other._rangeObj.start,other._rangeObj.end) > self._rangeObj.End=other._rangeObj.Start > elif which=="endToEnd": > self._rangeObj.End=other._rangeObj.End > > diff --git a/source/addonHandler.py b/source/addonHandler.py > index 8f4fc17..0c135a3 100644 > --- a/source/addonHandler.py > +++ b/source/addonHandler.py > @@ -155,7 +155,7 @@ def getAvailableAddons(refresh=False): > return _availableAddons.itervalues() > > def installAddonBundle(bundle): > - """Extracts an Addon bundle in to a unique subdirectory of the user > addons > directory, marking the addon as needing install completion on NVDA > restart.""" > + """Extracts an Addon bundle in to a unique subdirectory of the user > addons > directory, marking the addon as needing install completion on NVDA > restart.""" > addonPath = os.path.join(globalVars.appArgs.configPath, > "addons",bundle.manifest['name']+ADDON_PENDINGINSTALL_SUFFIX) > bundle.extract(addonPath) > addon=Addon(addonPath) > @@ -391,7 +391,7 @@ def _translatedManifestPaths(lang=None, > forBundle=False): > > > class AddonBundle(object): > - """ Represents the contents of an NVDA addon in a for suitable for > distribution. > + """ Represents the contents of an NVDA addon suitable for distribution. > The bundle is compressed using the zip file format. Manifest information > is available without the need for extraction.""" > def __init__(self, bundlePath): > > diff --git a/source/api.py b/source/api.py > index c829f3b..77eb33e 100644 > --- a/source/api.py > +++ b/source/api.py > @@ -218,19 +218,12 @@ def setNavigatorObject(obj,isFocus=False): > # #3320: If in document review yet there is no document to review the > mode > should be forced to object. > if reviewMode=='document' and (not obj.treeInterceptor or not > obj.treeInterceptor.isReady or obj.treeInterceptor.passThrough): > review.setCurrentMode('object',False) > - elif isFocus and reviewMode=='object' and obj.treeInterceptor and > obj.treeInterceptor.isReady and not obj.treeInterceptor.passThrough: > - review.setCurrentMode('document',False) > - #Specifically handle when the navigator object is set due to a focus > change in a virtualBuffer > - #The focus change may have been becaus the caret was moved, which caused > the focus change. > - #If so, don't clober the review position as it will have been already > set > to a more accurate position. > - if isFocus and oldPos and oldPos.obj is obj.treeInterceptor and > isinstance(obj.treeInterceptor,virtualBuffers.VirtualBuffer): > - try: > - objPos=obj.treeInterceptor.makeTextInfo(obj) > - except LookupError: > - objPos=None > - if objPos and objPos.isOverlapping(oldPos): > - globalVars.reviewPosition=oldPos > - globalVars.reviewPositionObj=oldPosObj > + elif obj.treeInterceptor and obj.treeInterceptor.isReady and not > obj.treeInterceptor.passThrough: > + if reviewMode=='object': > + review.setCurrentMode('document',False) > + if isFocus: > + > globalVars.reviewPosition=obj.treeInterceptor.makeTextInfo(textInfos.POSITION_CARET) > + globalVars.reviewPositionObj=globalVars.reviewPosition > eventHandler.executeEvent("becomeNavigatorObject",obj) > > def isTypingProtected(): > @@ -341,9 +334,9 @@ def getStatusBarText(obj): > @return: The status bar text. > @rtype: str > """ > - text = obj.name > - if text is None: > - text = "" > + text = obj.name or "" > + if text: > + text += " " > return text + " ".join(chunk for child in obj.children for chunk in > (child.name, child.value) if chunk and isinstance(chunk, basestring) and not > chunk.isspace()) > > def filterFileName(name): > > diff --git a/source/appModules/eclipse.py b/source/appModules/eclipse.py > index fb258e7..49d02ff 100644 > --- a/source/appModules/eclipse.py > +++ b/source/appModules/eclipse.py > @@ -2,10 +2,20 @@ > #A part of NonVisual Desktop Access (NVDA) > #This file is covered by the GNU General Public License. > #See the file COPYING for more details. > -#Copyright (C) 2010 James Teh <jamie@xxxxxxxxxxx> > +#Copyright (C) 2010-2014 NV Access Limited > > import controlTypes > import appModuleHandler > +from NVDAObjects.IAccessible import IAccessible > + > +class EclipseTextArea(IAccessible): > + > + def event_valueChange(self): > + # #2314: Eclipse incorrectly fires valueChange when the > selection > changes. > + # Unfortunately, this causes us to speak the entire selection > + # instead of just the changed selection. > + # Therefore, just drop this event. > + pass > > class AppModule(appModuleHandler.AppModule): > > @@ -14,3 +24,7 @@ class AppModule(appModuleHandler.AppModule): > # Eclipse tree views seem to fire a focus event on the > previously > focused item before firing focus on the new item (EclipseBug:315339). > # Try to filter this out. > obj.shouldAllowIAccessibleFocusEvent = False > + > + def chooseNVDAObjectOverlayClasses(self, obj, clsList): > + if obj.windowClassName == "SWT_Window0" and obj.role == > controlTypes.ROLE_EDITABLETEXT: > + clsList.insert(0, EclipseTextArea) > > diff --git a/source/appModules/outlook.py b/source/appModules/outlook.py > index f0dabc0..09f3e75 100644 > --- a/source/appModules/outlook.py > +++ b/source/appModules/outlook.py > @@ -433,6 +433,8 @@ class UIAGridRow(RowWithFakeNavigation,UIA): > role=super(UIAGridRow,self).role > if role==controlTypes.ROLE_TREEVIEW: > role=controlTypes.ROLE_TREEVIEWITEM > + elif role==controlTypes.ROLE_DATAITEM: > + role=controlTypes.ROLE_LISTITEM > return role > > def setFocus(self): > > diff --git a/source/braille.py b/source/braille.py > index 6971d81..e845eaa 100644 > --- a/source/braille.py > +++ b/source/braille.py > @@ -309,6 +309,8 @@ def _getDisplayDriver(name): > > def getDisplayList(): > displayList = [] > + # The display that should be placed at the end of the list. > + lastDisplay = None > for loader, name, isPkg in > pkgutil.iter_modules(brailleDisplayDrivers.__path__): > if name.startswith('_'): > continue > @@ -320,11 +322,17 @@ def getDisplayList(): > continue > try: > if display.check(): > - displayList.append((display.name, > display.description)) > + if display.name == "noBraille": > + lastDisplay = (display.name, > display.description) > + else: > + displayList.append((display.name, > display.description)) > else: > log.debugWarning("Braille display driver %s > reports as unavailable, > excluding" % name) > except: > log.error("", exc_info=True) > + displayList.sort(key=lambda d : d[1].lower()) > + if lastDisplay: > + displayList.append(lastDisplay) > return displayList > > class Region(object): > > diff --git a/source/cursorManager.py b/source/cursorManager.py > index 492b36c..d4aae44 100644 > --- a/source/cursorManager.py > +++ b/source/cursorManager.py > @@ -13,6 +13,7 @@ import wx > import baseObject > import gui > import sayAllHandler > +import review > from scriptHandler import willSayAllResume > import textInfos > import api > @@ -343,4 +344,5 @@ class ReviewCursorManager(CursorManager): > > def _set_selection(self, info): > self._selection = info.copy() > + review.handleCaretMove(info) > braille.handler.handleCaretMove(self) > > diff --git a/source/gui/__init__.py b/source/gui/__init__.py > index 5929f08..fc8271b 100644 > --- a/source/gui/__init__.py > +++ b/source/gui/__init__.py > @@ -458,6 +458,7 @@ class SysTrayIcon(wx.TaskBarIcon): > item = self.menu.Append(wx.ID_EXIT, _("E&xit"),_("Exit NVDA")) > self.Bind(wx.EVT_MENU, frame.onExitCommand, item) > > + self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.onActivate) > self.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.onActivate) > > def Destroy(self): > > diff --git a/source/installer.py b/source/installer.py > index 47a963d..8f67787 100644 > --- a/source/installer.py > +++ b/source/installer.py > @@ -144,6 +144,12 @@ def removeOldProgramFiles(destPath): > else: > os.remove(fn) > > + # #4235: mpr.dll is a Windows system dll accidentally included with > + # earlier versions of NVDA. Its presence causes problems in Windows > Vista. > + fn = os.path.join(destPath, "mpr.dll") > + if os.path.isfile(fn): > + tryRemoveFile(fn) > + > uninstallerRegInfo={ > "DisplayName":versionInfo.name, > "DisplayVersion":versionInfo.version, > > diff --git a/source/setup.py b/source/setup.py > index 752d1cb..b27e129 100755 > --- a/source/setup.py > +++ b/source/setup.py > @@ -1,7 +1,7 @@ > # -*- coding: UTF-8 -*- > #setup.py > #A part of NonVisual Desktop Access (NVDA) > -#Copyright (C) 2006-2013 NV Access Limited, Peter Vágner > +#Copyright (C) 2006-2014 NV Access Limited, Peter Vágner > #This file is covered by the GNU General Public License. > #See the file COPYING for more details. > > @@ -71,7 +71,7 @@ def isSystemDLL(pathname): > if dll in ("msvcp71.dll", "msvcp90.dll", "gdiplus.dll","mfc71.dll", > "mfc90.dll"): > # These dlls don't exist on many systems, so make sure they're > included. > return 0 > - elif dll.startswith("api-ms-win-") or dll == "powrprof.dll": > + elif dll.startswith("api-ms-win-") or dll in ("powrprof.dll", > "mpr.dll"): > # These are definitely system dlls available on all systems and > must be > excluded. > # Including them can cause serious problems when a binary build > is run on > a different version of Windows. > return 1 > > diff --git a/source/speech.py b/source/speech.py > index add2bbb..a201cd4 100755 > --- a/source/speech.py > +++ b/source/speech.py > @@ -536,7 +536,8 @@ def > speakSelectionChange(oldInfo,newInfo,speakSelected=True,speakUnselected=True > > def speakTypedCharacters(ch): > global curWordChars; > - if api.isTypingProtected(): > + typingIsProtected=api.isTypingProtected() > + if typingIsProtected: > realChar="*" > else: > realChar=ch > @@ -553,7 +554,7 @@ def speakTypedCharacters(ch): > curWordChars=[] > if log.isEnabledFor(log.IO): > log.io("typed word: %s"%typedWord) > - if config.conf["keyboard"]["speakTypedWords"]: > + if config.conf["keyboard"]["speakTypedWords"] and not > typingIsProtected: > speakText(typedWord) > if config.conf["keyboard"]["speakTypedCharacters"] and ord(ch)>=32: > speakSpelling(realChar) > > diff --git a/source/synthDriverHandler.py b/source/synthDriverHandler.py > index 7c2ed9d..417c114 100644 > --- a/source/synthDriverHandler.py > +++ b/source/synthDriverHandler.py > @@ -39,6 +39,8 @@ def _getSynthDriver(name): > > def getSynthList(): > synthList=[] > + # The synth that should be placed at the end of the list. > + lastSynth = None > for loader, name, isPkg in pkgutil.iter_modules(synthDrivers.__path__): > if name.startswith('_'): > continue > @@ -49,11 +51,17 @@ def getSynthList(): > continue > try: > if synth.check(): > - synthList.append((synth.name,synth.description)) > + if synth.name == "silence": > + lastSynth = > (synth.name,synth.description) > + else: > + > synthList.append((synth.name,synth.description)) > else: > log.debugWarning("Synthesizer '%s' doesn't pass > the check, excluding > from list"%name) > except: > log.error("",exc_info=True) > + synthList.sort(key=lambda s : s[1].lower()) > + if lastSynth: > + synthList.append(lastSynth) > return synthList > > def getSynth(): > > diff --git a/source/versionInfo.py b/source/versionInfo.py > index de3b859..428e54a 100644 > --- a/source/versionInfo.py > +++ b/source/versionInfo.py > @@ -29,7 +29,7 @@ def _updateVersionFromVCS(): > > name="NVDA" > longName=_("NonVisual Desktop Access") > -version="2014.3dev" > +version="2014.4dev" > publisher="unknown" > updateVersionType=None > try: > > diff --git a/source/virtualBuffers/MSHTML.py > b/source/virtualBuffers/MSHTML.py > index d35ff64..afd6d92 100644 > --- a/source/virtualBuffers/MSHTML.py > +++ b/source/virtualBuffers/MSHTML.py > @@ -238,7 +238,7 @@ class MSHTML(VirtualBuffer): > elif nodeType=="button": > > attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_PUSHBUTTON]} > elif nodeType=="edit": > - > attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_READONLY:[None],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1]} > + > attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT,oleacc.ROLE_SYSTEM_COMBOBOX],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_READONLY:[None],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1],"IHTMLElement::%s"%"isContentEditable":[1]} > elif nodeType=="radioButton": > > attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_RADIOBUTTON],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1]} > elif nodeType=="comboBox": > > diff --git a/source/virtualBuffers/gecko_ia2.py > b/source/virtualBuffers/gecko_ia2.py > index 31f8c57..f61007f 100755 > --- a/source/virtualBuffers/gecko_ia2.py > +++ b/source/virtualBuffers/gecko_ia2.py > @@ -209,7 +209,7 @@ class Gecko_ia2(VirtualBuffer): > elif nodeType=="button": > > attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_PUSHBUTTON,oleacc.ROLE_SYSTEM_BUTTONMENU,IAccessibleHandler.IA2_ROLE_TOGGLE_BUTTON]} > elif nodeType=="edit": > - > attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_READONLY:[None]} > + > attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT,oleacc.ROLE_SYSTEM_COMBOBOX],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_READONLY:[None],"IAccessible2::state_%s"%IAccessibleHandler.IA2_STATE_EDITABLE:[1]} > elif nodeType=="frame": > > attrs={"IAccessible::role":[IAccessibleHandler.IA2_ROLE_INTERNAL_FRAME]} > elif nodeType=="separator": > > diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t > index d07340e..a677322 100644 > --- a/user_docs/en/changes.t2t > +++ b/user_docs/en/changes.t2t > @@ -3,6 +3,32 @@ > > %!includeconf: ../changes.t2tconf > > += 2014.4 = > + > +== Changes == > +- If an object you have moved to with object navigation is inside a browse > mode document, but the object you were on previously was not, the review > mode is automatically set to document. Previously this only happened if the > navigator object was moved due to the focus changing. (#4369) > +- The Braille display and Synthesizer lists in the respective settings > dialogs are now alphabetically sorted except for No braille/No speech, which > are now at the bottom. (#2724) > +- Updated liblouis braille translator to 2.6.0. (#4434, #3835) > +- In browse mode, pressing e and shift+e to navigate to edit fields now > includes editable combo boxes. This includes the search box in the latest > versionn of Google Search. (#4436) > +- Clicking the NVDA icon in the Notification Area with the left mouse > button now opens the NVDA menu instead of doing nothing. (#4459) > + > + > +== Bug Fixes == > +- When moving focus back to a browse mode document (e.g. alt tabbing to an > already opened web page) the review cursor is properly positioned at the > virtual caret, rather than the focused control (e.g. a near by link). > (#4369) > +- In Powerpoint slide shows, the review cursor correctly follows the > virtual caret. (#4370) > +- In Mozilla Firefox and other Gecko-based browsers, new content within a > live region will be announced even if the new content has a usable ARIA live > type different to the parent live region. E.g. Content marked as assertive > is added to a live region marked as polite. (#4169). > +- In Internet Explorer and other MSHTML controls, some cases where a > document is contained within another document no longer prevent the user > from accessing some of the content (specifically, framesets inside > framesets). (#4418) > +- NVDA no longer crashes when attempting to use a Handy Tech braille > display in some cases. (#3709) > +- In Windows Vista, a spurious "Entry Point Not Found" dialog is no longer > displayed in several cases such as when starting NVDA from the Desktop > shortcut or via the shortcut key. (#4235) > +- Serious problems with editable text controls in dialogs in recent > versions of Eclipse have been fixed. (#3872) > +- In Outlook 2010, moving the caret now works as expected in the location > field of appointments and meeting requests. (#4126) > +- Inside a live region, content which is marked as not being live (e.g. > aria-live="off") is now correctly ignored. (#4405) > +- When reporting the text of a status bar that has a name, the name is now > correctly separated from the first word of the status bar text. (#4430) > +- In password entry fields with speaking of typed words enabled, multiple > asterisks are no longer pointlessly reported when beginning new words. > (#4402) > +- In the Microsoft Outlook message list, items are no longer pointlessly > announced as Data Items. (#4439) > +- When selecting text in the code editing control in the Eclipse IDE, the > entire selection is no longer announced every time the selection changes. > (#2314) > + > + > = 2014.3 = > > == New Features == > > diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t > index 77966c9..0560398 100644 > --- a/user_docs/en/userGuide.t2t > +++ b/user_docs/en/userGuide.t2t > @@ -84,7 +84,7 @@ Running the portable version directly from read-only media > is not supported at t > Using the temporary copy of NVDA is also an option (e.g. for demonstration > purposes), though starting NVDA in this way each time can become very time > consuming. > > ++ Portable and Temporary Copy Restrictions ++ > -Apart from the inability to automatically start during and or after > log-on, the portable and temporary copies of NVDA also have the following > restrictions: > +Apart from the inability to automatically start during and/or after > log-on, the portable and temporary copies of NVDA also have the following > restrictions: > - The inability to interact with applications running with administrative > privileges, unless of course NVDA itself has been run also with these > privileges (not recommended). > - The inability to read User Account Control (UAC) screens when trying to > start an application with administrative privileges. > - Windows 8: the inability to support input from a touch screen. > @@ -107,7 +107,7 @@ This also includes UAC control and other secure > screens. > > +++ Create Desktop Shortcut (ctrl+alt+n) +++ > This option allows you to choose whether or not NVDA should create a > shortcut on the desktop to start NVDA. > -This shortcut if created will also be assigned a shortcut key of > control+alt+n allowing you to start NVDA at any time with this key stroke. > +If created, this shortcut will also be assigned a shortcut key of > control+alt+n, allowing you to start NVDA at any time with this key stroke. > > +++ Copy Portable Configuration to Current User Account +++ > This option allows you to choose whether or not NVDA should copy the user > configuration from the currently running NVDA into the configuration for the > currently logged on user, for the installed copy of NVDA. > @@ -152,22 +152,20 @@ The third lets you control if this Welcome dialog > should appear each time NVDA s > > +++ The NVDA Modifier Key +++ > Most NVDA-specific keyboard commands consist of pressing a particular key > called the NVDA modifier key in conjunction with one or more other keys. > -Notable exceptions to this are the text review commands for desktop > keyboards which just use the numpad keys by themselves, but there are some > other exceptions as well. > - > -NVDA can be configured so that either the numpad Insert, Extended Insert, > or capslock key can be used as the NVDA modifier key. > +Notable exceptions to this are the text review commands for the desktop > keyboard layout which just use the numpad keys by themselves, but there are > some other exceptions as well. > > +NVDA can be configured so that the numpad Insert, Extended Insert and/or > capslock key can be used as the NVDA modifier key. > By default, both the numpad Insert and Extended Insert keys are set as NVDA > modifier keys. > > -If you wish to cause one of the NVDA modifier keys to act like its original > key (for instance you wish to turn capslock on when you have set capslock to > be an NVDA modifier key) you can press the key twice in quick succession. > +If you wish to cause one of the NVDA modifier keys to behave as it usually > would if NVDA were not running (e.g. you wish to turn capslock on when you > have set capslock to be an NVDA modifier key), you can press the key twice > in quick succession. > > +++ Keyboard Layouts +++ > -NVDA currently comes with two sets of key commands. > -There is a layout for Desktops and a layout for Laptops. > -NVDA by default is set to use the Desktop layout, though you can switch to > the Laptop layout in the Keyboard Settings, found under Preferences in the > NVDA menu. > +NVDA currently comes with two sets of key commands (known as keyboard > layouts): the desktop layout and the laptop layout. > +By default, NVDA is set to use the Desktop layout, though you can switch > to the Laptop layout in the Keyboard Settings, found under Preferences in > the NVDA menu. > > -The Desktop layout makes heavy use of the numberpad (with numlock off). > -Although most laptops do not have a physical numberpad, some laptops can > emulate one by holding down the FN key and pressing letters and numbers on > the right-hand side of the keyboard (7 8 9 u i o j k l etc). > -If your laptop can not do this, or does not allow you to turn numlock off, > you may want to switch to the Laptop layout instead. > +The Desktop layout makes heavy use of the numpad (with numlock off). > +Although most laptops do not have a physical numpad, some laptops can > emulate one by holding down the FN key and pressing letters and numbers on > the right-hand side of the keyboard (7, 8, 9, u, i, o, j, k, l, etc.). > +If your laptop cannot do this or does not allow you to turn numlock off, > you may want to switch to the Laptop layout instead. > > ++ NVDA Touch Gestures ++ > If you are running NVDA on a device with a touch screen and running Windows > 8 or higher, you can also control NVDA directly via the touch screen. > @@ -234,7 +232,7 @@ When the menu comes up, You can use the arrow keys to > navigate the menu, and the > || Name | Desktop key | Laptop key | Touch | Description | > | Stop speech | Control | control | 2-finger tap | Instantly stops speaking > | > | Pause Speech | shift | shift | none | Instantly pauses speech. Pressing > it again will continue speaking where it left off (if pausing is supported > by the current synthesizer) | > -| NVDA Menu | NVDA+n | NVDA+n | 2-finger double tap | Pops up the NVDA menu > to allow you to access preferences, tools and help etc | > +| NVDA Menu | NVDA+n | NVDA+n | 2-finger double tap | Pops up the NVDA menu > to allow you to access preferences, tools, help, etc. | > | Toggle Speech Mode | NVDA+s | NVDA+s | none | Toggles speech mode between > speech, beeps and off. | > | Toggle Input Help Mode | NVDA+1 | NVDA+1 | none | Pressing any key in > this mode will report the key, and the description of any NVDA command > associated with it | > | Quit NVDA | NVDA+q | NVDA+q | none | Exits NVDA | > @@ -669,12 +667,13 @@ This option is a slider which goes from 0 to 100, (0 > being the lowest volume and > This option is a slider that lets you choose how much inflection (rise and > fall in pitch) the synthesizer should use to speak with. (The only > synthesizer that provides this option at the present time is eSpeak). > > ==== Automatic Language switching ==== > -This checkbox allows you to toggle whether or not NVDA should switch speech > synthesizer languages on the fly, if language markup is available in the > text being read. > +This checkbox allows you to toggle whether NVDA should switch speech > synthesizer languages automatically if the text being read specifies its > language. > This option is enabled by default. > Currently only the eSpeak synthesizer supports automatic language > switching. > > ==== Automatic Dialect switching ==== > -If automatic language switching is turned on, this checkbox allows you to > toggle whether or not dialect changes should be made, rather than just > actual language changes. E.g. If reading in an English U.S. voice but a > document states some text is in English U.K. then if this feature is enabled > the synthesizer will switch accents. > +This checkbox allows you to toggle whether or not dialect changes should be > made, rather than just actual language changes. > +For example, if reading in an English U.S. voice but a document specifies > that some text is in English U.K., then the synthesizer will switch accents > if this option is enabled. > This option is disabled by default. > > %kc:setting > @@ -880,7 +879,7 @@ Key: NVDA+6 > > When enabled, the review cursor will automatically be moved to the position > of the System caret each time it moves. > > -==== Follow mouse ==== > +==== Follow mouse cursor ==== > When enabled, the review cursor will follow the mouse as it moves. > > ==== Simple Review mode ==== > @@ -1718,8 +1717,8 @@ These are (ordered from left to right): > Currently, the right thumb key is not in use. > The inner keys are both mapped to space. > > -%kc:beginInclude > || Name | Key | > +%kc:beginInclude > | backspace key | dot 7 | > | enter key | dot 8 | > | escape key | space with dot 7 | > @@ -1882,6 +1881,43 @@ Please see the [BRLTTY key tables documentation > http://mielke.cc/brltty/doc/driv > | Route to braille cell | route (bring cursor to character) | > %kc:endInclude > > ++ Braille control type and state abbreviations + > +In order to fit as much information as possible on a braille display, The > folowing abbreviations have been defined to indicate control type and > state. > + > +|| Abbreviation | Control type | > +| btn | button | > +| cbo | combo box | > +| chk | check box | > +| dlg | dialog | > +| edt | editable text field | > +| gra | graphic | > +| cN | table column number n, e.g. c1, c2. | > +| rN | table row number n, e.g. r1, r2. | > +| hN | heading at level n, e.g. h1, h2. | > +| lnk | link | > +| lst | list | > +| vlnk | visited link | > +| mnu | menu | > +| mnubar | menu bar | > +| rbtn | radio button | > +| tb | table | > +| tv | treeview | > +| lv N | a tree view item has a hierarchical level N| > +| ``-----`` | seperator | > + > +The following state indicators are also defined: > +|| Abbreviation | Control state | > +| ... | displayed when an object supports autocompletion | > +| ( ) | displayed when an object (e.g. a check box) is not checked | > +| (x) | displayed when an object (e.g. a check box) is checked | > +| (-) | displayed when an object (e.g. a check box) is half checked | > +| - | displayed when an object (e.g. a tree view item) is collapsible | > +| + | displayed when an object (e.g. a tree view item) is Expandable | > +| clk | displayed when an object is clickable | > +| ro | displayed when an object (e.g. an editable text field) is read-only > | > +| sel | displayed when an object is selected | > +| submnu | displayed when an object has a popup (usually a sub-menu) | > + > + Advanced Topics + > > ++ Advanced Customization of Symbol Pronunciation ++ > > Repository URL: https://bitbucket.org/nvdaaddonteam/nvda/ > > -- > > This is a commit notification from bitbucket.org. You are receiving > this because you have the service enabled, addressing the recipient of > this email. > > ---------------------------------------------------------------- > > NVDA add-ons Central: A list for discussing NVDA add-ons > > To post a message, send an email to nvda-addons@xxxxxxxxxxxxx. > > To unsubscribe, send an email with the subject line of "unsubscribe" > (without quotes) to nvda-addons-request@xxxxxxxxxxxxx. > > If you have questions for list moderators, please send a message to > nvda-addons-moderators@xxxxxxxxxxxxx. > > Community addons can be found here: http://addons.nvda-project.org > ---------------------------------------------------------------- NVDA add-ons Central: A list for discussing NVDA add-ons To post a message, send an email to nvda-addons@xxxxxxxxxxxxx. To unsubscribe, send an email with the subject line of "unsubscribe" (without quotes) to nvda-addons-request@xxxxxxxxxxxxx. If you have questions for list moderators, please send a message to nvda-addons-moderators@xxxxxxxxxxxxx. Community addons can be found here: http://addons.nvda-project.org