Thanks for that! On 10/27/14, Noelia <nrm1977@xxxxxxxxx> wrote: > Hi, thanks Joseph. > I am not a NVDA commiter, that is, I can't modify the repo maintainer by > NVAccess. > However, I'm a member of NVDA add-on team, and can write to the NVDA > repo forked at > https://bitbucket.org/nvdaaddonteam/nvda > I feel that your ticket (4354) is very interesting, and I recently > started reading a book: Story of mathematics, writen by Boyer. I know > that I will find symbols there (it's digitalized in Word), and I wanted > to experiment with a branch for this ticket. > So, if I can continue, the commits will be send to add-ons commits list, > and the answers, to the add-on list. > Thanks. > > > El 27/10/2014 6:53, Bhavya shah escribió: >> Hmm. >> Interesting, I understood, thanks for the clarification. >> >> On 10/27/14, Joseph Lee <joseph.lee22590@xxxxxxxxx> wrote: >>> Hi, >>> Here's the story: >>> As you pointed out, the below message would have been good for >>> development >>> list. However, I sent the below notice here, seeing that Noelia forked >>> this >>> branch from an older version of the master branch. You see, NV Access >>> isn't >>> the only one which hosts complete NVDA repository - there exists another >>> repository at Bitbucket under the add-ons team account which mirrors the >>> NV >>> Access repository and is meant for developers with Bitbucket account to >>> experiment with new features, like what Noelia is doing with ticket >>> 4354. >>> Besides this branch, we have other branches at the Bitbucket repo, and >>> NV >>> Access and other developers maintain NVDA repos at Bitbucket (I have one >>> at >>> Bitbucket which has additional branches such as post Windows XP builds >>> and >>> a >>> branch with missing translator comments added). >>> Unlike the NV Access repo, the Bitbucket NVDA add-ons team repo is >>> updated >>> on a semi-regular basis. Until a few weeks ago, when Mesar integrated >>> various localizations into NVDA snapshots, he updated Bitbucket repo as >>> well >>> (he hasn't done that for a while). Thus after noticing that Noelia was >>> using >>> an older code, I updated the NVDA add-ons team repo to reflect latest >>> changes from NV Access repo so Noelia can have a more recent code from >>> which >>> she can work on her branch (this affects my post Windows XP builds as >>> well, >>> as it was sort of forked from the add-ons team repo), hence the notice >>> came >>> to this list. >>> Hope this helps (I hope I didn't confuse you; I'll answer other repo >>> questions after the Tek Talk event). >>> Cheers, >>> Joseph >>> >>> -----Original Message----- >>> From: nvda-addons-bounce@xxxxxxxxxxxxx >>> [mailto:nvda-addons-bounce@xxxxxxxxxxxxx] On Behalf Of Bhavya shah >>> Sent: Sunday, October 26, 2014 10:34 PM >>> To: nvda-addons@xxxxxxxxxxxxx >>> Subject: [nvda-addons] Re: commit/nvda: josephsl: Merge branch 'master' >>> into >>> t4354 >>> >>> 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','${n >>> vdaHelperLogLevel}'),('_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/lotusNotesRichTex >>> t/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_IAcc >>> essible2,(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.compa >>> re(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-c >>> hildStart,childLength),text,useMarkup); >>>> + >>> child->getTextInRange(max(startOffset,childStart)-childStart,min(endOffset-c >>> hildStart,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/iaccessi >>> ble2 >>>> * 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.uniqueNumb >>> er >>>> + 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=No >>> ne,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._ra >>> ngeObj.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.POSITIO >>> N_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_SY >>> STEM_FOCUSABLE:[1]} >>>> + >>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT,oleacc.ROLE_SYSTEM_COMBO >>> BOX],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_READONLY:[None],"IAccessibl >>> e::state_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1],"IHTMLElement::%s"%"isContent >>> Editable":[1]} >>>> elif nodeType=="radioButton": >>>> >>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_RADIOBUTTON],"IAccessible::st >>> ate_%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_COMBO >>> BOX],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_READONLY:[None],"IAccessibl >>> e2::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 >>> >>> ---------------------------------------------------------------- >>> >>> 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 >> > ---------------------------------------------------------------- > > 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