Commit 800a6e16 authored by Ian Hickson's avatar Ian Hickson Committed by jslavitz

Quick fix for tap-to-show-keyboard regression (#26629)

* Fixes Android keyboard bug
parent 4c99958d
......@@ -98,22 +98,21 @@ typedef GestureForceInterpolation = double Function(double pressureMin, double p
/// force touch functionality, with the exception of the iPhone XR. In addition,
/// a small handful of Android devices have this functionality as well.
///
/// Reported pressure will always be in the range [0.0, 1.0], where 1.0 is
/// maximum pressure and 0.0 is minimum pressure. If using a non-linear
/// interpolation equation, the pressure reported will correspond with the
/// custom curve. (ie. if the interpolation maps t(0.5) -> 0.1, a value of 0.1
/// will be reported at a device pressure value of 0.5).
///
/// Reported pressure will always be in the range 0.0 to 1.0, where 1.0 is
/// maximum pressure and 0.0 is minimum pressure. If using a custom
/// [interpolation] callback, the pressure reported will correspond to that
/// custom curve.
class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
/// Creates a force press gesture recognizer.
///
/// The [startPressure] defaults to 0.4, and [peakPressure] defaults to 0.85
/// where a value of 0.0 is no pressure and a value of 1.0 is maximum pressure.
///
/// [startPressure], [peakPressure] and [interpolation] must not be null.
/// [peakPressure] must be greater than [startPressure]. [interpolation] must
/// always return a value in the range [0.0, 1.0] where
/// pressureMin <= pressure <= pressureMax.
/// The [startPressure], [peakPressure] and [interpolation] arguments must not
/// be null. The [peakPressure] argument must be greater than [startPressure].
/// The [interpolation] callback must always return a value in the range 0.0
/// to 1.0 for values of `pressure` that are between `pressureMin` and
/// `pressureMax`.
ForcePressGestureRecognizer({
this.startPressure = 0.4,
this.peakPressure = 0.85,
......@@ -172,21 +171,22 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
final double peakPressure;
/// The function used to convert the raw device pressure values into a value
/// in the range [0, 1].
/// in the range 0.0 to 1.0.
///
/// The function takes in the device's min, max and raw touch
/// pressure and returns a value in the range [0.0, 1.0] denoting the
/// interpolated touch pressure.
/// The function takes in the device's minimum, maximum and raw touch pressure
/// and returns a value in the range 0.0 to 1.0 denoting the interpolated
/// touch pressure.
///
/// This function must always return values in the range [0, 1] when
/// pressureMin <= pressure <= pressureMax.
/// This function must always return values in the range 0.0 to 1.0 given a
/// pressure that is between the minimum and maximum pressures. It may return
/// [double.NaN] for values that it does not want to support.
///
/// By default, the the function is a simple linear interpolation, however,
/// changing the function could be useful to accommodate variations in the way
/// different devices respond to pressure, change how animations from pressure
/// feedback are rendered or for other custom functionality.
/// By default, the function is a linear interpolation; however, changing the
/// function could be useful to accommodate variations in the way different
/// devices respond to pressure, or to change how animations from pressure
/// feedback are rendered.
///
/// For example, an ease in curve can be used to determine the interpolated
/// For example, an ease-in curve can be used to determine the interpolated
/// value:
///
/// ```dart
......@@ -216,7 +216,12 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
// A static pointer with changes in pressure creates PointerMoveEvent events.
if (event is PointerMoveEvent || event is PointerDownEvent) {
final double pressure = interpolation(event.pressureMin, event.pressureMax, event.pressure);
assert(pressure.isNaN ? true : (pressure <= 1.0 && pressure >= 0.0));
assert(
event.pressure < event.pressureMin || // contract is undefined for underflowing pressures...
event.pressure > event.pressureMax || // contract is undefined for overflowing pressures...
pressure.isNaN || // and interpolation may return NaN for values it doesn't want to support...
(pressure <= 1.0 && pressure >= 0.0) // but if everything is going well, it must be in the range 1.0..0.0.
);
_lastPosition = event.position;
_lastPressure = pressure;
......@@ -300,6 +305,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
}
static double _inverseLerp(double min, double max, double t) {
assert(min <= max);
return (t - min) / (max - min);
}
......
......@@ -280,7 +280,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(EnumProperty<DragStartBehavior>('Start Behavior', dragStartBehavior));
properties.add(EnumProperty<DragStartBehavior>('start behavior', dragStartBehavior));
}
}
......
......@@ -613,16 +613,9 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
void _handleForcePressStarted(ForcePressDetails details) {
if (widget.selectionEnabled) {
switch (Theme.of(context).platform) {
case TargetPlatform.iOS:
// The cause is not technically double tap, but we would like to show
// the toolbar.
_renderEditable.selectWordsInRange(from: details.globalPosition, cause: SelectionChangedCause.doubleTap);
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
break;
}
// The cause is not technically double tap, but we would like to show
// the toolbar.
_renderEditable.selectWordsInRange(from: details.globalPosition, cause: SelectionChangedCause.doubleTap);
}
}
......@@ -724,6 +717,20 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
if (widget.maxLength != null && widget.maxLengthEnforced)
formatters.add(LengthLimitingTextInputFormatter(widget.maxLength));
bool forcePressEnabled;
TextSelectionControls textSelectionControls;
switch (themeData.platform) {
case TargetPlatform.iOS:
forcePressEnabled = true;
textSelectionControls = cupertinoTextSelectionControls;
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
forcePressEnabled = false;
textSelectionControls = materialTextSelectionControls;
break;
}
Widget child = RepaintBoundary(
child: EditableText(
key: _editableTextKey,
......@@ -740,11 +747,7 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
autocorrect: widget.autocorrect,
maxLines: widget.maxLines,
selectionColor: themeData.textSelectionColor,
selectionControls: widget.selectionEnabled
? (themeData.platform == TargetPlatform.iOS
? cupertinoTextSelectionControls
: materialTextSelectionControls)
: null,
selectionControls: widget.selectionEnabled ? textSelectionControls : null,
onChanged: widget.onChanged,
onEditingComplete: widget.onEditingComplete,
onSubmitted: widget.onSubmitted,
......@@ -789,7 +792,7 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
ignoring: !(widget.enabled ?? widget.decoration?.enabled ?? true),
child: TextSelectionGestureDetector(
onTapDown: _handleTapDown,
onForcePressStart: _handleForcePressStarted,
onForcePressStart: forcePressEnabled ? _handleForcePressStarted : null,
onSingleTapUp: _handleSingleTapUp,
onSingleTapCancel: _handleSingleTapCancel,
onSingleLongTapDown: _handleSingleLongTapDown,
......
......@@ -725,8 +725,8 @@ class _TextSelectionGestureDetectorState extends State<TextSelectionGestureDetec
void _forcePressStarted(ForcePressDetails details) {
_doubleTapTimer?.cancel();
_doubleTapTimer = null;
if (widget.onForcePressStart != null)
widget.onForcePressStart(details);
if (widget.onForcePressStart != null)
widget.onForcePressStart(details);
}
void _forcePressEnded(ForcePressDetails details) {
......@@ -761,8 +761,8 @@ class _TextSelectionGestureDetectorState extends State<TextSelectionGestureDetec
return GestureDetector(
onTapDown: _handleTapDown,
onTapUp: _handleTapUp,
onForcePressStart: _forcePressStarted,
onForcePressEnd: _forcePressEnded,
onForcePressStart: widget.onForcePressStart != null ? _forcePressStarted : null,
onForcePressEnd: widget.onForcePressEnd != null ? _forcePressEnded : null,
onTapCancel: _handleTapCancel,
onLongPress: _handleLongPress,
excludeFromSemantics: true,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment