diff --git a/lib/widgets/tv_browse_rail.dart b/lib/widgets/tv_browse_rail.dart index e0f2fa00..835aeb42 100644 --- a/lib/widgets/tv_browse_rail.dart +++ b/lib/widgets/tv_browse_rail.dart @@ -1315,15 +1315,25 @@ class TvBrowseRailState extends State { child: Stack( clipBehavior: Clip.none, children: [ - _buildHubRailList( - hub: hub, - hubIndex: hubIndex, - episodePosterMode: episodePosterMode, - metrics: metrics, - scale: scale, - fullCardLayout: fullCardLayout, - scrollController: scrollController, - totalCount: totalCount, + // Inactive rows drop out of the semantics tree: their cards + // can't take focus until the hub is activated (locked-hub + // model), and the per-frame semantics pass on a11y-active TV + // boxes scales with node count — the active row's nodes are + // the only ones a screen reader can act on anyway. + ListenableSelector( + listenable: _focusModel, + selector: () => _focusModel.hubIndex == hubIndex, + builder: (context, isActive, child) => ExcludeSemantics(excluding: !isActive, child: child), + child: _buildHubRailList( + hub: hub, + hubIndex: hubIndex, + episodePosterMode: episodePosterMode, + metrics: metrics, + scale: scale, + fullCardLayout: fullCardLayout, + scrollController: scrollController, + totalCount: totalCount, + ), ), Positioned.fill( left: -leftOverflow, diff --git a/lib/widgets/tv_spotlight_background.dart b/lib/widgets/tv_spotlight_background.dart index 88db7c15..4eb50117 100644 --- a/lib/widgets/tv_spotlight_background.dart +++ b/lib/widgets/tv_spotlight_background.dart @@ -102,7 +102,7 @@ class TvSpotlightBackground extends StatelessWidget { // Expand instead of the default loose centered Stack so the // info keeps filling the region and bottom-left aligning. layoutBuilder: (currentChild, previousChildren) => - Stack(fit: StackFit.expand, children: [...previousChildren, if (currentChild != null) currentChild]), + Stack(fit: StackFit.expand, children: [...previousChildren, ?currentChild]), child: KeyedSubtree( key: ValueKey(media.globalKey), child: LayoutBuilder(