Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIA objects: recognize more UIA dialogs via more class names and IsDialog property in Windows 10 Redstone 5 #8473

Merged
merged 10 commits into from Jul 19, 2018
10 changes: 9 additions & 1 deletion source/NVDAObjects/UIA/__init__.py
Expand Up @@ -789,7 +789,15 @@ def findOverlayClasses(self,clsList):
elif UIAControlType==UIAHandler.UIA_ListItemControlTypeId:
clsList.append(ListItem)
# #5942: In Windows 10 build 14332 and later, Microsoft rewrote various dialog code including that of User Account Control.
if self.UIAIsWindowElement and UIAClassName in ("#32770","NUIDialog", "Credential Dialog Xaml Host"):
# #8405: there are more dialogs scattered throughout Windows 10 and various apps.
# Apart from "popup" dialog seen when uninstaling apps and such, they are window elements (popup dialog isn't).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instaling > installing

# Dialog detection is a bit easier on build 17682 and later thanks to IsDialog property.
try:
isDialog = self._getUIACacheablePropertyValue(UIAHandler.UIA_IsDialogPropertyId)
except COMError:
isDialog = False
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of setting this to False, you could consider setting isDialog to the expression in the if clause. like:

isDialog = (self.UIAIsWindowElement and UIAClassName in UIAHandler.UIADialogClassNames) or (not self.UIAIsWindowElement and UIAClassName == "Popup"):

To me, this is a bit more readable. Or are there cases where isDialog returns False, and yet we should treat something as a dialog? In that case, the "not isdialog" check still seems redundant. I think we should always respect isDialog if possible.

if isDialog or (not isDialog and (self.UIAIsWindowElement and UIAClassName in UIAHandler.UIADialogClassNames)
or (not self.UIAIsWindowElement and UIAClassName == "Popup")):
clsList.append(Dialog)
# #6241: Try detecting all possible suggestions containers and search fields scattered throughout Windows 10.
# In Windows 10, allow Start menu search box and Edge's address omnibar to participate in announcing appearance of auto-suggestions.
Expand Down
16 changes: 16 additions & 0 deletions source/_UIAHandler.py
Expand Up @@ -43,6 +43,9 @@
UIA_LocalizedLandmarkTypePropertyId=30158
UIA_LandmarkTypePropertyId=30157

# Specific to Windows 10 (note: remove this once IUIAutomation6 interface support is implemented):
UIA_IsDialogPropertyId = 30174

HorizontalTextAlignment_Left=0
HorizontalTextAlignment_Centered=1
HorizontalTextAlignment_Right=2
Expand Down Expand Up @@ -76,6 +79,19 @@
"ConsoleWindowClass",
]

# #8405: used to detect UIA dialogs prior to Windows 10 RS5.
UIADialogClassNames=[
"#32770",
"NUIDialog",
"Credential Dialog Xaml Host", # UAC dialog in Anniversary Update and later
"Shell_Dialog",
"Shell_Flyout",
"Shell_SystemDialog", # Various dialogs in Windows 10 Settings app
# Chiefly Uninstall app dialog in Windows 10.
# Although it is not listed as a window element, RS5 recognizes this as a proper dialog.
"Popup",
]

NVDAUnitsToUIAUnits={
"character":TextUnit_Character,
"word":TextUnit_Word,
Expand Down