Skip to content

Commit 25cb221

Browse files
Merge a8e98fb into 79ad4f0
2 parents 79ad4f0 + a8e98fb commit 25cb221

1 file changed

Lines changed: 33 additions & 11 deletions

File tree

source/browseMode.py

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,11 @@ def _set_selection(self, info, reason=OutputReason.CARET):
14061406
followBrowseModeFocus = config.conf["virtualBuffers"]["autoFocusFocusableElements"]
14071407
if followBrowseModeFocus or self.passThrough:
14081408
focusObj.setFocus()
1409+
# Track this object as NVDA having just requested setting focus to it
1410+
# So that when NVDA does receive the focus event for it
1411+
# It can handle it quietly rather than speaking the new focus.
1412+
if followBrowseModeFocus:
1413+
self._objPendingFocusBeforeActivate = obj
14091414
# Queue the reporting of pass through mode so that it will be spoken after the actual content.
14101415
queueHandler.queueFunction(queueHandler.eventQueue, reportPassThrough, self)
14111416

@@ -1623,12 +1628,30 @@ def event_gainFocus(self, obj, nextHandler):
16231628
self._replayFocusEnteredEvents()
16241629
return nextHandler()
16251630

1626-
#We only want to update the caret and speak the field if we're not in the same one as before
1627-
caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
1628-
# Expand to one character, as isOverlapping() doesn't treat, for example, (4,4) and (4,5) as overlapping.
1629-
caretInfo.expand(textInfos.UNIT_CHARACTER)
1630-
isOverlapping = focusInfo.isOverlapping(caretInfo)
1631-
if not self._hadFirstGainFocus or not isOverlapping or (isOverlapping and previousFocusObjIsDefunct):
1631+
# Save off and clear any previous object that was focused by NVDA
1632+
# and waiting on a focus event.
1633+
objPendingFocusBeforeActivate = self._objPendingFocusBeforeActivate
1634+
self._objPendingFocusBeforeActivate = None
1635+
1636+
# We do not want to speak the new focus and update the caret if...
1637+
if not self._hadFirstGainFocus or previousFocusObjIsDefunct:
1638+
# still initializing or the old focus is dead.
1639+
isOverlapping = False
1640+
elif config.conf["virtualBuffers"]["autoFocusFocusableElements"]:
1641+
# if this focus event was caused by NVDA setting the focus itself
1642+
# Due to auto focus focusable elements option being enabled,
1643+
# And we detect that the caret was already positioned within the focus.
1644+
# Note that this is not the default and may be removed in future.
1645+
caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
1646+
# Expand to one character, as isOverlapping() doesn't treat, for example, (4,4) and (4,5) as overlapping.
1647+
caretInfo.expand(textInfos.UNIT_CHARACTER)
1648+
isOverlapping = focusInfo.isOverlapping(caretInfo)
1649+
else:
1650+
# if this focus event was caused by NVDA setting the focus itself
1651+
# due to activation or applications key etc.
1652+
isOverlapping = (obj == objPendingFocusBeforeActivate)
1653+
1654+
if not isOverlapping:
16321655
# The virtual caret is not within the focus node.
16331656
oldPassThrough=self.passThrough
16341657
passThrough = self.shouldPassThrough(obj, reason=OutputReason.FOCUS)
@@ -1666,9 +1689,9 @@ def event_gainFocus(self, obj, nextHandler):
16661689
# Note: this is usually called after the caret movement.
16671690
vision.handler.handleGainFocus(obj)
16681691
elif (
1669-
self._objPendingFocusBeforeActivate
1670-
and obj == self._objPendingFocusBeforeActivate
1671-
and obj is not self._objPendingFocusBeforeActivate
1692+
objPendingFocusBeforeActivate
1693+
and obj == objPendingFocusBeforeActivate
1694+
and obj is not objPendingFocusBeforeActivate
16721695
):
16731696
# With auto focus focusable elements disabled, when the user activates
16741697
# an element (e.g. by pressing enter) or presses a key which we pass
@@ -1680,10 +1703,9 @@ def event_gainFocus(self, obj, nextHandler):
16801703
# the properties before the activation/key, so use that to speak any
16811704
# changes.
16821705
speech.speakObject(
1683-
self._objPendingFocusBeforeActivate,
1706+
objPendingFocusBeforeActivate,
16841707
OutputReason.CHANGE
16851708
)
1686-
self._objPendingFocusBeforeActivate = None
16871709
else:
16881710
self._replayFocusEnteredEvents()
16891711
return nextHandler()

0 commit comments

Comments
 (0)