Repository: nvaccess/nvda

Issue:
Windows 10 build 14366: Toasts are not announced
Hi,

A user using Insider build 14366 reports that toasts are no longer announced.

STR:
1. Using Insider build 14366/14367, perform an action that causes toasts to appear, such as connecting hardware.
2. Listen for toast sound.

Expected: NVDA announces toasts.
Actual: NVDA does not announce toasts.
Cause: Accessibility event Checker (accevent) says toasts do not fire tooltip open event, only window open event is fired. This does not happen with Narrator: when toasts appear, because it listens to window open event, it announces them. I was able to reproduce this on 14366/14367, and can confirm that toasts are announced in build 10586.

Technical: NVDA's UIA handler has a map of which UIA events corresponds to NVDA events. This map does not contain window open event, yet tooltip open event is assigned to alert event. We don't want to listen to window open event, as it causes a flood of events to come through, especially for objects that we do not wish to announce. One workaround would be to tell NVDA that certain windows are safe, thereby allowing window open event from objects such as toasts to be accepted. All this changes if Microsoft fixes this before Anniversary Update (Version 1607) is released (feedback sent to Microsoft).

Thanks.



Discussion:

Resolving patch:
diff --git a/source/NVDAObjects/UIA/__init__.py b/source/NVDAObjects/UIA/__init__.py
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -8,6 +8,7 @@
 from ctypes.wintypes import POINT, RECT
 from comtypes import COMError
 import weakref
+import sys
 import UIAHandler
 import globalVars
 import eventHandler
@@ -19,7 +20,7 @@
 from logHandler import log
 from NVDAObjects.window import Window
 from NVDAObjects import NVDAObjectTextInfo, InvalidNVDAObject
-from NVDAObjects.behaviors import ProgressBar, EditableTextWithoutAutoSelectDetection, Dialog
+from NVDAObjects.behaviors import ProgressBar, EditableTextWithoutAutoSelectDetection, Dialog, Notification
 import braille
 
 class UIATextInfo(textInfos.TextInfo):
@@ -327,9 +328,10 @@ def findOverlayClasses(self,clsList):
 		if UIAClassName=="WpfTextView":
 			clsList.append(WpfTextView)
 		# #5136: Windows 8.x and Windows 10 uses different window class and other attributes for toast notifications.
-		elif ((UIAClassName=="ToastContentHost" and UIAControlType==UIAHandler.UIA_ToolTipControlTypeId) #Windows 8.x
-		or (self.windowClassName=="Windows.UI.Core.CoreWindow" and UIAControlType==UIAHandler.UIA_WindowControlTypeId and self.UIAElement.cachedAutomationId=="NormalToastView")): # Windows 10
-			clsList.append(Toast)
+		elif UIAClassName=="ToastContentHost" and UIAControlType==UIAHandler.UIA_ToolTipControlTypeId: #Windows 8.x
+			clsList.append(Toast_win8)
+		elif self.windowClassName=="Windows.UI.Core.CoreWindow" and UIAControlType==UIAHandler.UIA_WindowControlTypeId and "ToastView" in self.UIAElement.cachedAutomationId: # Windows 10
+			clsList.append(Toast_win10)
 		elif self.UIAElement.cachedFrameworkID in ("InternetExplorer","MicrosoftEdge"):
 			import edge
 			if UIAClassName in ("Internet Explorer_Server","WebView") and self.role==controlTypes.ROLE_PANE:
@@ -972,14 +974,17 @@ def event_stateChange(self):
 class Dialog(Dialog):
 	role=controlTypes.ROLE_DIALOG
 
-class Toast(UIA):
+class Toast_win8(Notification, UIA):
 
-	def event_alert(self):
-		if not config.conf["presentation"]["reportHelpBalloons"]:
-			return
-		speech.speakObject(self,reason=controlTypes.REASON_FOCUS)
-		# TODO: Don't use getBrailleTextForProperties directly.
-		braille.handler.message(braille.getBrailleTextForProperties(name=self.name, role=self.role))
+	event_UIA_toolTipOpened=Notification.event_alert
+
+class Toast_win10(Notification, UIA):
+
+	# #6096: Windows 10 Redstone build 14366 and later does not fire tooltip event when toasts appear.
+	if sys.getwindowsversion().build > 10586:
+		event_UIA_window_windowOpen=Notification.event_alert
+	else:
+		event_UIA_toolTipOpened=Notification.event_alert
 
 #WpfTextView fires name state changes once a second, plus when IUIAutomationTextRange::GetAttributeValue is called.
 #This causes major lags when using this control with Braille in NVDA. (#2759) 
diff --git a/source/NVDAObjects/behaviors.py b/source/NVDAObjects/behaviors.py
--- a/source/NVDAObjects/behaviors.py
+++ b/source/NVDAObjects/behaviors.py
@@ -621,7 +621,7 @@ def event_show(self):
 
 class Notification(NVDAObject):
 	"""Informs the user of non-critical information that does not require immediate action.
-	This is primarily for notifications displayed in the system notification area.
+	This is primarily for notifications displayed in the system notification area, and for Windows 8 and later, toasts.
 	The object should fire a alert or show event when the user should be notified.
 	"""
 
diff --git a/source/_UIAHandler.py b/source/_UIAHandler.py
--- a/source/_UIAHandler.py
+++ b/source/_UIAHandler.py
@@ -119,9 +119,10 @@
 	UIA_SelectionItem_ElementRemovedFromSelectionEventId:"stateChange",
 	#UIA_MenuModeEndEventId:"menuModeEnd",
 	#UIA_Text_TextSelectionChangedEventId:"caret",
-	UIA_ToolTipOpenedEventId:"alert",
+	UIA_ToolTipOpenedEventId:"UIA_toolTipOpened",
 	#UIA_AsyncContentLoadedEventId:"documentLoadComplete",
 	#UIA_ToolTipClosedEventId:"hide",
+	UIA_Window_WindowOpenedEventId:"UIA_window_windowOpen",
 }
 
 class UIAHandler(COMObject):


Test patch: