Repository: nvaccess/nvda

Issue:
J and K keys no longer navigate between tweets in Twitter app (using NVDA 2021.1 beta 1 & 2)
<!-- Please read the text in this edit field before filling it in.
Please thoroughly read NVDA's wiki article on how to fill in this template, including how to provide the required files.
Issues may be closed if the required information is not present.
https://github.com/nvaccess/nvda/blob/master/devDocs/githubIssueTemplateExplanationAndExamples.md
Please also note that the NVDA project has a Citizen and Contributor Code of Conduct which can be found at https://github.com/nvaccess/nvda/blob/master/CODE_OF_CONDUCT.md. NV Access expects that all contributors and other community members read and abide by the rules set out in this document while participating or contributing to this project. This includes creating or commenting on issues and pull requests. 

Each of the questions and sections below start with multiple hash symbols (#). Place your answers and information on the blank line below each question.
-->

### Steps to reproduce:

1. Open the Twitter app
2. Turn off NVDA's single letter navigation (NVDA+shift+spacebar
3. Press J or K to navigate between tweets

### Actual behavior:

Using NVDA 2020.4, NVDA reads the next tweet as focus moves.
Using NVDA 2021.1 Beta 1 or Beta 2, the focus moves but NVDA does not read anything.  Reading manually (eg reading current line) the focus is still on the previous tweet.

When running the 2021.1 betas, the following log fragment was generated:

```
IO - inputCore.InputManager.executeGesture (09:46:43.732) - winInputHook (21940):
Input: kb(desktop):k
DEBUGWARNING - NVDAObjects.UIA.UIA._prefetchUIACacheForPropertyIDs (09:46:43.782) - MainThread (1284):
IUIAutomationElement.buildUpdatedCache failed given IDs of {30019, 30086, 30022, 30025, 30155, 30036, 30070, 30103, 30008, 30009, 30010, 30046, 30079}
DEBUGWARNING - eventHandler.executeEvent (09:46:43.790) - MainThread (1284):
error executing event: typedCharacter on <NVDAObjects.UIA.spartanEdge.EdgeNode object at 0x0387E050> with extra args of {'ch': 'k'}
Traceback (most recent call last):
  File "eventHandler.pyc", line 246, in executeEvent
  File "eventHandler.pyc", line 96, in __init__
  File "eventHandler.pyc", line 105, in next
  File "NVDAObjects\__init__.pyc", line 1082, in event_typedCharacter
  File "speech\speech.pyc", line 1027, in speakTypedCharacters
  File "api.pyc", line 272, in isTypingProtected
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\__init__.pyc", line 937, in _get_isProtected
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\UIA\web.pyc", line 364, in _get_states
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\UIA\__init__.pyc", line 1425, in _get_states
  File "NVDAObjects\UIA\__init__.pyc", line 839, in _getUIACacheablePropertyValue
  File "comtypesMonkeyPatches.pyc", line 27, in __call__
_ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', (None, None, None, 0, None))
DEBUGWARNING - NVDAObjects.UIA.UIA._prefetchUIACacheForPropertyIDs (09:46:43.813) - MainThread (1284):
IUIAutomationElement.buildUpdatedCache failed given IDs of {30019, 30086, 30022, 30025, 30155, 30036, 30070, 30103, 30008, 30009, 30010, 30046, 30079}
DEBUGWARNING - eventHandler.executeEvent (09:46:43.814) - MainThread (1284):
error executing event: gainFocus on <NVDAObjects.UIA.spartanEdge.EdgeNode object at 0x034DDE70> with extra args of {}
Traceback (most recent call last):
  File "eventHandler.pyc", line 246, in executeEvent
  File "eventHandler.pyc", line 96, in __init__
  File "eventHandler.pyc", line 105, in next
  File "browseMode.pyc", line 1569, in event_gainFocus
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\UIA\web.pyc", line 364, in _get_states
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\UIA\__init__.pyc", line 1425, in _get_states
  File "NVDAObjects\UIA\__init__.pyc", line 839, in _getUIACacheablePropertyValue
  File "comtypesMonkeyPatches.pyc", line 27, in __call__
_ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', (None, None, None, 0, None))
```

Reading Twitter in Edge or Firefox, the J and K keys work as expected in this situation.

### Expected behavior:

NVDA should move focus to the next (or previous) tweet and read it.

### System configuration
#### NVDA installed/portable/running from source:
#### NVDA version:

NVDA 2021.1 Beta 2 installed
NVDA 2020.4 portable


#### Windows version:

Windows 10 (64-bit) Version: 2009, Build: 19042 

#### Name and version of other software in use when reproducing the issue:

#### Other information about your system:

Twitter app (no version information available?)

### Other questions
#### Does the issue still occur after restarting your computer?

#### Have you tried any other versions of NVDA? If so, please report their behaviors.

#### If add-ons are disabled, is your problem still occurring?

#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?



Discussion:
Not sure why the text got all jumbled up there.  Here's the same log fragment as text:

[twitterlog.txt](https://github.com/nvaccess/nvda/files/6612613/twitterlog.txt)


Resolving patch:
diff --git a/source/browseMode.py b/source/browseMode.py
--- a/source/browseMode.py
+++ b/source/browseMode.py
@@ -1566,8 +1566,16 @@ def event_gainFocus(self, obj, nextHandler):
 		# If the previous focus object was removed, we might hit a false positive for overlap detection.
 		# Track the previous focus target so that we can account for this scenario.
 		previousFocusObjIsDefunct = False
-		if self._lastFocusObj and controlTypes.STATE_DEFUNCT in self._lastFocusObj.states:
-			previousFocusObjIsDefunct = True
+		if self._lastFocusObj:
+			try:
+				states = self._lastFocusObj.states
+				previousFocusObjIsDefunct = controlTypes.STATE_DEFUNCT in states
+			except Exception:
+				log.debugWarning(
+					"Error fetching states when checking for defunct object. Treating object as defunct anyway.",
+					exc_info=True
+				)
+				previousFocusObjIsDefunct = True
 
 		self._lastFocusObj=obj
 


Test patch: