diff --git a/miscDeps b/miscDeps index 3efa98d052e..8987b2cfd5a 160000 --- a/miscDeps +++ b/miscDeps @@ -1 +1 @@ -Subproject commit 3efa98d052ef196db4d94303fb415525c890cb37 +Subproject commit 8987b2cfd5a86703053654741df7a160af585e27 diff --git a/source/NVDAObjects/UIA/__init__.py b/source/NVDAObjects/UIA/__init__.py index 6d7af1d71e7..72aa013655e 100644 --- a/source/NVDAObjects/UIA/__init__.py +++ b/source/NVDAObjects/UIA/__init__.py @@ -4,6 +4,8 @@ #See the file COPYING for more details. #Copyright (C) 2009-2017 NV Access Limited, Joseph Lee, Mohammad Suliman +"""Support for UI Automation (UIA) controls.""" + from ctypes import byref from ctypes.wintypes import POINT, RECT from comtypes import COMError @@ -25,7 +27,7 @@ from UIAUtils import * from NVDAObjects.window import Window from NVDAObjects import NVDAObjectTextInfo, InvalidNVDAObject -from NVDAObjects.behaviors import ProgressBar, EditableTextWithoutAutoSelectDetection, Dialog, Notification +from NVDAObjects.behaviors import ProgressBar, EditableTextWithoutAutoSelectDetection, Dialog, Notification, EditableTextWithSuggestions import braille class UIATextInfo(textInfos.TextInfo): @@ -738,9 +740,26 @@ def findOverlayClasses(self,clsList): pass elif UIAControlType==UIAHandler.UIA_ListItemControlTypeId: clsList.append(ListItem) - # #5942: In recent Windows 10 Redstone builds (14332 and later), Microsoft rewrote various dialog code including that of User Account Control. + # #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"): 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. + if self.UIAElement.cachedAutomationID in ("SearchTextBox", "TextBox", "addressEditBox"): + clsList.append(SearchField) + try: + # Nested block here in order to catch value error and variable binding error when attempting to access automation ID for invalid elements. + try: + # #6241: Raw UIA base tree walker is better than simply looking at self.parent when locating suggestion list items. + parentElement=UIAHandler.handler.baseTreeWalker.GetParentElementBuildCache(self.UIAElement,UIAHandler.handler.baseCacheRequest) + # Sometimes, fetching parent (list control) via base tree walker fails, especially when dealing with suggestions in Windows10 Start menu. + # Oddly, we need to take care of context menu for Start search suggestions as well. + if parentElement.cachedAutomationId.lower() in ("suggestionslist", "contextmenu"): + clsList.append(SuggestionListItem) + except COMError: + pass + except ValueError: + pass clsList.append(UIA) @@ -1418,7 +1437,7 @@ class Toast_win8(Notification, UIA): class Toast_win10(Notification, UIA): - # #6096: Windows 10 Redstone build 14366 and later does not fire tooltip event when toasts appear. + # #6096: Windows 10 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: @@ -1435,3 +1454,29 @@ def event_nameChange(self): def event_stateChange(self): return +class SearchField(EditableTextWithSuggestions, UIA): + """An edit field that presents suggestions based on a search term. + """ + + def event_UIA_controllerFor(self): + # Only useful if suggestions appear and disappear. + if self == api.getFocusObject() and len(self.controllerFor)>0: + self.event_suggestionsOpened() + else: + self.event_suggestionsClosed() + + +class SuggestionListItem(UIA): + """Recent Windows releases use suggestions lists for various things, including Start menu suggestions, Store, Settings app and so on. + """ + + role=controlTypes.ROLE_LISTITEM + + def event_UIA_elementSelected(self): + focusControllerFor=api.getFocusObject().controllerFor + if len(focusControllerFor)>0 and focusControllerFor[0].appModule is self.appModule and self.name: + speech.cancelSpeech() + api.setNavigatorObject(self) + self.reportFocus() + # Display results as flash messages. + braille.handler.message(braille.getBrailleTextForProperties(name=self.name, role=self.role, positionInfo=self.positionInfo)) diff --git a/source/NVDAObjects/behaviors.py b/source/NVDAObjects/behaviors.py index 78532eb0adc..52e4e5a6f05 100755 --- a/source/NVDAObjects/behaviors.py +++ b/source/NVDAObjects/behaviors.py @@ -3,9 +3,10 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2006-2013 NV Access Limited, Peter Vágner +#Copyright (C) 2006-2017 NV Access Limited, Peter Vágner, Joseph Lee """Mix-in classes which provide common behaviour for particular types of controls across different APIs. +Behaviors described in this mix-in include providing table navigation commands for certain table rows, terminal input and output support, announcing notifications and suggestion items and so on. """ import os @@ -26,6 +27,7 @@ import api import ui import braille +import nvwave class ProgressBar(NVDAObject): @@ -633,3 +635,28 @@ def event_alert(self): braille.handler.message(braille.getBrailleTextForProperties(name=self.name, role=self.role)) event_show = event_alert + +class EditableTextWithSuggestions(NVDAObject): + """Allows NvDA to announce appearance/disappearance of suggestions as text is entered. + This is used in various places, including Windows 10 search edit fields and others. + Subclasses should provide L{event_suggestionsOpened} and can optionally override L{event_suggestionsClosed}. + These events are fired when suggestions appear and disappear, respectively. + """ + + def event_suggestionsOpened(self): + """Called when suggestions appear when text is entered e.g. search suggestions. + Subclasses should provide custom implementations if possible. + By default NVDA will announce appearance of suggestions using speech, braille or a sound will be played. + """ + # Translators: Announced in braille when suggestions appear when search term is entered in various search fields such as Start search box in Windows 10. + braille.handler.message(_("Suggestions")) + if config.conf["presentation"]["reportAutoSuggestionsWithSound"]: + nvwave.playWaveFile(r"waves\suggestionsOpened.wav") + + def event_suggestionsClosed(self): + """Called when suggestions list or container is closed. + Subclasses should provide custom implementations if possible. + By default NVDA will announce this via speech, braille or via a sound. + """ + if config.conf["presentation"]["reportAutoSuggestionsWithSound"]: + nvwave.playWaveFile(r"waves\suggestionsClosed.wav") diff --git a/source/UIAHandler.py b/source/UIAHandler.py index 32844a6cae7..83b7fb734b0 100644 --- a/source/UIAHandler.py +++ b/source/UIAHandler.py @@ -1,3 +1,9 @@ +#UIAHandler.py +#A part of NonVisual Desktop Access (NVDA) +#Copyright (C) 2008-2016 NV Access Limited +#This file is covered by the GNU General Public License. +#See the file COPYING for more details. + import winVersion from comtypes import COMError import config diff --git a/source/_UIAHandler.py b/source/_UIAHandler.py index 9dd7a190f41..101f840d69a 100644 --- a/source/_UIAHandler.py +++ b/source/_UIAHandler.py @@ -1,3 +1,9 @@ +#_UIAHandler.py +#A part of NonVisual Desktop Access (NVDA) +#Copyright (C) 2011-2017 NV Access Limited, Joseph Lee +#This file is covered by the GNU General Public License. +#See the file COPYING for more details. + from ctypes import * from ctypes.wintypes import * import comtypes.client @@ -117,6 +123,7 @@ UIA_IsEnabledPropertyId:"stateChange", UIA_ValueValuePropertyId:"valueChange", UIA_RangeValueValuePropertyId:"valueChange", + UIA_ControllerForPropertyId:"UIA_controllerFor", } UIAEventIdsToNVDAEventNames={ diff --git a/source/appModules/searchui.py b/source/appModules/searchui.py index 159ccf3f066..383f0f4dfa5 100644 --- a/source/appModules/searchui.py +++ b/source/appModules/searchui.py @@ -1,34 +1,15 @@ #A part of NonVisual Desktop Access (NVDA) -#Copyright (C) 2015 NV Access Limited +#Copyright (C) 2015-2016 NV Access Limited #This file is covered by the GNU General Public License. #See the file COPYING for more details. import appModuleHandler -import controlTypes -import api -import speech -from NVDAObjects.UIA import UIA -from NVDAObjects.UIA.edge import EdgeList from NVDAObjects.IAccessible import IAccessible, ContentGenericClient -# Windows 10 Search UI suggestion list item -class SuggestionListItem(UIA): - - role=controlTypes.ROLE_LISTITEM - - def event_UIA_elementSelected(self): - focusControllerFor=api.getFocusObject().controllerFor - if len(focusControllerFor)>0 and focusControllerFor[0].appModule is self.appModule and self.name: - speech.cancelSpeech() - api.setNavigatorObject(self) - self.reportFocus() - class AppModule(appModuleHandler.AppModule): def chooseNVDAObjectOverlayClasses(self,obj,clsList): - if isinstance(obj,UIA) and isinstance(obj.parent,EdgeList): - clsList.insert(0,SuggestionListItem) - elif isinstance(obj,IAccessible): + if isinstance(obj,IAccessible): try: # #5288: Never use ContentGenericClient, as this uses displayModel # which will freeze if the process is suspended. diff --git a/source/config/configSpec.py b/source/config/configSpec.py index 89cc9638272..8acc7f308c7 100644 --- a/source/config/configSpec.py +++ b/source/config/configSpec.py @@ -76,6 +76,7 @@ reportHelpBalloons = boolean(default=true) reportObjectDescriptions = boolean(default=True) reportDynamicContentChanges = boolean(default=True) + reportAutoSuggestionsWithSound = boolean(default=True) [[progressBarUpdates]] reportBackgroundProgressBars = boolean(default=false) #output modes are beep, speak, both, or off diff --git a/source/gui/settingsDialogs.py b/source/gui/settingsDialogs.py index 579b8fd0878..1c291b0fb5e 100644 --- a/source/gui/settingsDialogs.py +++ b/source/gui/settingsDialogs.py @@ -949,6 +949,12 @@ def makeSettings(self, settingsSizer): self.dynamicContentCheckBox=sHelper.addItem(wx.CheckBox(self,label=dynamicContentText)) self.dynamicContentCheckBox.SetValue(config.conf["presentation"]["reportDynamicContentChanges"]) + # Translators: This is the label for a combobox in the + # object presentation settings dialog. + autoSuggestionsLabelText = _("Play a sound when &auto-suggestions appear") + self.autoSuggestionSoundsCheckBox=sHelper.addItem(wx.CheckBox(self,label=autoSuggestionsLabelText)) + self.autoSuggestionSoundsCheckBox.SetValue(config.conf["presentation"]["reportAutoSuggestionsWithSound"]) + def postInit(self): self.tooltipCheckBox.SetFocus() @@ -962,6 +968,7 @@ def onOk(self,evt): config.conf["presentation"]["progressBarUpdates"]["progressBarOutputMode"]=self.progressLabels[self.progressList.GetSelection()][0] config.conf["presentation"]["progressBarUpdates"]["reportBackgroundProgressBars"]=self.reportBackgroundProgressBarsCheckBox.IsChecked() config.conf["presentation"]["reportDynamicContentChanges"]=self.dynamicContentCheckBox.IsChecked() + config.conf["presentation"]["reportAutoSuggestionsWithSound"]=self.autoSuggestionSoundsCheckBox.IsChecked() super(ObjectPresentationDialog, self).onOk(evt) class BrowseModeDialog(SettingsDialog): diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t index bc568d13946..aa798210bb2 100644 --- a/user_docs/en/userGuide.t2t +++ b/user_docs/en/userGuide.t2t @@ -1165,6 +1165,13 @@ Key: NVDA+5 Toggles the announcement of new content in particular objects such as terminals and the history control in chat programs. +==== Play a sound when auto-suggestions appear ==== +Toggles announcement of appearance of auto-suggestions, and if enabled, NVDA will play a sound to indicate this. +Auto-suggestions are lists of suggested entries based on text entered into certain edit fields and documents. +For example, when you enter text into the search box in Start menu in Windows Vista and later, Windows displays a list of suggestions based on what you typed. +For some edit fields such as search fields in various Windows 10 apps, NVDA can notify you that a list of suggestions has appeared when you type text. +The auto-suggestions list will close once you move away from the edit field, and for some fields, NVDA can notify you of this when this happens. + +++ Input Composition Settings +++ The Input Composition Settings dialog can be found under the Preferences menu. This dialog allows you to control how NVDA reports the input of Asian characters, such as with IME or Text Service input methods.