Revert "drop/restore focus when app becomes invisible/visible" (#25390)
This commit is contained in:
parent
8c439fd39f
commit
a0efb78640
@ -12,7 +12,6 @@ import 'package:flutter/rendering.dart';
|
|||||||
import 'banner.dart';
|
import 'banner.dart';
|
||||||
import 'basic.dart';
|
import 'basic.dart';
|
||||||
import 'binding.dart';
|
import 'binding.dart';
|
||||||
import 'focus_manager.dart';
|
|
||||||
import 'framework.dart';
|
import 'framework.dart';
|
||||||
import 'localizations.dart';
|
import 'localizations.dart';
|
||||||
import 'media_query.dart';
|
import 'media_query.dart';
|
||||||
@ -731,33 +730,7 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
void didChangeAppLifecycleState(AppLifecycleState state) { }
|
||||||
switch (defaultTargetPlatform) {
|
|
||||||
case TargetPlatform.iOS:
|
|
||||||
return;
|
|
||||||
case TargetPlatform.android:
|
|
||||||
case TargetPlatform.fuchsia:
|
|
||||||
// When the application moves to the background, any focus nodes
|
|
||||||
// need to lose focus. When the application is restored to the
|
|
||||||
// foreground state, any focused node should regain focus (including)
|
|
||||||
// restoring the keyboard. This is only important in cases where
|
|
||||||
// applications in the background are partially visible.
|
|
||||||
switch (state) {
|
|
||||||
case AppLifecycleState.paused:
|
|
||||||
case AppLifecycleState.suspending:
|
|
||||||
case AppLifecycleState.inactive: {
|
|
||||||
final FocusManager focusManager = WidgetsBinding.instance.focusManager;
|
|
||||||
focusManager.windowDidLoseFocus();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AppLifecycleState.resumed: {
|
|
||||||
final FocusManager focusManager = WidgetsBinding.instance.focusManager;
|
|
||||||
focusManager.windowDidGainFocus();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didHaveMemoryPressure() { }
|
void didHaveMemoryPressure() { }
|
||||||
|
@ -417,45 +417,6 @@ class FocusManager {
|
|||||||
final FocusScopeNode rootScope = FocusScopeNode();
|
final FocusScopeNode rootScope = FocusScopeNode();
|
||||||
|
|
||||||
FocusNode _currentFocus;
|
FocusNode _currentFocus;
|
||||||
bool _windowHasFocus = true;
|
|
||||||
FocusNode _cachedFocus;
|
|
||||||
FocusScopeNode _cachedScope;
|
|
||||||
|
|
||||||
/// Call when the window loses focus.
|
|
||||||
///
|
|
||||||
/// The currently focused node and containg scope is cached, then the current
|
|
||||||
/// focus is removed. For example, this ensures that cursors do not blink
|
|
||||||
/// while in the background.
|
|
||||||
///
|
|
||||||
/// This method is safe to call multiple times.
|
|
||||||
void windowDidLoseFocus() {
|
|
||||||
if (!_windowHasFocus) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_windowHasFocus = false;
|
|
||||||
_cachedFocus = _currentFocus;
|
|
||||||
_cachedScope = _cachedFocus._parent;
|
|
||||||
_currentFocus?.unfocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Call when the window regains focus.
|
|
||||||
///
|
|
||||||
/// If there is a cached focus node from when the window lost focus, this
|
|
||||||
/// method will restore focus to that node. For example, this ensures that
|
|
||||||
/// a focused text node will re-request the keyboard.
|
|
||||||
///
|
|
||||||
/// This method is safe to call multiple times.
|
|
||||||
void windowDidGainFocus() {
|
|
||||||
if (_windowHasFocus) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_windowHasFocus = true;
|
|
||||||
if (_cachedFocus != null) {
|
|
||||||
_cachedScope._setFocus(_cachedFocus);
|
|
||||||
_cachedFocus = null;
|
|
||||||
_cachedScope = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _willDisposeFocusNode(FocusNode node) {
|
void _willDisposeFocusNode(FocusNode node) {
|
||||||
assert(node != null);
|
assert(node != null);
|
||||||
@ -473,18 +434,16 @@ class FocusManager {
|
|||||||
|
|
||||||
FocusNode _findNextFocus() {
|
FocusNode _findNextFocus() {
|
||||||
FocusScopeNode scope = rootScope;
|
FocusScopeNode scope = rootScope;
|
||||||
while (scope._firstChild != null) {
|
while (scope._firstChild != null)
|
||||||
scope = scope._firstChild;
|
scope = scope._firstChild;
|
||||||
}
|
|
||||||
return scope._focus;
|
return scope._focus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _update() {
|
void _update() {
|
||||||
_haveScheduledUpdate = false;
|
_haveScheduledUpdate = false;
|
||||||
final FocusNode nextFocus = _findNextFocus();
|
final FocusNode nextFocus = _findNextFocus();
|
||||||
if (_currentFocus == nextFocus) {
|
if (_currentFocus == nextFocus)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
final FocusNode previousFocus = _currentFocus;
|
final FocusNode previousFocus = _currentFocus;
|
||||||
_currentFocus = nextFocus;
|
_currentFocus = nextFocus;
|
||||||
previousFocus?._notify();
|
previousFocus?._notify();
|
||||||
|
@ -2,9 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
@ -246,29 +243,4 @@ void main() {
|
|||||||
|
|
||||||
parentFocusScope.detach();
|
parentFocusScope.detach();
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Focus is lost/restored when window focus is lost/restored on Fuchsia', (WidgetTester tester) async {
|
|
||||||
debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
|
|
||||||
final FocusNode node = FocusNode();
|
|
||||||
await tester.pumpWidget(MaterialApp(
|
|
||||||
home: Scaffold(
|
|
||||||
body: TextField(
|
|
||||||
focusNode: node,
|
|
||||||
autofocus: true,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
));
|
|
||||||
expect(node.hasFocus, true);
|
|
||||||
ByteData message = const StringCodec().encodeMessage('AppLifecycleState.inactive');
|
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) {});
|
|
||||||
await tester.pump();
|
|
||||||
// Focus is lost when app goes to background.
|
|
||||||
expect(node.hasFocus, false);
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) {});
|
|
||||||
await tester.pump();
|
|
||||||
// Focus is restored.
|
|
||||||
expect(node.hasFocus, true);
|
|
||||||
debugDefaultTargetPlatformOverride = null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user