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

Make UIA in MS Word optional again, through an Advanced Settings category #9200

Merged
merged 7 commits into from
Jan 31, 2019
25 changes: 4 additions & 21 deletions source/_UIAHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@
"FoxitDocWnd",
]

Version=namedtuple('Version',('major','minor','build'))
# The minimum version of Microsoft Word where we can trust that UI Automation is complete enough to use
minMSWordUIAVersion=Version(16,0,9000)

# #8405: used to detect UIA dialogs prior to Windows 10 RS5.
UIADialogClassNames=[
"#32770",
Expand Down Expand Up @@ -366,9 +362,10 @@ def _isUIAWindowHelper(self,hwnd):
res=windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
if res:
# the window does support UIA natively, but
# MS Word documents now have a very usable UI Automation implementation. However,
# MS Word documents now have a fairly usable UI Automation implementation. However,
# Builds of MS Office 2016 before build 9000 or so had bugs which we cannot work around.
# Therefore refuse to use UIA for builds earlier than this, if we can inject in-process.
# And even current builds of Office 2016 are still missing enough info from UIA that it is still impossible to switch to UIA completely.
# Therefore, if we can inject in-process, refuse to use UIA and instead fall back to the MS Word object model.
if (
# An MS Word document window
windowClass=="_WwG"
Expand All @@ -377,21 +374,7 @@ def _isUIAWindowHelper(self,hwnd):
# Allow the user to explisitly force UIA support for MS Word documents no matter the Office version
and not config.conf['UIA']['useInMSWordWhenAvailable']
):
# We can only safely check the version of known Office apps using the Word document control, as we know their versioning scheme.
# But if the Word Document control is used in other unknown apps we should just use UIA if it has been implemented.
if appModule.appName not in ('outlook','winword','excel'):
log.debugWarning("Unknown application using MS Word document control: %s"%appModule.appName)
return True
try:
versionMajor,versionMinor,versionBuild,versionPatch=[int(x) for x in appModule.productVersion.split('.')]
except Exception as e:
log.error("Error parsing version information %s, %s"%(appModule.productVersion,e))
return True
if (
versionMajor<minMSWordUIAVersion.major
or versionMajor==minMSWordUIAVersion.major and versionMinor==minMSWordUIAVersion.minor and versionBuild<minMSWordUIAVersion.build
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should leave in place checks that exclude versions that we know will not work. Though this should be reflected in the user guide; "This setting will not enable UIA in MS Word versions below 16.0.9000"

):
return False
return False
return bool(res)

def isUIAWindow(self,hwnd):
Expand Down
65 changes: 65 additions & 0 deletions source/gui/settingsDialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,69 @@ def onSave(self):
lang = self.languageCodes[self.languageChoice.Selection]
config.conf["uwpOcr"]["language"] = lang

class AdvancedPanel(SettingsPanel):
# Translators: This is the label for the Advanced settings panel.
title = _("Advanced")

def makeSettings(self, settingsSizer):
sHelper = guiHelper.BoxSizerHelper(self, sizer=settingsSizer)

# Translators: This is a label appearing on the Advanced settings panel.
panelText =_("Warning! The following settings are for advanced users. Changing them may cause NVDA to function incorrectly. Please only change these if you know what you are doing or have been specifically instructed by NVDA developers.")
sHelper.addItem(wx.StaticText(self, label=panelText))

# Translators: This is the label for a group of Advanced options in the
# Advanced settings panel
groupText = _("Microsoft UI Automation")
UIAGroup = guiHelper.BoxSizerHelper(self, sizer=wx.StaticBoxSizer(wx.StaticBox(self, label=groupText), wx.VERTICAL))
sHelper.addItem(UIAGroup)

# Translators: This is the label for a checkbox in the
# Advanced settings panel.
label = _("Use UI Automation to access Microsoft &Word document controls when available")
self.UIAInMSWordCheckBox=UIAGroup.addItem(wx.CheckBox(self, label=label))
self.UIAInMSWordCheckBox.SetValue(config.conf["UIA"]["useInMSWordWhenAvailable"])

# Translators: This is the label for a group of Advanced options in the
# Advanced settings panel
groupText = _("Editable Text")
editableTextGroup = guiHelper.BoxSizerHelper(self, sizer=wx.StaticBoxSizer(wx.StaticBox(self, label=groupText), wx.VERTICAL))
sHelper.addItem(editableTextGroup)

# Translators: This is the label for a numeric control in the
# Advanced settings panel.
label = _("Caret movement timeout (in ms)")
self.caretMoveTimeoutSpinControl=editableTextGroup.addLabeledControl(label,nvdaControls.SelectOnFocusSpinCtrl,
min=0, max=2000,
initial=config.conf["editableText"]["caretMoveTimeoutMs"]
)

# Translators: This is the label for a group of Advanced options in the
# Advanced settings panel
groupText = _("Debug logging")
debugLogGroup = guiHelper.BoxSizerHelper(self, sizer=wx.StaticBoxSizer(wx.StaticBox(self, label=groupText), wx.VERTICAL))
sHelper.addItem(debugLogGroup)

self.logCategories=[
"hwIo",
"audioDucking",
"gui",
"louis",
"timeSinceInput",
]
# Translators: This is the label for a list in the
# Advanced settings panel
logCategoriesLabel=_("Enabled logging categories")
self.logCategoriesList=debugLogGroup.addLabeledControl(logCategoriesLabel, nvdaControls.CustomCheckListBox, choices=self.logCategories)
self.logCategoriesList.CheckedItems=[index for index,x in enumerate(self.logCategories) if config.conf['debugLog'][x]]
self.logCategoriesList.Select(0)

def onSave(self):
config.conf["UIA"]["useInMSWordWhenAvailable"]=self.UIAInMSWordCheckBox.IsChecked()
config.conf["editableText"]["caretMoveTimeoutMs"]=self.caretMoveTimeoutSpinControl.GetValue()
for index,key in enumerate(self.logCategories):
config.conf['debugLog'][key]=self.logCategoriesList.IsChecked(index)

class DictionaryEntryDialog(wx.Dialog):
TYPE_LABELS = {
# Translators: This is a label for an Entry Type radio button in add dictionary entry dialog.
Expand Down Expand Up @@ -2481,6 +2544,8 @@ class NVDASettingsDialog(MultiCategorySettingsDialog):
categoryClasses.append(TouchInteractionPanel)
if winVersion.isUwpOcrAvailable():
categoryClasses.append(UwpOcrPanel)
# And finally the Advanced panel which should always be last.
categoryClasses.append(AdvancedPanel)

def makeSettings(self, settingsSizer):
# Ensure that after the settings dialog is created the name is set correctly
Expand Down
20 changes: 20 additions & 0 deletions user_docs/en/userGuide.t2t
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,26 @@ This category contains the following options:
==== Recognition language ====[Win10OcrSettingsRecognitionLanguage]
This combo box allows you to choose the language to be used for text recognition.

+++ Advanced Settings +++
Warning! The settings in this category are for advanced users and may cause NVDA to not function correctly if configured in the wrong way.
Only make changes to these settings if you are sure you know what you are doing or if you have been specifically instructed to by an NVDA developer.

==== Use UI automation to access Microsoft Word document controls when available ====
When this option is enabled, NVDA will try to use the Microsoft UI Automation accessibility api in order to fetch information from Microsoft Word document controls.
this includes in Microsoft Word itself, and also the Microsoft Outlook message viewer and composer.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Doesn't start with a capital T

Suggested change
this includes in Microsoft Word itself, and also the Microsoft Outlook message viewer and composer.
This includes documents in Microsoft Word itself, and also the Microsoft Outlook message viewer and composer.

For the most recent versions of Microsoft Office 2016/365 running on windows 10, UI Automation support is complete enough to provide access to Microsoft Word documents almost on par with NvDA's existing Microsoft Word support, with the added advantage that responsiveness is majorly increased.
Copy link
Collaborator

Choose a reason for hiding this comment

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

What do you mean with "on par"? I assume it's a typo? Also, note the lower case v in NvDA's

Copy link
Contributor

Choose a reason for hiding this comment

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

@LeonarddeR "on par" is used in golf, and at least quite commonly in Australia, apparently comes from Latin to mean equal to. As a suggestion, the phrase "feature parity" might be preferable.

However, There may be some information which is either not exposed, or exposed incorrectly in some versions of Microsoft Office, which means this UI automation support cannot always be relied upon.
We still do not recommend that the majority of users turn this on by default, though we do welcome users of Office 2016/365 to test this feature and provide feedback.

==== Caret move timeout (in MS) ====
This option allows you to configure the number of mili seconds NVDA will wait for the caret (insertion point) to move in editable text controls.
If you find that NVDA seems to be incorrectly tracking the caret E.g. it seems to be always one character behind or is repeating lines, then you may wish to try increasing this value.

==== Debug logging categories ====
The checkboxes in this group allow you to enable specific categories of debug messages in NVDA's log.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is now a list instead of a group, though the list has its own group

Logging these messages can resort in decreased performance and large log files.
Only turn one of these on if specifically instructed to by an NVDA developer e.g. when debugging why a braille display driver is not functioning correctly.

++ miscellaneous Settings ++[MiscSettings]
Besides the [NVDA Settings #NVDASettings] dialog, The Preferences sub-menu of the NVDA Menu contains several other items which are outlined below.

Expand Down