3 new commits in nvda: https://bitbucket.org/nvdaaddonteam/nvda/commits/bcb22285da8e/ Changeset: bcb22285da8e Branch: None User: mdcurran Date: 2013-09-16 03:12:09 Summary: Merge branch 't3397'. Fixes #3397 Affected #: 4 files diff --git a/nvdaHelper/vbufBackends/mshtml/mshtml.cpp b/nvdaHelper/vbufBackends/mshtml/mshtml.cpp index 8f2adb6..e8590b4 100755 --- a/nvdaHelper/vbufBackends/mshtml/mshtml.cpp +++ b/nvdaHelper/vbufBackends/mshtml/mshtml.cpp @@ -561,8 +561,12 @@ inline void fillTextFormattingForNode(IHTMLDOMNode* pHTMLDOMNode, VBufStorage_fi inline void fillTextFormattingForTextNode(VBufStorage_controlFieldNode_t* parentNode, VBufStorage_textFieldNode_t* textNode) //text nodes don't support IHTMLElement2 interface, so using style information from parent node { - IHTMLElement2* pHTMLElement2=(static_cast<MshtmlVBufStorage_controlFieldNode_t*>(parentNode))->pHTMLElement2; - fillTextFormatting_helper(pHTMLElement2,textNode); + IHTMLElement2* pHTMLElement2=NULL; + static_cast<MshtmlVBufStorage_controlFieldNode_t*>(parentNode)->pHTMLDOMNode->QueryInterface(IID_IHTMLElement2,(void**)&pHTMLElement2); + if(pHTMLElement2) { + fillTextFormatting_helper(pHTMLElement2,textNode); + pHTMLElement2->Release(); + } } const int TABLEHEADER_COLUMN = 0x1; @@ -1227,11 +1231,11 @@ void MshtmlVBufBackend_t::render(VBufStorage_buffer_t* buffer, int docHandle, in LOG_DEBUG(L"Error getting document using WM_HTML_GETOBJECT"); return; } -IHTMLDOMNode* pHTMLDOMNode=NULL; + IHTMLDOMNode* pHTMLDOMNode=NULL; if(oldNode!=NULL) { - IHTMLElement2* pHTMLElement2=(static_cast<MshtmlVBufStorage_controlFieldNode_t*>(oldNode))->pHTMLElement2; - nhAssert(pHTMLElement2); - pHTMLElement2->QueryInterface(IID_IHTMLDOMNode,(void**)&pHTMLDOMNode); + pHTMLDOMNode=(static_cast<MshtmlVBufStorage_controlFieldNode_t*>(oldNode))->pHTMLDOMNode; + nhAssert(pHTMLDOMNode); + pHTMLDOMNode->AddRef(); } else { IHTMLDocument3* pHTMLDocument3=NULL; if(ObjectFromLresult(res,IID_IHTMLDocument3,0,(void**)&pHTMLDocument3)!=S_OK) { diff --git a/nvdaHelper/vbufBackends/mshtml/node.cpp b/nvdaHelper/vbufBackends/mshtml/node.cpp index c7d9b5b..84f44a8 100755 --- a/nvdaHelper/vbufBackends/mshtml/node.cpp +++ b/nvdaHelper/vbufBackends/mshtml/node.cpp @@ -14,8 +14,10 @@ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html #include <list> #include <windows.h> +#include <objbase.h> #include <oleidl.h> #include <mshtml.h> +#include <mshtmdid.h> #include <common/log.h> #include "mshtml.h" #include "node.h" @@ -25,33 +27,66 @@ using namespace std; class CDispatchChangeSink : public IDispatch { private: ULONG refCount; - bool hasFired; + MshtmlVBufStorage_controlFieldNode_t* storageNode; + IConnectionPoint* pConnectionPoint; + DWORD dwCookie; public: - MshtmlVBufStorage_controlFieldNode_t* storageNode; - bool allowDelete; - CDispatchChangeSink(MshtmlVBufStorage_controlFieldNode_t* storageNode): - refCount(1), - hasFired(false), - allowDelete(true) { + CDispatchChangeSink(MshtmlVBufStorage_controlFieldNode_t* storageNode) : + refCount(1), dwCookie(0), pConnectionPoint(NULL) { nhAssert(storageNode); this->storageNode=storageNode; incBackendLibRefCount(); } - ~CDispatchChangeSink() { - decBackendLibRefCount(); + BOOL connect(IHTMLDOMNode* pHTMLDOMNode, REFIID iid) { + if(dwCookie) { + LOG_DEBUGWARNING(L"Already connected"); + return false; + } + IHTMLElement* pHTMLElement=NULL; + pHTMLDOMNode->QueryInterface(IID_IHTMLElement,(void**)&pHTMLElement); + if(!pHTMLElement) { + LOG_DEBUGWARNING(L"QueryInterface to IHTMLElement failed"); + return false; + } + IConnectionPointContainer* pConnectionPointContainer=NULL; + pHTMLElement->QueryInterface(IID_IConnectionPointContainer,(void**)&pConnectionPointContainer); + pHTMLElement->Release(); + if(!pConnectionPointContainer) { + LOG_DEBUGWARNING(L"QueryInterface to IConnectionPointContainer failed"); + return false; + } + IConnectionPoint* pConnectionPoint=NULL; + pConnectionPointContainer->FindConnectionPoint(iid,&pConnectionPoint); + pConnectionPointContainer->Release(); + if(!pConnectionPoint) { + return false; + } + DWORD dwCookie=0; + pConnectionPoint->Advise(this,&dwCookie); + if(!dwCookie) { + pConnectionPoint->Release(); + return false; + } + this->pConnectionPoint=pConnectionPoint; + this->dwCookie=dwCookie; + return true; } - void onChange() { - if(hasFired||allowDelete) { - return; - } - hasFired=true; - LOG_DEBUG(L"Marking storage node as invalid"); - this->storageNode->backend->invalidateSubtree(this->storageNode); - LOG_DEBUG(L"Done"); + BOOL disconnect() { + if(this->dwCookie==0) return false; + this->pConnectionPoint->Unadvise(this->dwCookie); + this->dwCookie=0; + this->pConnectionPoint->Release(); + this->pConnectionPoint=NULL; + return true; + } + + ~CDispatchChangeSink() { + this->disconnect(); + decBackendLibRefCount(); } HRESULT STDMETHODCALLTYPE IUnknown::QueryInterface(REFIID riid, void** pvpObject) { @@ -77,28 +112,18 @@ class CDispatchChangeSink : public IDispatch { if(this->refCount>0) this->refCount--; if(this->refCount==0) { - if (this->allowDelete) { - delete this; - } else { - #ifdef DEBUG - Beep(660,50); - #endif - LOG_DEBUG(L"refCount hit 0 before it should, not deleting, node info: " << this->storageNode->getDebugInfo()); - } + delete this; return 0; } return this->refCount; } HRESULT STDMETHODCALLTYPE IDispatch::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr) { - if(dispIdMember==0) { - LOG_DEBUG(L"calling onChange"); - this->onChange(); - LOG_DEBUG(L"Done, returning S_OK"); + if(dispIdMember==DISPID_EVMETH_ONPROPERTYCHANGE||dispIdMember==DISPID_EVMETH_ONLOAD) { + this->storageNode->backend->invalidateSubtree(this->storageNode); return S_OK; } - LOG_DEBUG(L"invoke called with unknown member ID, returning E_INVALIDARG"); - return E_INVALIDARG; + return E_FAIL; } HRESULT STDMETHODCALLTYPE IDispatch::GetTypeInfoCount(UINT* count) { @@ -238,48 +263,22 @@ class CHTMLChangeSink : public IHTMLChangeSink { }; MshtmlVBufStorage_controlFieldNode_t::MshtmlVBufStorage_controlFieldNode_t(int docHandle, int ID, bool isBlock, MshtmlVBufBackend_t* backend, IHTMLDOMNode* pHTMLDOMNode,const wstring& lang): VBufStorage_controlFieldNode_t(docHandle,ID,isBlock), language(lang) { - VARIANT_BOOL varBool; nhAssert(backend); nhAssert(pHTMLDOMNode); this->backend=backend; - this->pHTMLElement2=NULL; + pHTMLDOMNode->AddRef(); + this->pHTMLDOMNode=pHTMLDOMNode; this->propChangeSink=NULL; this->loadSink=NULL; this->pHTMLChangeSink=NULL; this->HTMLChangeSinkCookey=0; - pHTMLDOMNode->QueryInterface(IID_IHTMLElement2,(void**)&(this->pHTMLElement2)); - if(!this->pHTMLElement2) { - LOG_DEBUG(L"Could not queryInterface from IHTMLDOMNode to IHTMLElement2"); - } - if(this->pHTMLElement2) { - CDispatchChangeSink* propChangeSink=new CDispatchChangeSink(this); - // It seems that IE 6 sometimes calls Release() once too many times. - // We don't want propChangeSink to be deleted until we're finished with it. - propChangeSink->allowDelete=false; - if((pHTMLElement2->attachEvent(L"onpropertychange",propChangeSink,&varBool)==S_OK)&&varBool) { - this->propChangeSink=propChangeSink; - } else { - LOG_DEBUG(L"Error attaching onPropertyChange event sink to IHTMLElement2 at "<<pHTMLElement2); - propChangeSink->allowDelete=true; - propChangeSink->Release(); - } - } BSTR nodeName=NULL; pHTMLDOMNode->get_nodeName(&nodeName); - if(nodeName!=NULL&&(_wcsicmp(nodeName,L"frame")==0||_wcsicmp(nodeName,L"iframe")==0||_wcsicmp(nodeName,L"img")==0||_wcsicmp(nodeName,L"input")==0)) { - if(this->pHTMLElement2) { - CDispatchChangeSink* loadSink=new CDispatchChangeSink(this); - // It seems that IE 6 sometimes calls Release() once too many times. - // We don't want loadSink to be deleted until we're finished with it. - loadSink->allowDelete=false; - if((pHTMLElement2->attachEvent(L"onload",loadSink,&varBool)==S_OK)&&varBool) { - this->loadSink=loadSink; - } else { - LOG_DEBUG(L"Error attaching onload event sink to IHTMLElement2 at "<<pHTMLElement2); - loadSink->allowDelete=true; - loadSink->Release(); - } - } + CDispatchChangeSink* propChangeSink=new CDispatchChangeSink(this); + if(propChangeSink->connect(pHTMLDOMNode,IID_IDispatch)) { + this->propChangeSink=propChangeSink; + } else { + propChangeSink->Release(); } if(nodeName!=NULL&&(_wcsicmp(nodeName,L"body")==0||_wcsicmp(nodeName,L"frameset")==0)) { IHTMLDOMNode2* pHTMLDOMNode2=NULL; @@ -317,23 +316,15 @@ MshtmlVBufStorage_controlFieldNode_t::MshtmlVBufStorage_controlFieldNode_t(int d MshtmlVBufStorage_controlFieldNode_t::~MshtmlVBufStorage_controlFieldNode_t() { if(this->propChangeSink) { - nhAssert(this->pHTMLElement2); - if(pHTMLElement2->detachEvent(L"onpropertychange",this->propChangeSink)!=S_OK) { - LOG_DEBUG(L"Error detaching onpropertychange event sink from IHTMLElement2"); + if(!(static_cast<CDispatchChangeSink*>(this->propChangeSink)->disconnect())) { + LOG_DEBUGWARNING(L"Failed to stop listening with HTMLElementEvents2 for node "<<this->getDebugInfo()); } - static_cast<CDispatchChangeSink*>(this->propChangeSink)->allowDelete=true; this->propChangeSink->Release(); + this->propChangeSink=NULL; } - if(this->loadSink) { - nhAssert(this->pHTMLElement2); - if(pHTMLElement2->detachEvent(L"onload",this->loadSink)!=S_OK) { - LOG_DEBUG(L"Error detaching onload event sink from IHTMLElement2"); - } - static_cast<CDispatchChangeSink*>(this->loadSink)->allowDelete=true; - this->loadSink->Release(); - } - if(this->pHTMLElement2) { - this->pHTMLElement2->Release(); + if(this->pHTMLDOMNode) { + this->pHTMLDOMNode->Release(); + this->pHTMLDOMNode=NULL; } if(this->pHTMLChangeSink) { nhAssert(this->pMarkupContainer2); diff --git a/nvdaHelper/vbufBackends/mshtml/node.h b/nvdaHelper/vbufBackends/mshtml/node.h index 7fc7ae6..ec43b80 100755 --- a/nvdaHelper/vbufBackends/mshtml/node.h +++ b/nvdaHelper/vbufBackends/mshtml/node.h @@ -24,7 +24,7 @@ class MshtmlVBufStorage_controlFieldNode_t : public VBufStorage_controlFieldNode public: MshtmlVBufBackend_t* backend; - IHTMLElement2* pHTMLElement2; + IHTMLDOMNode* pHTMLDOMNode; IDispatch* propChangeSink; IDispatch* loadSink; IMarkupContainer2* pMarkupContainer2; diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t index b16889d..0109e1c 100644 --- a/user_docs/en/changes.t2t +++ b/user_docs/en/changes.t2t @@ -17,6 +17,7 @@ - NVDA will now report the pinned state for pinned controls such as tabs in Mozilla Firefox. (#3372) - It is now possible to bind scripts to keyboard gestures containing Alt and/or Windows keys as modifiers. Previously, if this was done, performing the script would cause the Start Menu or menu bar to be activated. (#3472) - Selecting text in browse mode documents (e.g. using control+shift+end) no longer causes the keyboard layout to be switched on systems with multiple keyboard layouts installed. (#3472) +- Internet Explorer should no longer crash or become unusable when closing NVDA. (#3397) = 2013.2 = https://bitbucket.org/nvdaaddonteam/nvda/commits/b37c884644c0/ Changeset: b37c884644c0 Branch: None User: jteh Date: 2013-09-16 04:36:06 Summary: English User Guide: Pluralisation fix. Translators should ignore. Affected #: 1 file diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t index ba9af2e..fb0bc56 100644 --- a/user_docs/en/userGuide.t2t +++ b/user_docs/en/userGuide.t2t @@ -633,7 +633,7 @@ The Voice Settings dialog box contains the following options: ==== Voice ==== The first option that you land on in this dialog is a combo box listing all the voices of the current synthesizer that you have installed. You can use the arrow keys to listen to all the various choices. -Left and Up arrow take you up in the list, while right and down arrow moves you down in the list. +Left and Up arrow take you up in the list, while right and down arrow move you down in the list. ==== Variant ==== If you are using the Espeak synthesizer that is packaged with NVDA, this is a combo box that lets you select the Variant the synthesizer should speak with. https://bitbucket.org/nvdaaddonteam/nvda/commits/55903f8f0936/ Changeset: 55903f8f0936 Branch: master User: mdcurran Date: 2013-09-17 01:50:09 Summary: Merge branch 't3468'. Fixes #3468 Affected #: 2 files diff --git a/source/keyboardHandler.py b/source/keyboardHandler.py index e934d75..ed7090b 100644 --- a/source/keyboardHandler.py +++ b/source/keyboardHandler.py @@ -3,7 +3,7 @@ #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) 2006-2010 Michael Curran <mick@xxxxxxxxxx>, James Teh <jamie@xxxxxxxxxxx>, Peter Vágner <peter.v@xxxxxxxxxxx>, Aleksey Sadovoy <lex@xxxxxx> +#Copyright (C) 2006-2013 NV Access Limited, Peter Vágner, Aleksey Sadovoy """Keyboard support""" @@ -323,6 +323,11 @@ class KeyboardInputGesture(inputCore.InputGesture): return "plus" return unichr(vkChar).lower() + if self.vkCode == 0xFF: + # #3468: This key is unknown to Windows. + # GetKeyNameText often returns something inappropriate in these cases + # due to disregarding the extended flag. + return "unknown_%02x" % self.scanCode return winUser.getKeyNameText(self.scanCode, self.isExtended) def _get_modifierNames(self): @@ -343,7 +348,11 @@ class KeyboardInputGesture(inputCore.InputGesture): key="+".join(self._keyNamesInDisplayOrder)) def _get_displayName(self): - return "+".join(localizedKeyLabels.get(key, key) for key in self._keyNamesInDisplayOrder) + return "+".join( + # Translators: Reported for an unknown key press. + # %s will be replaced with the key code. + _("unknown %s") % key[8:] if key.startswith("unknown_") + else localizedKeyLabels.get(key, key) for key in self._keyNamesInDisplayOrder) def _get_identifiers(self): keyNames = set(self.modifierNames) @@ -358,6 +367,11 @@ class KeyboardInputGesture(inputCore.InputGesture): if self.isExtended and winUser.VK_VOLUME_MUTE <= self.vkCode <= winUser.VK_VOLUME_UP: # Don't report volume controlling keys. return False + if self.vkCode == 0xFF: + # #3468: This key is unknown to Windows. + # This could be for an event such as gyroscope movement, + # so don't report it. + return False # Aside from space, a key name of more than 1 character is a command. if self.vkCode != winUser.VK_SPACE and len(self.mainKeyName) > 1: return True @@ -372,6 +386,11 @@ class KeyboardInputGesture(inputCore.InputGesture): return self.SPEECHEFFECT_CANCEL if self.isExtended and winUser.VK_VOLUME_MUTE <= self.vkCode <= winUser.VK_VOLUME_UP: return None + if self.vkCode == 0xFF: + # #3468: This key is unknown to Windows. + # This could be for an event such as gyroscope movement, + # so don't interrupt speech. + return None if not config.conf['keyboard']['speechInterruptForCharacters'] and (not self.shouldReportAsCommand or self.vkCode in (winUser.VK_SHIFT, winUser.VK_LSHIFT, winUser.VK_RSHIFT)): return None if self.vkCode==winUser.VK_RETURN and not config.conf['keyboard']['speechInterruptForEnter']: diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t index 0109e1c..3d42657 100644 --- a/user_docs/en/changes.t2t +++ b/user_docs/en/changes.t2t @@ -18,6 +18,7 @@ - It is now possible to bind scripts to keyboard gestures containing Alt and/or Windows keys as modifiers. Previously, if this was done, performing the script would cause the Start Menu or menu bar to be activated. (#3472) - Selecting text in browse mode documents (e.g. using control+shift+end) no longer causes the keyboard layout to be switched on systems with multiple keyboard layouts installed. (#3472) - Internet Explorer should no longer crash or become unusable when closing NVDA. (#3397) +- Physical movement and other events on some newer computers are no longer treated as inappropriate key presses. Previously, this silenced speech and sometimes triggered NVDA commands. (#3468) = 2013.2 = 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.