Skip to content

Commit

Permalink
Fix browse mode in Firefox extension popups. (#7809)
Browse files Browse the repository at this point in the history
Firefox extensions can pop up documents to provide access to their functionality without creating a new browser tab.
For example, both the LastPass and bitwarden password managers pop up a document allowing you to access your vault, add a site, etc. when you press their button on the toolbar.
Previously, browse mode only worked in these documents when you were focused on the document itself.
If you focused something inside the document (e.g. a link, a button or a text box), browse mode functionality ceased to work.
This could happen even if you moved the browse mode cursor, so you would suddenly be "thrown out" of browse mode.

This occurred because the Gecko vbuf code to handle combo box popups was being incorrectly used in this case.
It only checked for Mozilla popup windows, but these popup documents are also popup windows.
It walked to the nearest ancestor with a different HWND, but that meant that the document was skipped.
Thus, anything inside the document was never considered to be part of the document.
Now, the code to deal with combo box popups has been tightened so that it only matches those.
  • Loading branch information
jcsteh authored and michaelDCurran committed Dec 20, 2017
1 parent eb2647d commit 359fba3
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions source/virtualBuffers/gecko_ia2.py
Expand Up @@ -2,7 +2,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) 2008-2017 NV Access Limited, Babbage B.V.
#Copyright (C) 2008-2017 NV Access Limited, Babbage B.V., Mozilla Corporation

from . import VirtualBuffer, VirtualBufferTextInfo, VBufStorage_findMatch_word, VBufStorage_findMatch_notEmpty
import treeInterceptorHandler
Expand Down Expand Up @@ -99,14 +99,29 @@ def _get_shouldPrepare(self):
return False
return True

def _getExpandedComboBox(self, obj):
"""If obj is an item in an expanded combo box, get the combo box.
"""
if not (obj.windowClassName.startswith('Mozilla') and obj.windowStyle & winUser.WS_POPUP):
# This is not a Mozilla popup window, so it can't be an expanded combo box.
return None
if obj.role not in (controlTypes.ROLE_LISTITEM, controlTypes.ROLE_LIST):
return None
parent = obj.parent
# Try a maximum of 2 ancestors, since we might be on the list item or the list.
for i in xrange(2):
obj = obj.parent
if not obj:
return None
if obj.role == controlTypes.ROLE_COMBOBOX:
return obj
return None

def __contains__(self,obj):
#Special code to handle Mozilla combobox lists
if obj.windowClassName.startswith('Mozilla') and winUser.getWindowStyle(obj.windowHandle)&winUser.WS_POPUP:
parent=obj.parent
while parent and parent.windowHandle==obj.windowHandle:
parent=parent.parent
if parent:
obj=parent.parent
# if this is a Mozilla combo box popup, we want to work with the combo box.
combo = self._getExpandedComboBox(obj)
if combo:
obj = combo
if not (isinstance(obj,NVDAObjects.IAccessible.IAccessible) and isinstance(obj.IAccessibleObject,IAccessibleHandler.IAccessible2)) or not obj.windowClassName.startswith('Mozilla') or not winUser.isDescendantWindow(self.rootNVDAObject.windowHandle,obj.windowHandle):
return False
if self.rootNVDAObject.windowHandle==obj.windowHandle:
Expand Down

0 comments on commit 359fba3

Please sign in to comment.