Repository: nvaccess/nvda

Issue:
Unwanted Alt gesture is being sent to  applications, which typically triggers main menu, in certain situations, when NVDA gesture contains Alt modifier.
### Description
I put down two ways to reproduce this problem. One of them is using my add-on SentenceNav, the other one using another my add-on IndentNav. However, this issue is not add-on related per se, it is rather related to how NVDA handles keystrokes containing Alt modifier. I wasn't able to find many built-in NVDA gestures with Alt modifier, therefore using some from my add-ons.
I've been able to track down the source of this bug to commit 9ab0ef826c21af0e646a1832fea1d01742a28317, therefore cc author @michaelDCurran. 
My best understaneding of what's happening, is that for long running gestures, if you release Alt modifier before the gesture is done executing, then NVDA decides to send a raw Alt keystroke, or something that is interpreted as raw Alt keystroke to the application, thus triggering the main menu.
### Steps to reproduce 1:
1. Install IndentNav add-on: https://github.com/mltony/nvda-indent-nav/releases/latest/download/IndentNav.nvda-addon
2. Download Test file and open it in Notepad: http://elk.duckdns.org/test.txt
3. Position the cursor on the first line of the file.
4. Press NVDA+Alt+DownArrow to find the next line with the same indentation level and release NVDA and Alt modifiers quickly enough - within approximately half a second.
### Actual behavior 1:
Main menu is activated - which I suspect due to the fact that raw Alt keystroke has been sent to the application.
### Expected behavior 1:
Main menu should not be activated.
### Steps to reproduce 2:
1. Install SentenceNav add-on: https://github.com/mltony/nvda-sentence-nav/releases/latest/download/SentenceNav.nvda-addon
2. Open facebook.com in Firefox. This issue is not specific to facebook or Firefox, however, it can be more easily reproduced by slower-to-react environments, which I found facebook in firefox to be.
3. Find some text post in facebook feed, or a text comment.
4. Press Alt+Down or Alt+Up; try to release the Alt key as soon as possible.
### Actual behavior 2:
Often times the focus will jump to main menu.
### Expected behavior 2:
Main menu should not be activated.

### System configuration
#### NVDA installed/portable/running from source:
Installed/running from installer

#### NVDA version:
alpha-20739 and later.

#### Windows version:
Windows 10;
Version 1803 (OS Build 17134.1667)
#### Name and version of other software in use when reproducing the issue:
Notepad; Firefox 80.0.1 (64-bit).
#### Other information about your system:

### Other questions
#### Does the issue still occur after restarting your computer?
Yes
#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Yes, alpha-20718 and prior work just fine.
#### If addons are disabled, is your problem still occuring?
I need two add-ons to reproduce this, however, I disabled all the other add-ons to make this case clean.
#### Did you try to run the COM registry fixing tool in NVDA menu / tools?
Yes.


Discussion:
I can often reproduce this with all addons disabled in Internet Explorer. Especially when performing table navigation with ctrl+alt+arrow keys. When releasing the keys, NVDA activates the menu and I have to press escape to exit it. This results in loss of focus, and on complex web pages unfortunately it is very frustrating. Our CRM system at work runs only under Internet Explorer, but I have also seen this behavior in Google Chrome from time to time.
This sounds like a regression that needs to be investigated before the release of 2020.3. Therefore I"m setting the milestone to investigate.
I have also seen this issue many times, maybe using table navigation commands, previous/next sentence shortcut in Sentence Nav add-on or using Alt+Number shortcut of Outlook Extended add-on. But I did not find an reliable way to reproduce at the time.

We'll take a look at this next week. We may do a beta 1 on Monday and address this in a subsequent beta.

Resolving patch:
diff --git a/source/keyboardHandler.py b/source/keyboardHandler.py
--- a/source/keyboardHandler.py
+++ b/source/keyboardHandler.py
@@ -322,10 +322,6 @@ class KeyboardInputGesture(inputCore.InputGesture):
 	"""A key pressed on the traditional system keyboard.
 	"""
 
-	#: the number of times this gesture instance has been sent as input
-	# I.e. Gesture.send was called.
-	sendCount = 0
-
 #: All normal modifier keys, where modifier vk codes are mapped to a more general modifier vk code
 # or C{None} if not applicable.
 	#: @type: dict
@@ -503,17 +499,21 @@ def _reportToggleKey(self):
 			state=_("on") if toggleState else _("off")))
 
 	def executeScript(self, script):
-		super().executeScript(script)
-		if self.sendCount == 0 and canModifiersPerformAction(self.generalizedModifiers):
+		if canModifiersPerformAction(self.generalizedModifiers):
 			# #3472: These modifiers can perform an action if pressed alone
 			# and we've just totally consumed the main key.
 			# Send special reserved vkcode VK_NONE (0xff)
 			# to at least notify the app's key state that something happened.
 			# This allows alt and windows to be bound to scripts and
 			# stops control+shift from switching keyboard layouts in cursorManager selection scripts.
+			# This must be done before executing the script,
+			# As if the script takes a long time and the user releases these modifier keys before the script finishes,
+			# it is already too late.
 			with ignoreInjection():
 				winUser.keybd_event(winUser.VK_NONE, 0, 0, 0)
 				winUser.keybd_event(winUser.VK_NONE, 0, winUser.KEYEVENTF_KEYUP, 0)
+		# Now actually execute the script.
+		super().executeScript(script)
 
 	def send(self):
 		keys = []
@@ -547,7 +547,6 @@ def send(self):
 				# has been injected and NVDA has received and processed it.
 				time.sleep(0.01)
 				wx.Yield()
-		self.sendCount += 1
 
 	@classmethod
 	def fromName(cls, name):


Test patch: