@@ -821,22 +821,11 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
821821    // in range_slider.dart. 
822822    Size  screenSize () =>  MediaQuery .of (context).size;
823823
824-     VoidCallback ?  handleDidGainAccessibilityFocus;
825-     switch  (theme.platform) {
826-       case  TargetPlatform .android: 
827-       case  TargetPlatform .fuchsia: 
828-       case  TargetPlatform .iOS: 
829-       case  TargetPlatform .linux: 
830-       case  TargetPlatform .macOS: 
831-         break ;
832-       case  TargetPlatform .windows: 
833-         handleDidGainAccessibilityFocus =  () {
834-           // Automatically activate the slider when it receives a11y focus. 
835-           if  (! focusNode.hasFocus &&  focusNode.canRequestFocus) {
836-             focusNode.requestFocus ();
837-           }
838-         };
839-         break ;
824+     void  handleDidGainAccessibilityFocus () {
825+       // Automatically activate the slider when it receives a11y focus. 
826+       if  (! focusNode.hasFocus &&  focusNode.canRequestFocus) {
827+         focusNode.requestFocus ();
828+       }
840829    }
841830
842831    final  Map <ShortcutActivator , Intent > shortcutMap;
@@ -857,38 +846,35 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
857846      ?  math.min (MediaQuery .of (context).textScaleFactor, 1.3 )
858847      :  MediaQuery .of (context).textScaleFactor;
859848
860-     return  Semantics (
861-       container:  true ,
862-       slider:  true ,
863-       onDidGainAccessibilityFocus:  handleDidGainAccessibilityFocus,
864-       child:  FocusableActionDetector (
865-         actions:  _actionMap,
866-         shortcuts:  shortcutMap,
867-         focusNode:  focusNode,
868-         autofocus:  widget.autofocus,
869-         enabled:  _enabled,
870-         onShowFocusHighlight:  _handleFocusHighlightChanged,
871-         onShowHoverHighlight:  _handleHoverChanged,
872-         mouseCursor:  effectiveMouseCursor,
873-         child:  CompositedTransformTarget (
874-           link:  _layerLink,
875-           child:  _SliderRenderObjectWidget (
876-             key:  _renderObjectKey,
877-             value:  _convert (widget.value),
878-             secondaryTrackValue:  (widget.secondaryTrackValue !=  null ) ?  _convert (widget.secondaryTrackValue! ) :  null ,
879-             divisions:  widget.divisions,
880-             label:  widget.label,
881-             sliderTheme:  sliderTheme,
882-             textScaleFactor:  textScaleFactor,
883-             screenSize:  screenSize (),
884-             onChanged:  (widget.onChanged !=  null ) &&  (widget.max >  widget.min) ?  _handleChanged :  null ,
885-             onChangeStart:  _handleDragStart,
886-             onChangeEnd:  _handleDragEnd,
887-             state:  this ,
888-             semanticFormatterCallback:  widget.semanticFormatterCallback,
889-             hasFocus:  _focused,
890-             hovering:  _hovering,
891-           ),
849+     return  FocusableActionDetector (
850+       actions:  _actionMap,
851+       shortcuts:  shortcutMap,
852+       focusNode:  focusNode,
853+       autofocus:  widget.autofocus,
854+       enabled:  _enabled,
855+       onShowFocusHighlight:  _handleFocusHighlightChanged,
856+       onShowHoverHighlight:  _handleHoverChanged,
857+       mouseCursor:  effectiveMouseCursor,
858+       includeFocusSemantics:  false ,
859+       child:  CompositedTransformTarget (
860+         link:  _layerLink,
861+         child:  _SliderRenderObjectWidget (
862+           key:  _renderObjectKey,
863+           value:  _convert (widget.value),
864+           secondaryTrackValue:  (widget.secondaryTrackValue !=  null ) ?  _convert (widget.secondaryTrackValue! ) :  null ,
865+           divisions:  widget.divisions,
866+           label:  widget.label,
867+           sliderTheme:  sliderTheme,
868+           textScaleFactor:  textScaleFactor,
869+           screenSize:  screenSize (),
870+           onChanged:  (widget.onChanged !=  null ) &&  (widget.max >  widget.min) ?  _handleChanged :  null ,
871+           onChangeStart:  _handleDragStart,
872+           onChangeEnd:  _handleDragEnd,
873+           state:  this ,
874+           semanticFormatterCallback:  widget.semanticFormatterCallback,
875+           onDidGainAccessibilityFocus:  handleDidGainAccessibilityFocus,
876+           hasFocus:  _focused,
877+           hovering:  _hovering,
892878        ),
893879      ),
894880    );
@@ -949,6 +935,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
949935    required  this .onChangeEnd,
950936    required  this .state,
951937    required  this .semanticFormatterCallback,
938+     required  this .onDidGainAccessibilityFocus,
952939    required  this .hasFocus,
953940    required  this .hovering,
954941  });
@@ -964,6 +951,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
964951  final  ValueChanged <double >?  onChangeStart;
965952  final  ValueChanged <double >?  onChangeEnd;
966953  final  SemanticFormatterCallback ?  semanticFormatterCallback;
954+   final  VoidCallback ?  onDidGainAccessibilityFocus;
967955  final  _SliderState  state;
968956  final  bool  hasFocus;
969957  final  bool  hovering;
@@ -984,6 +972,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
984972      state:  state,
985973      textDirection:  Directionality .of (context),
986974      semanticFormatterCallback:  semanticFormatterCallback,
975+       onDidGainAccessibilityFocus:  onDidGainAccessibilityFocus,
987976      platform:  Theme .of (context).platform,
988977      hasFocus:  hasFocus,
989978      hovering:  hovering,
@@ -1008,6 +997,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
1008997      ..onChangeEnd =  onChangeEnd
1009998      ..textDirection =  Directionality .of (context)
1010999      ..semanticFormatterCallback =  semanticFormatterCallback
1000+       ..onDidGainAccessibilityFocus =  onDidGainAccessibilityFocus
10111001      ..platform =  Theme .of (context).platform
10121002      ..hasFocus =  hasFocus
10131003      ..hovering =  hovering
@@ -1029,6 +1019,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
10291019    required  TargetPlatform  platform,
10301020    required  ValueChanged <double >?  onChanged,
10311021    required  SemanticFormatterCallback ?  semanticFormatterCallback,
1022+     required  this .onDidGainAccessibilityFocus,
10321023    required  this .onChangeStart,
10331024    required  this .onChangeEnd,
10341025    required  _SliderState  state,
@@ -1114,6 +1105,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
11141105  bool  _active =  false ;
11151106  double  _currentDragValue =  0.0 ;
11161107  Rect ?  overlayRect;
1108+   late  Offset  _thumbCenter;
11171109
11181110  // This rect is used in gesture calculations, where the gesture coordinates 
11191111  // are relative to the sliders origin. Therefore, the offset is passed as 
@@ -1259,6 +1251,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
12591251    }
12601252  }
12611253
1254+   VoidCallback ?  onDidGainAccessibilityFocus;
12621255  ValueChanged <double >?  onChangeStart;
12631256  ValueChanged <double >?  onChangeEnd;
12641257
@@ -1582,10 +1575,10 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
15821575      sliderTheme:  _sliderTheme,
15831576      isDiscrete:  isDiscrete,
15841577    );
1585-     final   Offset  thumbCenter  =  Offset (trackRect.left +  visualPosition *  trackRect.width, trackRect.center.dy);
1578+     _thumbCenter  =  Offset (trackRect.left +  visualPosition *  trackRect.width, trackRect.center.dy);
15861579    if  (isInteractive) {
15871580      final  Size  overlaySize =  sliderTheme.overlayShape! .getPreferredSize (isInteractive, false );
1588-       overlayRect =  Rect .fromCircle (center:  thumbCenter , radius:  overlaySize.width /  2.0 );
1581+       overlayRect =  Rect .fromCircle (center:  _thumbCenter , radius:  overlaySize.width /  2.0 );
15891582    }
15901583    final  Offset ?  secondaryOffset =  (secondaryVisualPosition !=  null ) ?  Offset (trackRect.left +  secondaryVisualPosition *  trackRect.width, trackRect.center.dy) :  null ;
15911584
@@ -1596,7 +1589,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
15961589      sliderTheme:  _sliderTheme,
15971590      enableAnimation:  _enableAnimation,
15981591      textDirection:  _textDirection,
1599-       thumbCenter:  thumbCenter ,
1592+       thumbCenter:  _thumbCenter ,
16001593      secondaryOffset:  secondaryOffset,
16011594      isDiscrete:  isDiscrete,
16021595      isEnabled:  isInteractive,
@@ -1605,7 +1598,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
16051598    if  (! _overlayAnimation.isDismissed) {
16061599      _sliderTheme.overlayShape! .paint (
16071600        context,
1608-         thumbCenter ,
1601+         _thumbCenter ,
16091602        activationAnimation:  _overlayAnimation,
16101603        enableAnimation:  _enableAnimation,
16111604        isDiscrete:  isDiscrete,
@@ -1642,7 +1635,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
16421635            sliderTheme:  _sliderTheme,
16431636            enableAnimation:  _enableAnimation,
16441637            textDirection:  _textDirection,
1645-             thumbCenter:  thumbCenter ,
1638+             thumbCenter:  _thumbCenter ,
16461639            isEnabled:  isInteractive,
16471640          );
16481641        }
@@ -1655,7 +1648,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
16551648          if  (attached) {
16561649            _sliderTheme.valueIndicatorShape! .paint (
16571650              context,
1658-               offset +  thumbCenter ,
1651+               offset +  _thumbCenter ,
16591652              activationAnimation:  _valueIndicatorAnimation,
16601653              enableAnimation:  _enableAnimation,
16611654              isDiscrete:  isDiscrete,
@@ -1674,7 +1667,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
16741667
16751668    _sliderTheme.thumbShape! .paint (
16761669      context,
1677-       thumbCenter ,
1670+       _thumbCenter ,
16781671      activationAnimation:  _overlayAnimation,
16791672      enableAnimation:  _enableAnimation,
16801673      isDiscrete:  isDiscrete,
@@ -1688,22 +1681,47 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
16881681    );
16891682  }
16901683
1684+   @override 
1685+   void  assembleSemanticsNode (SemanticsNode  node, SemanticsConfiguration  config, Iterable <SemanticsNode > children) {
1686+     node.rect =  Rect .fromCenter (
1687+       center:  _thumbCenter,
1688+       width:  kMinInteractiveDimension,
1689+       height:  kMinInteractiveDimension,
1690+     );
1691+ 
1692+     node.updateWith (config:  config);
1693+   }
1694+ 
16911695  @override 
16921696  void  describeSemanticsConfiguration (SemanticsConfiguration  config) {
16931697    super .describeSemanticsConfiguration (config);
16941698
16951699    // The Slider widget has its own Focus widget with semantics information, 
1696-     // and we  want that semantics node to collect the semantics information here 
1700+     // and want that semantics node to collect the semantics information here 
16971701    // so that it's all in the same node: otherwise Talkback sees that the node 
16981702    // has focusable children, and it won't focus the Slider's Focus widget 
16991703    // because it thinks the Focus widget's node doesn't have anything to say 
17001704    // (which it doesn't, but this child does). Aggregating the semantic 
17011705    // information into one node means that Talkback will recognize that it has 
17021706    // something to say and focus it when it receives keyboard focus. 
17031707    // (See https://github.com/flutter/flutter/issues/57038 for context). 
1704-     config.isSemanticBoundary =  false ;
1708+     config.isSemanticBoundary =  true ;
17051709
17061710    config.isEnabled =  isInteractive;
1711+     config.isSlider =  true ;
1712+     config.isFocusable =  isInteractive;
1713+     config.isFocused =  hasFocus;
1714+     switch  (_platform) {
1715+       case  TargetPlatform .android: 
1716+       case  TargetPlatform .fuchsia: 
1717+       case  TargetPlatform .iOS: 
1718+       case  TargetPlatform .linux: 
1719+       case  TargetPlatform .macOS: 
1720+         break ;
1721+       case  TargetPlatform .windows: 
1722+         config.onDidGainAccessibilityFocus =  onDidGainAccessibilityFocus;
1723+         break ;
1724+     }
17071725    config.textDirection =  textDirection;
17081726    if  (isInteractive) {
17091727      config.onIncrease =  increaseAction;
0 commit comments