From a2e6c30b44c155816f897af454a82fbc313e0b2d Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Fri, 3 Apr 2020 20:26:01 -0700 Subject: [PATCH] Update Highlight mode initial value calculation. (#52990) --- .../lib/src/widgets/focus_manager.dart | 37 ++++++++++++++----- .../test/widgets/focus_manager_test.dart | 15 ++++++++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/packages/flutter/lib/src/widgets/focus_manager.dart b/packages/flutter/lib/src/widgets/focus_manager.dart index b410c75fb6..2872ea4657 100644 --- a/packages/flutter/lib/src/widgets/focus_manager.dart +++ b/packages/flutter/lib/src/widgets/focus_manager.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:io'; import 'dart:ui'; import 'package:flutter/foundation.dart'; @@ -1368,7 +1367,34 @@ class FocusManager with DiagnosticableTreeMixin, ChangeNotifier { /// the [WidgetsBinding] instance. static FocusManager get instance => WidgetsBinding.instance.focusManager; - bool _lastInteractionWasTouch = true; + bool get _lastInteractionWasTouch { + // Assume that if we're on one of these mobile platforms, or if there's no + // mouse connected, that the initial interaction will be touch-based, and + // that it's traditional mouse and keyboard on all others. + // + // This only affects the initial value: the ongoing value is updated to a + // known correct value as soon as any pointer events are received. + if (_lastInteractionWasTouchValue == null) { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.iOS: + _lastInteractionWasTouchValue = !WidgetsBinding.instance.mouseTracker.mouseIsConnected; + break; + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: + _lastInteractionWasTouchValue = false; + break; + } + } + return _lastInteractionWasTouchValue; + } + bool _lastInteractionWasTouchValue; + set _lastInteractionWasTouch(bool value) { + _lastInteractionWasTouchValue = value; + } + /// Sets the strategy by which [highlightMode] is determined. /// @@ -1418,13 +1444,6 @@ class FocusManager with DiagnosticableTreeMixin, ChangeNotifier { // Update function to be called whenever the state relating to highlightMode // changes. void _updateHighlightMode() { - // Assume that if we're on one of these mobile platforms, or if there's no - // mouse connected, that the initial interaction will be touch-based, and - // that it's traditional mouse and keyboard on all others. - // - // This only affects the initial value: the ongoing value is updated as soon - // as any input events are received. - _lastInteractionWasTouch ??= Platform.isAndroid || Platform.isIOS || !WidgetsBinding.instance.mouseTracker.mouseIsConnected; FocusHighlightMode newMode; switch (highlightStrategy) { case FocusHighlightStrategy.automatic: diff --git a/packages/flutter/test/widgets/focus_manager_test.dart b/packages/flutter/test/widgets/focus_manager_test.dart index 88513d04a1..7a8fd61b15 100644 --- a/packages/flutter/test/widgets/focus_manager_test.dart +++ b/packages/flutter/test/widgets/focus_manager_test.dart @@ -828,6 +828,21 @@ void main() { // receive it. expect(receivedAnEvent, isEmpty); }); + testWidgets('Initial highlight mode guesses correctly.', (WidgetTester tester) async { + FocusManager.instance.highlightStrategy = FocusHighlightStrategy.automatic; + switch (defaultTargetPlatform) { + case TargetPlatform.fuchsia: + case TargetPlatform.android: + case TargetPlatform.iOS: + expect(FocusManager.instance.highlightMode, equals(FocusHighlightMode.touch)); + break; + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: + expect(FocusManager.instance.highlightMode, equals(FocusHighlightMode.traditional)); + break; + } + }, variant: TargetPlatformVariant.all()); testWidgets('Events change focus highlight mode.', (WidgetTester tester) async { await setupWidget(tester); int callCount = 0;