[PR #12358] Use UIA notifications for text output #29008

Open
opened 2026-01-31 09:32:12 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/12358

State: closed
Merged: Yes


Summary of the Pull Request

This change makes Windows Terminal raise a RaiseNotificationEvent() (docs) for new text output to the buffer.

This is intended to help Narrator identify what new output appears and reduce the workload of diffing the buffer when a TextChanged event occurs.

Detailed Description of the Pull Request / Additional comments

The flow of the event occurs as follows:

  • Terminal::_WriteBuffer()
    • New text is output to the text buffer. Notify the renderer that we have new text (and what that text is).
  • Renderer::TriggerNewTextNotification()
    • Cycle through all the rendering engines and tell them to notify handle the new text output.
    • None of the rendering engines except UiaEngine has it implemented, so really we're just notifying UIA.
  • UiaEngine::NotifyNewText()
    • Concatenate any new output into a string.
    • When we're done painting, tell the notification system to actually notify of new events occurring and clear any stored output text. That way, we're ready for the next renderer frame.
  • InteractivityAutomationPeer::NotifyNewOutput() --> TermControlAutomationPeer::NotifyNewOutput
    • NOTE: these are split because of the in-proc and out-of-proc separation of the buffer.
    • Actually RaiseNotificationEvent() for the new text output.

Additionally, we had to handle the "local echo" problem: when a key is pressed, the character is said twice (once for the keyboard event, and again for the character being written to the buffer). To accomplish this, we did the following:

  • TermControl:
    • here, we already handle keyboard events, so I added a line saying "if we have an automation peer attached, record the keyboard event in the automation peer".
  • TermControlAutomationPeer:
    • just before the notification is dispatched, check if the string of recent keyboard events match the beginning of the string of new output. If that's the case, we can assume that the common prefix was the "local echo".

This is a fairly naive heuristic, but it's been working.

Closes the following ADO bugs:

Test cases

  • Base case: "echo hello"
  • Partial line change
  • Scrolling (should be unaffected)
  • Large output
  • "local echo": keyboard events read input character twice
**Original Pull Request:** https://github.com/microsoft/terminal/pull/12358 **State:** closed **Merged:** Yes --- ## Summary of the Pull Request This change makes Windows Terminal raise a `RaiseNotificationEvent()` ([docs](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.peers.automationpeer.raisenotificationevent?view=winrt-22000)) for new text output to the buffer. This is intended to help Narrator identify what new output appears and reduce the workload of diffing the buffer when a `TextChanged` event occurs. ## Detailed Description of the Pull Request / Additional comments The flow of the event occurs as follows: - `Terminal::_WriteBuffer()` - New text is output to the text buffer. Notify the renderer that we have new text (and what that text is). - `Renderer::TriggerNewTextNotification()` - Cycle through all the rendering engines and tell them to notify handle the new text output. - None of the rendering engines _except_ `UiaEngine` has it implemented, so really we're just notifying UIA. - `UiaEngine::NotifyNewText()` - Concatenate any new output into a string. - When we're done painting, tell the notification system to actually notify of new events occurring and clear any stored output text. That way, we're ready for the next renderer frame. - `InteractivityAutomationPeer::NotifyNewOutput()` --> `TermControlAutomationPeer::NotifyNewOutput` - NOTE: these are split because of the in-proc and out-of-proc separation of the buffer. - Actually `RaiseNotificationEvent()` for the new text output. Additionally, we had to handle the "local echo" problem: when a key is pressed, the character is said twice (once for the keyboard event, and again for the character being written to the buffer). To accomplish this, we did the following: - `TermControl`: - here, we already handle keyboard events, so I added a line saying "if we have an automation peer attached, record the keyboard event in the automation peer". - `TermControlAutomationPeer`: - just before the notification is dispatched, check if the string of recent keyboard events match the beginning of the string of new output. If that's the case, we can assume that the common prefix was the "local echo". This is a fairly naive heuristic, but it's been working. Closes the following ADO bugs: - https://dev.azure.com/microsoft/OS/_workitems/edit/36506838 - (Probably) https://dev.azure.com/microsoft/OS/_workitems/edit/38011453 ## Test cases - [x] Base case: "echo hello" - [x] Partial line change - [x] Scrolling (should be unaffected) - [x] Large output - [x] "local echo": keyboard events read input character twice
claunia added the pull-request label 2026-01-31 09:32:12 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#29008