diff --git a/source/NVDAObjects/UIA/__init__.py b/source/NVDAObjects/UIA/__init__.py index 842562f6e9e..c71718816a4 100644 --- a/source/NVDAObjects/UIA/__init__.py +++ b/source/NVDAObjects/UIA/__init__.py @@ -1028,8 +1028,6 @@ def findOverlayClasses(self, clsList): # NOQA: C901 ): # Bounces focus from a netUI dead placeholder menu item when no item is selected up to the menu itself. clsList.append(PlaceholderNetUITWMenuItem) - elif UIAClassName == "WpfTextView": - clsList.append(WpfTextView) elif ( UIAClassName == "ListViewItem" and self.UIAElement.cachedFrameworkID == "WPF" @@ -1261,6 +1259,8 @@ def findOverlayClasses(self, clsList): # NOQA: C901 if self.UIAFrameworkId == 'XAML': # This UIA element is being exposed by the XAML framework. clsList.append(XamlEditableText) + elif UIAClassName == "WpfTextView": + clsList.append(WpfTextView) if UIAHandler.autoSelectDetectionAvailable: clsList.append(EditableTextWithAutoSelectDetection) else: @@ -2213,17 +2213,16 @@ def event_UIA_dropTargetEffect(self): ui.message(dropTargetEffect) -class XamlEditableText(EditableTextBase, UIA): - """ a UIA element with editable text exposed by the XAML framework.""" +class InaccurateTextChangeEventEmittingEditableText(EditableTextBase, UIA): - # XAML fires UIA textSelectionChange events before the caret position change is reflected + # XAML and WPF fire UIA textSelectionChange events before the caret position change is reflected # in the related UIA text pattern. - # This means that, apart from deleting text, NVDA cannot rely on textSelectionChange (caret) events in XAML - # to detect if the caret has moved, as it occurs too early. + # This means that, apart from deleting text, NVDA cannot rely on textSelectionChange (caret) events + # in XAML or WPF to detect if the caret has moved, as it occurs too early. caretMovementDetectionUsesEvents = False def _backspaceScriptHelper(self, unit: str, gesture: inputCore.InputGesture): - """As UIA text range objects from XAML don't mutate with backspace, + """As UIA text range objects from XAML or WPF don't mutate with backspace, comparing a text range copied from before backspace with a text range fetched after backspace isn't reliable, as the ranges compare equal. Therefore, we must always rely on events for caret change detection in this case. @@ -2235,6 +2234,11 @@ def _backspaceScriptHelper(self, unit: str, gesture: inputCore.InputGesture): self.caretMovementDetectionUsesEvents = False +class XamlEditableText(InaccurateTextChangeEventEmittingEditableText): + """An UIA element with editable text exposed by the XAML framework.""" + ... + + class TreeviewItem(UIA): def _get_value(self): @@ -2400,10 +2404,12 @@ class ToolTip(ToolTip, UIA): event_UIA_toolTipOpened=ToolTip.event_show -#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) -#For now just ignore the events. -class WpfTextView(UIA): +class WpfTextView(InaccurateTextChangeEventEmittingEditableText): + """WpfTextView fires name state changes once a second, + plus when IUIAutomationTextRange::GetAttributeValue is called. + This causes major lag when using this control with Braille in NVDA. (#2759) + For now just ignore the events. + """ def event_nameChange(self): return @@ -2411,6 +2417,7 @@ def event_nameChange(self): def event_stateChange(self): return + class SearchField(EditableTextWithSuggestions, UIA): """An edit field that presents suggestions based on a search term. This is now an empty class as functionality has been moved to the base EditableText behaviour.