-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add InternalRaiseAutomationNotification in WmDateChanged of the MonthCalendar #13707
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
base: main
Are you sure you want to change the base?
Add InternalRaiseAutomationNotification in WmDateChanged of the MonthCalendar #13707
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #13707 +/- ##
===================================================
+ Coverage 76.82947% 77.11751% +0.28803%
===================================================
Files 3257 3274 +17
Lines 642592 645061 +2469
Branches 47565 47702 +137
===================================================
+ Hits 493700 497455 +3755
+ Misses 145232 143943 -1289
- Partials 3660 3663 +3
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR enhances accessibility support for the MonthCalendar control by adding automation notifications when the selected date changes. The change ensures that screen readers like NVDA can properly announce date changes when users navigate the calendar with keyboard inputs.
Key changes:
- Adds automation notification calls in the WmDateChanged method to notify accessibility tools when calendar focus/selection changes
- Introduces a new app context switch to control this behavior
- Uses both legacy MSAA events and modern UIA notifications for broader compatibility
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
MonthCalendar.cs | Adds automation notification logic in WmDateChanged method with app context switch guard |
LocalAppContextSwitches.cs | Defines new app context switch for enabling MonthCalendar automation notifications |
Comments suppressed due to low confidence (1)
src/System.Windows.Forms.Primitives/src/System/LocalAppContextSwitches/LocalAppContextSwitches.cs:29
- The switch name contains 'RichTextBox' but should reference 'MonthCalendar' since this switch is for MonthCalendar automation notifications. It should be 'System.Windows.Forms.MonthCalendar.EnableMonthCalendarAutomationNotification'.
internal const string EnableMonthCalendarAutomationNotificationSwitchName = "System.Windows.Forms.RichTextBox.EnableMonthCalendarAutomationNotification";
...ystem.Windows.Forms.Primitives/src/System/LocalAppContextSwitches/LocalAppContextSwitches.cs
Outdated
Show resolved
Hide resolved
…Switches/LocalAppContextSwitches.cs Co-authored-by: Copilot <[email protected]>
fa2437f
to
728b2c6
Compare
@merriemcgaw Regarding this PR, I need to correct a mistake Turning on the existing switch I updated the PR, adding MSAA events to MonthCalendar while retaining the original UIA events, so that both tools can read cell content normally, please review again |
@merriemcgaw please review this PR again. The only issue currently is that the I can disable So, can the mouse issue here be ignored? |
@KlausLoeffelmann getting this one on your radar for review. |
OnDateChanged(new DateRangeEventArgs(start, end)); | ||
} | ||
|
||
private void NotifyWinEvent(AccessibleEvents accessibleEvent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this throw potentially and with that regress exiting scenarios?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original method AccessibilityNotifyClients(...)
internally checks the AppContextSwitches.NoClientNotifications
flag. If this flag is set to true, it calls NotifyWinEvent(...);
otherwise, it does nothing:
winforms/src/System.Windows.Forms/System/Windows/Forms/Control.cs
Lines 4227 to 4233 in 5a9fb88
protected void AccessibilityNotifyClients(AccessibleEvents accEvent, int objectID, int childID) | |
{ | |
if (IsHandleCreated && AppContextSwitches.NoClientNotifications) | |
{ | |
PInvoke.NotifyWinEvent((uint)accEvent, this, objectID, childID + 1); | |
} | |
} |
Since AppContextSwitches.NoClientNotifications
defaults to false, the system event is never raised, which causes screen readers like NVDA to miss updates from MonthCalendar
.
Unfortunately, this method is protected and not overridable, and enabling the switch globally would affect all controls—not just MonthCalendar
—which could introduce regressions elsewhere.
To resolve this, I replaced the call with a direct invocation of NotifyWinEvent(...)
, and added a handle check to ensure safety:
private void NotifyWinEvent(AccessibleEvents accessibleEvent)
{
try
{
if (this.IsHandleCreated)
{
PInvoke.NotifyWinEvent(
(uint)accessibleEvent,
this,
(int)OBJECT_IDENTIFIER.OBJID_CLIENT,
(int)PInvoke.CHILDID_SELF
);
}
}
catch (Exception ex)
{
Debug.WriteLine($"NotifyWinEvent failed: {ex.Message}");
}
}
This ensures that NVDA receives the necessary accessibility events without relying on global switches, and avoids potential exceptions by validating the control’s handle.
Fixes #13657
Proposed changes
WmDateChanged
of theMonthCalendar
so that the MonthCalendar remains in the Focused state when switching dates with the keyboardCustomer Impact
Regression?
Risk
Screenshots
Before
NVDA cannot announce the correct information for the calendar date
Bug_13657_A11y_WinForms.NETRuntime_CommonControl2_InfoAndRelationships.mp4
After
The calendar date can be announced and the
MonthCalendar
can be focused with NVDANVDA-2024.4.2.mp4
Test methodology
Test environment(s)
Microsoft Reviewers: Open in CodeFlow