From b37bfd4f6162fa105fec54230d5d78dd5b49490f Mon Sep 17 00:00:00 2001 From: Quin Gillespie Date: Thu, 25 Jun 2026 13:19:59 -0600 Subject: [PATCH] Fix RichTextBox flooding AT channel with entire document on focus Removes the explicit UIA automation notification from OnGotFocus that was sending the full Text of the control to assistive technology on every focus event. For large documents this caused NVDA and JAWS to freeze, and produced a double-announcement (the native MSAA focus event already reads the current line correctly). The pass-through override is kept to satisfy the shipped public API surface. Closes #14671 --- .../Forms/Controls/RichTextBox/RichTextBox.cs | 15 +----------- .../System/Windows/Forms/RichTextBoxTests.cs | 23 ++++++++----------- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/src/System.Windows.Forms/System/Windows/Forms/Controls/RichTextBox/RichTextBox.cs b/src/System.Windows.Forms/System/Windows/Forms/Controls/RichTextBox/RichTextBox.cs index 4a6c7972a34..48b0044159c 100644 --- a/src/System.Windows.Forms/System/Windows/Forms/Controls/RichTextBox/RichTextBox.cs +++ b/src/System.Windows.Forms/System/Windows/Forms/Controls/RichTextBox/RichTextBox.cs @@ -2388,20 +2388,7 @@ protected virtual void OnContentsResized(ContentsResizedEventArgs e) ((ContentsResizedEventHandler?)Events[s_requestSizeEvent])?.Invoke(this, e); } - protected override void OnGotFocus(EventArgs e) - { - base.OnGotFocus(e); - - // Use parent's accessible object because RichTextBox doesn't support UIA Providers, and its - // AccessibilityObject doesn't get created even when assistive tech (e.g. Narrator) is used - if (Parent?.IsAccessibilityObjectCreated == true) - { - Parent.AccessibilityObject.InternalRaiseAutomationNotification( - Automation.AutomationNotificationKind.Other, - Automation.AutomationNotificationProcessing.MostRecent, - Text); - } - } + protected override void OnGotFocus(EventArgs e) => base.OnGotFocus(e); protected override void OnHandleCreated(EventArgs e) { diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RichTextBoxTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RichTextBoxTests.cs index 349b5f21983..662fae62fbf 100644 --- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RichTextBoxTests.cs +++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RichTextBoxTests.cs @@ -10594,26 +10594,21 @@ public void RichTextBox_CheckRichEditWithVersionCanCreateOldVersions() [WinFormsTheory] [NewAndDefaultData] - public void RichTextBox_OnGotFocus_RaisesAutomationNotification_WithText(EventArgs eventArgs) + public void RichTextBox_OnGotFocus_DoesNotRaiseAutomationNotification(EventArgs eventArgs) { + // NVDA and JAWS already announce the focused line via native MSAA on focus; an additional + // UIA automation notification caused the line to be read twice. The correct behaviour is + // to let the native accessibility infrastructure handle the announcement. Mock mockParent = new() { CallBase = true }; Mock mockAccessibleObject = new(MockBehavior.Strict, mockParent.Object); - mockAccessibleObject - .Setup(a => a.InternalRaiseAutomationNotification( - It.IsAny(), - It.IsAny(), - It.IsAny())) - .Returns(true) - .Verifiable(); mockParent.Protected().Setup("CreateAccessibilityInstance") .Returns(mockAccessibleObject.Object); using Control parent = mockParent.Object; - string richTextBoxContent = "RichTextBox"; using SubRichTextBox control = new() { Parent = parent, - Text = richTextBoxContent, + Text = "RichTextBox", }; // Enforce accessible object creation @@ -10622,10 +10617,10 @@ public void RichTextBox_OnGotFocus_RaisesAutomationNotification_WithText(EventAr control.OnGotFocus(eventArgs); mockAccessibleObject.Verify(a => a.InternalRaiseAutomationNotification( - AutomationNotificationKind.Other, - AutomationNotificationProcessing.MostRecent, - richTextBoxContent), - Times.Once); + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Never); } [WinFormsTheory]