@@ -150,6 +150,11 @@ - (void)loadAOTData:(NSString*)assetsDir;
150
150
*/
151
151
- (void )setUpPlatformViewChannel ;
152
152
153
+ /* *
154
+ * Creates an accessibility channel and sets up the message handler.
155
+ */
156
+ - (void )setUpAccessibilityChannel ;
157
+
153
158
/* *
154
159
* Handles messages received from the Flutter engine on the _*Channel channels.
155
160
*/
@@ -366,6 +371,9 @@ @implementation FlutterEngine {
366
371
// A message channel for sending user settings to the flutter engine.
367
372
FlutterBasicMessageChannel* _settingsChannel;
368
373
374
+ // A message channel for accessibility.
375
+ FlutterBasicMessageChannel* _accessibilityChannel;
376
+
369
377
// A method channel for miscellaneous platform functionality.
370
378
FlutterMethodChannel* _platformChannel;
371
379
@@ -409,6 +417,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix
409
417
410
418
_platformViewController = [[FlutterPlatformViewController alloc ] init ];
411
419
[self setUpPlatformViewChannel ];
420
+ [self setUpAccessibilityChannel ];
412
421
[self setUpNotificationCenterListeners ];
413
422
414
423
return self;
@@ -923,6 +932,16 @@ - (void)setUpPlatformViewChannel {
923
932
}];
924
933
}
925
934
935
+ - (void )setUpAccessibilityChannel {
936
+ _accessibilityChannel = [FlutterBasicMessageChannel
937
+ messageChannelWithName: @" flutter/accessibility"
938
+ binaryMessenger: self .binaryMessenger
939
+ codec: [FlutterStandardMessageCodec sharedInstance ]];
940
+ __weak FlutterEngine* weakSelf = self;
941
+ [_accessibilityChannel setMessageHandler: ^(id message, FlutterReply reply) {
942
+ [weakSelf handleAccessibilityEvent: message];
943
+ }];
944
+ }
926
945
- (void )setUpNotificationCenterListeners {
927
946
NSNotificationCenter * center = [NSNotificationCenter defaultCenter ];
928
947
// macOS fires this private message when VoiceOver turns on or off.
@@ -967,7 +986,30 @@ - (void)onAccessibilityStatusChanged:(NSNotification*)notification {
967
986
968
987
self.semanticsEnabled = enabled;
969
988
}
989
+ - (void )handleAccessibilityEvent : (NSDictionary <NSString*, id>*)annotatedEvent {
990
+ NSString * type = annotatedEvent[@" type" ];
991
+ if ([type isEqualToString: @" announce" ]) {
992
+ NSString * message = annotatedEvent[@" data" ][@" message" ];
993
+ NSNumber * assertiveness = annotatedEvent[@" data" ][@" assertiveness" ];
994
+ if (message == nil ) {
995
+ return ;
996
+ }
970
997
998
+ NSAccessibilityPriorityLevel priority = [assertiveness isEqualToNumber: @1 ]
999
+ ? NSAccessibilityPriorityHigh
1000
+ : NSAccessibilityPriorityMedium;
1001
+
1002
+ [self announceAccessibilityMessage: message withPriority: priority];
1003
+ }
1004
+ }
1005
+
1006
+ - (void )announceAccessibilityMessage : (NSString *)message
1007
+ withPriority : (NSAccessibilityPriorityLevel )priority {
1008
+ NSAccessibilityPostNotificationWithUserInfo (
1009
+ [self viewControllerForId: kFlutterDefaultViewId ].flutterView,
1010
+ NSAccessibilityAnnouncementRequestedNotification ,
1011
+ @{NSAccessibilityAnnouncementKey : message, NSAccessibilityPriorityKey : @(priority)});
1012
+ }
971
1013
- (void )handleMethodCall : (FlutterMethodCall*)call result : (FlutterResult)result {
972
1014
if ([call.method isEqualToString: @" SystemNavigator.pop" ]) {
973
1015
[NSApp terminate: self ];
0 commit comments