// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

class HoverClient extends StatefulWidget {
  const HoverClient({
    Key? key,
    this.onHover,
    this.child,
    this.onEnter,
    this.onExit,
  }) : super(key: key);

  final ValueChanged<bool>? onHover;
  final Widget? child;
  final VoidCallback? onEnter;
  final VoidCallback? onExit;

  @override
  HoverClientState createState() => HoverClientState();
}

class HoverClientState extends State<HoverClient> {
  void _onExit(PointerExitEvent details) {
    widget.onExit?.call();
    widget.onHover?.call(false);
  }

  void _onEnter(PointerEnterEvent details) {
    widget.onEnter?.call();
    widget.onHover?.call(true);
  }

  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: _onEnter,
      onExit: _onExit,
      child: widget.child,
    );
  }
}

class HoverFeedback extends StatefulWidget {
  const HoverFeedback({Key? key, this.onEnter, this.onExit}) : super(key: key);

  final VoidCallback? onEnter;
  final VoidCallback? onExit;

  @override
  State<HoverFeedback> createState() => _HoverFeedbackState();
}

class _HoverFeedbackState extends State<HoverFeedback> {
  bool _hovering = false;

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: HoverClient(
        onHover: (bool hovering) => setState(() => _hovering = hovering),
        onEnter: widget.onEnter,
        onExit: widget.onExit,
        child: Text(_hovering ? 'HOVERING' : 'not hovering'),
      ),
    );
  }
}

void main() {
  testWidgets('onEnter and onExit can be triggered with mouse buttons pressed', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerExitEvent? exit;
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: Container(
          color: const Color.fromARGB(0xff, 0xff, 0x00, 0x00),
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: Offset.zero);
    await gesture.down(Offset.zero); // Press the mouse button.
    addTearDown(gesture.removePointer);
    await tester.pump();
    enter = null;
    exit = null;
    // Trigger the enter event.
    await gesture.moveTo(const Offset(400.0, 300.0));
    expect(enter, isNotNull);
    expect(enter!.position, equals(const Offset(400.0, 300.0)));
    expect(enter!.localPosition, equals(const Offset(50.0, 50.0)));
    expect(exit, isNull);

    // Trigger the exit event.
    await gesture.moveTo(const Offset(1.0, 1.0));
    expect(exit, isNotNull);
    expect(exit!.position, equals(const Offset(1.0, 1.0)));
    expect(exit!.localPosition, equals(const Offset(-349.0, -249.0)));
  });

  testWidgets('detects pointer enter', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: Container(
          color: const Color.fromARGB(0xff, 0xff, 0x00, 0x00),
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: Offset.zero);
    addTearDown(gesture.removePointer);
    await tester.pump();
    move = null;
    enter = null;
    exit = null;
    await gesture.moveTo(const Offset(400.0, 300.0));
    expect(move, isNotNull);
    expect(move!.position, equals(const Offset(400.0, 300.0)));
    expect(move!.localPosition, equals(const Offset(50.0, 50.0)));
    expect(enter, isNotNull);
    expect(enter!.position, equals(const Offset(400.0, 300.0)));
    expect(enter!.localPosition, equals(const Offset(50.0, 50.0)));
    expect(exit, isNull);
  });

  testWidgets('detects pointer exiting', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: Container(
          color: const Color.fromARGB(0xff, 0xff, 0x00, 0x00),
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: Offset.zero);
    addTearDown(gesture.removePointer);
    await gesture.moveTo(const Offset(400.0, 300.0));
    await tester.pump();
    move = null;
    enter = null;
    exit = null;
    await gesture.moveTo(const Offset(1.0, 1.0));
    expect(move, isNull);
    expect(enter, isNull);
    expect(exit, isNotNull);
    expect(exit!.position, equals(const Offset(1.0, 1.0)));
    expect(exit!.localPosition, equals(const Offset(-349.0, -249.0)));
  });

  testWidgets('triggers pointer enter when a mouse is connected', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    await tester.pump();

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(400, 300));
    addTearDown(gesture.removePointer);
    expect(move, isNull);
    expect(enter, isNotNull);
    expect(enter!.position, equals(const Offset(400.0, 300.0)));
    expect(enter!.localPosition, equals(const Offset(50.0, 50.0)));
    expect(exit, isNull);
  });

  testWidgets('triggers pointer exit when a mouse is disconnected', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    await tester.pump();

    TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(400, 300));
    addTearDown(() => gesture?.removePointer);
    await tester.pump();
    move = null;
    enter = null;
    exit = null;
    await gesture.removePointer();
    gesture = null;
    expect(move, isNull);
    expect(enter, isNull);
    expect(exit, isNotNull);
    expect(exit!.position, equals(const Offset(400.0, 300.0)));
    expect(exit!.localPosition, equals(const Offset(50.0, 50.0)));
    exit = null;
    await tester.pump();
    expect(move, isNull);
    expect(enter, isNull);
    expect(exit, isNull);
  });

  testWidgets('triggers pointer enter when widget appears', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(const Center(
      child: SizedBox(
        width: 100.0,
        height: 100.0,
      ),
    ));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: Offset.zero);
    addTearDown(gesture.removePointer);
    await gesture.moveTo(const Offset(400.0, 300.0));
    await tester.pump();
    expect(enter, isNull);
    expect(move, isNull);
    expect(exit, isNull);
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    await tester.pump();
    expect(move, isNull);
    expect(enter, isNotNull);
    expect(enter!.position, equals(const Offset(400.0, 300.0)));
    expect(enter!.localPosition, equals(const Offset(50.0, 50.0)));
    expect(exit, isNull);
  });

  testWidgets("doesn't trigger pointer exit when widget disappears", (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: Offset.zero);
    addTearDown(gesture.removePointer);
    await gesture.moveTo(const Offset(400.0, 300.0));
    await tester.pump();
    move = null;
    enter = null;
    exit = null;
    await tester.pumpWidget(const Center(
      child: SizedBox(
        width: 100.0,
        height: 100.0,
      ),
    ));
    expect(enter, isNull);
    expect(move, isNull);
    expect(exit, isNull);
  });

  testWidgets('triggers pointer enter when widget moves in', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(Container(
      alignment: Alignment.topLeft,
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(401.0, 301.0));
    addTearDown(gesture.removePointer);
    await tester.pump();
    expect(enter, isNull);
    expect(move, isNull);
    expect(exit, isNull);
    await tester.pumpWidget(Container(
      alignment: Alignment.center,
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    await tester.pump();
    expect(enter, isNotNull);
    expect(enter!.position, equals(const Offset(401.0, 301.0)));
    expect(enter!.localPosition, equals(const Offset(51.0, 51.0)));
    expect(move, isNull);
    expect(exit, isNull);
  });

  testWidgets('triggers pointer exit when widget moves out', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(Container(
      alignment: Alignment.center,
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(400, 300));
    addTearDown(gesture.removePointer);
    await tester.pump();
    enter = null;
    move = null;
    exit = null;
    await tester.pumpWidget(Container(
      alignment: Alignment.topLeft,
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    await tester.pump();
    expect(enter, isNull);
    expect(move, isNull);
    expect(exit, isNotNull);
    expect(exit!.position, equals(const Offset(400, 300)));
    expect(exit!.localPosition, equals(const Offset(50, 50)));
  });

  testWidgets('detects hover from touch devices', (WidgetTester tester) async {
    PointerEnterEvent? enter;
    PointerHoverEvent? move;
    PointerExitEvent? exit;
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: Container(
          color: const Color.fromARGB(0xff, 0xff, 0x00, 0x00),
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) => enter = details,
        onHover: (PointerHoverEvent details) => move = details,
        onExit: (PointerExitEvent details) => exit = details,
      ),
    ));
    final TestGesture gesture = await tester.createGesture();
    await gesture.addPointer(location: Offset.zero);
    addTearDown(gesture.removePointer);
    await tester.pump();
    move = null;
    enter = null;
    exit = null;
    await gesture.moveTo(const Offset(400.0, 300.0));
    expect(move, isNotNull);
    expect(move!.position, equals(const Offset(400.0, 300.0)));
    expect(move!.localPosition, equals(const Offset(50.0, 50.0)));
    expect(enter, isNull);
    expect(exit, isNull);
  });

  testWidgets('Hover works with nested listeners', (WidgetTester tester) async {
    final UniqueKey key1 = UniqueKey();
    final UniqueKey key2 = UniqueKey();
    final List<PointerEnterEvent> enter1 = <PointerEnterEvent>[];
    final List<PointerHoverEvent> move1 = <PointerHoverEvent>[];
    final List<PointerExitEvent> exit1 = <PointerExitEvent>[];
    final List<PointerEnterEvent> enter2 = <PointerEnterEvent>[];
    final List<PointerHoverEvent> move2 = <PointerHoverEvent>[];
    final List<PointerExitEvent> exit2 = <PointerExitEvent>[];
    void clearLists() {
      enter1.clear();
      move1.clear();
      exit1.clear();
      enter2.clear();
      move2.clear();
      exit2.clear();
    }

    await tester.pumpWidget(Container());
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await gesture.moveTo(const Offset(400.0, 0.0));
    await tester.pump();
    await tester.pumpWidget(
      Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          MouseRegion(
            onEnter: (PointerEnterEvent details) => enter1.add(details),
            onHover: (PointerHoverEvent details) => move1.add(details),
            onExit: (PointerExitEvent details) => exit1.add(details),
            key: key1,
            child: Container(
              width: 200,
              height: 200,
              padding: const EdgeInsets.all(50.0),
              child: MouseRegion(
                key: key2,
                onEnter: (PointerEnterEvent details) => enter2.add(details),
                onHover: (PointerHoverEvent details) => move2.add(details),
                onExit: (PointerExitEvent details) => exit2.add(details),
                child: Container(),
              ),
            ),
          ),
        ],
      ),
    );
    Offset center = tester.getCenter(find.byKey(key2));
    await gesture.moveTo(center);
    await tester.pump();
    expect(move2, isNotEmpty);
    expect(enter2, isNotEmpty);
    expect(exit2, isEmpty);
    expect(move1, isNotEmpty);
    expect(move1.last.position, equals(center));
    expect(enter1, isNotEmpty);
    expect(enter1.last.position, equals(center));
    expect(exit1, isEmpty);
    clearLists();

    // Now make sure that exiting the child only triggers the child exit, not
    // the parent too.
    center = center - const Offset(75.0, 0.0);
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(move2, isEmpty);
    expect(enter2, isEmpty);
    expect(exit2, isNotEmpty);
    expect(move1, isNotEmpty);
    expect(move1.last.position, equals(center));
    expect(enter1, isEmpty);
    expect(exit1, isEmpty);
    clearLists();
  });

  testWidgets('Hover transfers between two listeners', (WidgetTester tester) async {
    final UniqueKey key1 = UniqueKey();
    final UniqueKey key2 = UniqueKey();
    final List<PointerEnterEvent> enter1 = <PointerEnterEvent>[];
    final List<PointerHoverEvent> move1 = <PointerHoverEvent>[];
    final List<PointerExitEvent> exit1 = <PointerExitEvent>[];
    final List<PointerEnterEvent> enter2 = <PointerEnterEvent>[];
    final List<PointerHoverEvent> move2 = <PointerHoverEvent>[];
    final List<PointerExitEvent> exit2 = <PointerExitEvent>[];
    void clearLists() {
      enter1.clear();
      move1.clear();
      exit1.clear();
      enter2.clear();
      move2.clear();
      exit2.clear();
    }

    await tester.pumpWidget(Container());
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await gesture.moveTo(const Offset(400.0, 0.0));
    await tester.pump();
    await tester.pumpWidget(
      Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          MouseRegion(
            key: key1,
            child: const SizedBox(
              width: 100.0,
              height: 100.0,
            ),
            onEnter: (PointerEnterEvent details) => enter1.add(details),
            onHover: (PointerHoverEvent details) => move1.add(details),
            onExit: (PointerExitEvent details) => exit1.add(details),
          ),
          MouseRegion(
            key: key2,
            child: const SizedBox(
              width: 100.0,
              height: 100.0,
            ),
            onEnter: (PointerEnterEvent details) => enter2.add(details),
            onHover: (PointerHoverEvent details) => move2.add(details),
            onExit: (PointerExitEvent details) => exit2.add(details),
          ),
        ],
      ),
    );
    final Offset center1 = tester.getCenter(find.byKey(key1));
    final Offset center2 = tester.getCenter(find.byKey(key2));
    await gesture.moveTo(center1);
    await tester.pump();
    expect(move1, isNotEmpty);
    expect(move1.last.position, equals(center1));
    expect(enter1, isNotEmpty);
    expect(enter1.last.position, equals(center1));
    expect(exit1, isEmpty);
    expect(move2, isEmpty);
    expect(enter2, isEmpty);
    expect(exit2, isEmpty);
    clearLists();
    await gesture.moveTo(center2);
    await tester.pump();
    expect(move1, isEmpty);
    expect(enter1, isEmpty);
    expect(exit1, isNotEmpty);
    expect(exit1.last.position, equals(center2));
    expect(move2, isNotEmpty);
    expect(move2.last.position, equals(center2));
    expect(enter2, isNotEmpty);
    expect(enter2.last.position, equals(center2));
    expect(exit2, isEmpty);
    clearLists();
    await gesture.moveTo(const Offset(400.0, 450.0));
    await tester.pump();
    expect(move1, isEmpty);
    expect(enter1, isEmpty);
    expect(exit1, isEmpty);
    expect(move2, isEmpty);
    expect(enter2, isEmpty);
    expect(exit2, isNotEmpty);
    expect(exit2.last.position, equals(const Offset(400.0, 450.0)));
    clearLists();
    await tester.pumpWidget(Container());
    expect(move1, isEmpty);
    expect(enter1, isEmpty);
    expect(exit1, isEmpty);
    expect(move2, isEmpty);
    expect(enter2, isEmpty);
    expect(exit2, isEmpty);
  });

  testWidgets('applies mouse cursor', (WidgetTester tester) async {
    await tester.pumpWidget(const _Scaffold(
      topLeft: MouseRegion(
        cursor: SystemMouseCursors.text,
        child: SizedBox(width: 10, height: 10),
      ),
    ));

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(100, 100));
    addTearDown(gesture.removePointer);

    await tester.pump();
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);

    await gesture.moveTo(const Offset(5, 5));
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);

    await gesture.moveTo(const Offset(100, 100));
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
  });

  testWidgets('MouseRegion uses updated callbacks', (WidgetTester tester) async {
    final List<String> logs = <String>[];
    Widget hoverableContainer({
      PointerEnterEventListener? onEnter,
      PointerHoverEventListener? onHover,
      PointerExitEventListener? onExit,
    }) {
      return Container(
        alignment: Alignment.topLeft,
        child: MouseRegion(
          onEnter: onEnter,
          onHover: onHover,
          onExit: onExit,
          child: Container(
            color: const Color.fromARGB(0xff, 0xff, 0x00, 0x00),
            width: 100.0,
            height: 100.0,
          ),
        ),
      );
    }

    await tester.pumpWidget(hoverableContainer(
      onEnter: (PointerEnterEvent details) {
        logs.add('enter1');
      },
      onHover: (PointerHoverEvent details) {
        logs.add('hover1');
      },
      onExit: (PointerExitEvent details) { logs.add('exit1'); },
    ));

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(150.0, 150.0));
    addTearDown(gesture.removePointer);

    // Start outside, move inside, then move outside
    await gesture.moveTo(const Offset(150.0, 150.0));
    await tester.pump();
    expect(logs, isEmpty);
    logs.clear();
    await gesture.moveTo(const Offset(50.0, 50.0));
    await tester.pump();
    await gesture.moveTo(const Offset(150.0, 150.0));
    await tester.pump();
    expect(logs, <String>['enter1', 'hover1', 'exit1']);
    logs.clear();

    // Same tests but with updated callbacks
    await tester.pumpWidget(hoverableContainer(
      onEnter: (PointerEnterEvent details) => logs.add('enter2'),
      onHover: (PointerHoverEvent details) => logs.add('hover2'),
      onExit: (PointerExitEvent details) => logs.add('exit2'),
    ));
    await gesture.moveTo(const Offset(150.0, 150.0));
    await tester.pump();
    await gesture.moveTo(const Offset(50.0, 50.0));
    await tester.pump();
    await gesture.moveTo(const Offset(150.0, 150.0));
    await tester.pump();
    expect(logs, <String>['enter2', 'hover2', 'exit2']);
  });

  testWidgets('needsCompositing set when parent class needsCompositing is set', (WidgetTester tester) async {
    await tester.pumpWidget(
      MouseRegion(
        onEnter: (PointerEnterEvent _) {},
        child: const Opacity(opacity: 0.5, child: Placeholder()),
      ),
    );

    RenderMouseRegion listener = tester.renderObject(find.byType(MouseRegion).first);
    expect(listener.needsCompositing, isTrue);

    await tester.pumpWidget(
      MouseRegion(
        onEnter: (PointerEnterEvent _) {},
        child: const Placeholder(),
      ),
    );

    listener = tester.renderObject(find.byType(MouseRegion).first);
    expect(listener.needsCompositing, isFalse);
  });

  testWidgets('works with transform', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/31986.
    final Key key = UniqueKey();
    const double scaleFactor = 2.0;
    const double localWidth = 150.0;
    const double localHeight = 100.0;
    final List<PointerEvent> events = <PointerEvent>[];

    await tester.pumpWidget(
      MaterialApp(
        home: Center(
          child: Transform.scale(
            scale: scaleFactor,
            child: MouseRegion(
              onEnter: (PointerEnterEvent event) {
                events.add(event);
              },
              onHover: (PointerHoverEvent event) {
                events.add(event);
              },
              onExit: (PointerExitEvent event) {
                events.add(event);
              },
              child: Container(
                key: key,
                color: Colors.blue,
                height: localHeight,
                width: localWidth,
                child: const Text('Hi'),
              ),
            ),
          ),
        ),
      ),
    );

    final Offset topLeft = tester.getTopLeft(find.byKey(key));
    final Offset topRight = tester.getTopRight(find.byKey(key));
    final Offset bottomLeft = tester.getBottomLeft(find.byKey(key));
    expect(topRight.dx - topLeft.dx, scaleFactor * localWidth);
    expect(bottomLeft.dy - topLeft.dy, scaleFactor * localHeight);

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);
    await gesture.moveTo(topLeft - const Offset(1, 1));
    await tester.pump();
    expect(events, isEmpty);

    await gesture.moveTo(topLeft + const Offset(1, 1));
    await tester.pump();
    expect(events, hasLength(2));
    expect(events.first, isA<PointerEnterEvent>());
    expect(events.last, isA<PointerHoverEvent>());
    events.clear();

    await gesture.moveTo(bottomLeft + const Offset(1, -1));
    await tester.pump();
    expect(events.single, isA<PointerHoverEvent>());
    expect(events.single.delta, const Offset(0.0, scaleFactor * localHeight - 2));
    events.clear();

    await gesture.moveTo(bottomLeft + const Offset(1, 1));
    await tester.pump();
    expect(events.single, isA<PointerExitEvent>());
    events.clear();
  });

  testWidgets('needsCompositing is always false', (WidgetTester tester) async {
    // Pretend that we have a mouse connected.
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);

    await tester.pumpWidget(
      Transform.scale(
        scale: 2.0,
        child: const MouseRegion(opaque: false),
      ),
    );
    final RenderMouseRegion mouseRegion = tester.renderObject(find.byType(MouseRegion));
    expect(mouseRegion.needsCompositing, isFalse);
    // No TransformLayer for `Transform.scale` is added because composting is
    // not required and therefore the transform is executed on the canvas
    // directly. (One TransformLayer is always present for the root
    // transform.)
    expect(tester.layers.whereType<TransformLayer>(), hasLength(1));

    // Test that needsCompositing stays false with callback change
    await tester.pumpWidget(
      Transform.scale(
        scale: 2.0,
        child: MouseRegion(
          opaque: false,
          onHover: (PointerHoverEvent _) {},
        ),
      ),
    );
    expect(mouseRegion.needsCompositing, isFalse);
    // If compositing was required, a dedicated TransformLayer for
    // `Transform.scale` would be added.
    expect(tester.layers.whereType<TransformLayer>(), hasLength(1));
  });

  testWidgets("Callbacks aren't called during build", (WidgetTester tester) async {
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await gesture.addPointer(location: Offset.zero);

    int numEntrances = 0;
    int numExits = 0;

    await tester.pumpWidget(
      Center(
        child: HoverFeedback(
          onEnter: () { numEntrances += 1; },
          onExit: () { numExits += 1; },
        ),
      ),
    );

    await gesture.moveTo(tester.getCenter(find.byType(Text)));
    await tester.pumpAndSettle();
    expect(numEntrances, equals(1));
    expect(numExits, equals(0));
    expect(find.text('HOVERING'), findsOneWidget);

    await tester.pumpWidget(
      Container(),
    );
    await tester.pump();
    expect(numEntrances, equals(1));
    expect(numExits, equals(0));

    await tester.pumpWidget(
      Center(
        child: HoverFeedback(
          onEnter: () { numEntrances += 1; },
          onExit: () { numExits += 1; },
        ),
      ),
    );
    await tester.pump();
    expect(numEntrances, equals(2));
    expect(numExits, equals(0));
  });

  testWidgets("MouseRegion activate/deactivate don't duplicate annotations", (WidgetTester tester) async {
    final GlobalKey feedbackKey = GlobalKey();
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);

    int numEntrances = 0;
    int numExits = 0;

    await tester.pumpWidget(
      Center(
        child: HoverFeedback(
          key: feedbackKey,
          onEnter: () { numEntrances += 1; },
          onExit: () { numExits += 1; },
        ),
      ),
    );

    await gesture.moveTo(tester.getCenter(find.byType(Text)));
    await tester.pumpAndSettle();
    expect(numEntrances, equals(1));
    expect(numExits, equals(0));
    expect(find.text('HOVERING'), findsOneWidget);

    await tester.pumpWidget(
      Center(
        child: HoverFeedback(
          key: feedbackKey,
          onEnter: () { numEntrances += 1; },
          onExit: () { numExits += 1; },
        ),
      ),
    );
    await tester.pump();
    expect(numEntrances, equals(1));
    expect(numExits, equals(0));
    await tester.pumpWidget(
      Container(),
    );
    await tester.pump();
    expect(numEntrances, equals(1));
    expect(numExits, equals(0));
  });

  testWidgets('Exit event when unplugging mouse should have a position', (WidgetTester tester) async {
    final List<PointerEnterEvent> enter = <PointerEnterEvent>[];
    final List<PointerHoverEvent> hover = <PointerHoverEvent>[];
    final List<PointerExitEvent> exit = <PointerExitEvent>[];

    await tester.pumpWidget(
      Center(
        child: MouseRegion(
          onEnter: (PointerEnterEvent e) => enter.add(e),
          onHover: (PointerHoverEvent e) => hover.add(e),
          onExit: (PointerExitEvent e) => exit.add(e),
          child: const SizedBox(
            height: 100.0,
            width: 100.0,
          ),
        ),
      ),
    );

    // Plug-in a mouse and move it to the center of the container.
    TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: Offset.zero);
    addTearDown(() => gesture?.removePointer());
    await tester.pumpAndSettle();
    await gesture.moveTo(tester.getCenter(find.byType(SizedBox)));

    expect(enter.length, 1);
    expect(enter.single.position, const Offset(400.0, 300.0));
    expect(hover.length, 1);
    expect(hover.single.position, const Offset(400.0, 300.0));
    expect(exit.length, 0);

    enter.clear();
    hover.clear();
    exit.clear();

    // Unplug the mouse.
    await gesture.removePointer();
    gesture = null;
    await tester.pumpAndSettle();

    expect(enter.length, 0);
    expect(hover.length, 0);
    expect(exit.length, 1);
    expect(exit.single.position, const Offset(400.0, 300.0));
    expect(exit.single.delta, Offset.zero);
  });

  testWidgets('detects pointer enter with closure arguments', (WidgetTester tester) async {
    await tester.pumpWidget(_HoverClientWithClosures());
    expect(find.text('not hovering'), findsOneWidget);

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await gesture.addPointer();
    // Move to a position out of MouseRegion
    await gesture.moveTo(tester.getBottomRight(find.byType(MouseRegion)) + const Offset(10, -10));
    await tester.pumpAndSettle();
    expect(find.text('not hovering'), findsOneWidget);

    // Move into MouseRegion
    await gesture.moveBy(const Offset(-20, 0));
    await tester.pumpAndSettle();
    expect(find.text('HOVERING'), findsOneWidget);
  });

  testWidgets('MouseRegion paints child once and only once when MouseRegion is inactive', (WidgetTester tester) async {
    int paintCount = 0;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MouseRegion(
          onEnter: (PointerEnterEvent e) {},
          child: CustomPaint(
            painter: _DelegatedPainter(onPaint: () { paintCount += 1; }),
            child: const Text('123'),
          ),
        ),
      ),
    );

    expect(paintCount, 1);
  });

  testWidgets('MouseRegion paints child once and only once when MouseRegion is active', (WidgetTester tester) async {
    int paintCount = 0;

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MouseRegion(
          onEnter: (PointerEnterEvent e) {},
          child: CustomPaint(
            painter: _DelegatedPainter(onPaint: () { paintCount += 1; }),
            child: const Text('123'),
          ),
        ),
      ),
    );

    expect(paintCount, 1);
  });

  testWidgets('A MouseRegion mounted under the pointer should should take effect in the next postframe', (WidgetTester tester) async {
    bool hovered = false;

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(5, 5));
    addTearDown(gesture.removePointer);

    await tester.pumpWidget(
      StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
        return _ColumnContainer(
          children: <Widget>[
            Text(hovered ? 'hover outer' : 'unhover outer'),
          ],
        );
      }),
    );

    expect(find.text('unhover outer'), findsOneWidget);

    await tester.pumpWidget(
      StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
        return _ColumnContainer(
          children: <Widget>[
            HoverClient(
              onHover: (bool value) { setState(() { hovered = value; }); },
              child: Text(hovered ? 'hover inner' : 'unhover inner'),
            ),
            Text(hovered ? 'hover outer' : 'unhover outer'),
          ],
        );
      }),
    );

    expect(find.text('unhover outer'), findsOneWidget);
    expect(find.text('unhover inner'), findsOneWidget);

    await tester.pump();

    expect(find.text('hover outer'), findsOneWidget);
    expect(find.text('hover inner'), findsOneWidget);
    expect(tester.binding.hasScheduledFrame, isFalse);
  });

  testWidgets('A MouseRegion unmounted under the pointer should not trigger state change', (WidgetTester tester) async {
    bool hovered = true;

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(5, 5));
    addTearDown(gesture.removePointer);

    await tester.pumpWidget(
      StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
        return _ColumnContainer(
          children: <Widget>[
            HoverClient(
              onHover: (bool value) { setState(() { hovered = value; }); },
              child: Text(hovered ? 'hover inner' : 'unhover inner'),
            ),
            Text(hovered ? 'hover outer' : 'unhover outer'),
          ],
        );
      }),
    );

    expect(find.text('hover outer'), findsOneWidget);
    expect(find.text('hover inner'), findsOneWidget);
    expect(tester.binding.hasScheduledFrame, isTrue);

    await tester.pump();
    expect(find.text('hover outer'), findsOneWidget);
    expect(find.text('hover inner'), findsOneWidget);
    expect(tester.binding.hasScheduledFrame, isFalse);

    await tester.pumpWidget(
      StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
        return _ColumnContainer(
          children: <Widget> [
            Text(hovered ? 'hover outer' : 'unhover outer'),
          ],
        );
      }),
    );

    expect(find.text('hover outer'), findsOneWidget);
    expect(tester.binding.hasScheduledFrame, isFalse);
  });

  testWidgets('A MouseRegion moved into the mouse should take effect in the next postframe', (WidgetTester tester) async {
    bool hovered = false;
    final List<bool> logHovered = <bool>[];
    bool moved = false;
    late StateSetter mySetState;

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(5, 5));
    addTearDown(gesture.removePointer);

    await tester.pumpWidget(
      StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
        mySetState = setState;
        return _ColumnContainer(
          children: <Widget>[
            Container(
              height: 100,
              width: 10,
              alignment: moved ? Alignment.topLeft : Alignment.bottomLeft,
              child: SizedBox(
                height: 10,
                width: 10,
                child: HoverClient(
                  onHover: (bool value) {
                    setState(() { hovered = value; });
                    logHovered.add(value);
                  },
                  child: Text(hovered ? 'hover inner' : 'unhover inner'),
                ),
              ),
            ),
            Text(hovered ? 'hover outer' : 'unhover outer'),
          ],
        );
      }),
    );

    expect(find.text('unhover inner'), findsOneWidget);
    expect(find.text('unhover outer'), findsOneWidget);
    expect(logHovered, isEmpty);
    expect(tester.binding.hasScheduledFrame, isFalse);

    mySetState(() { moved = true; });
    // The first frame is for the widget movement to take effect.
    await tester.pump();
    expect(find.text('unhover inner'), findsOneWidget);
    expect(find.text('unhover outer'), findsOneWidget);
    expect(logHovered, <bool>[true]);
    logHovered.clear();

    // The second frame is for the mouse hover to take effect.
    await tester.pump();
    expect(find.text('hover inner'), findsOneWidget);
    expect(find.text('hover outer'), findsOneWidget);
    expect(logHovered, isEmpty);
    expect(tester.binding.hasScheduledFrame, isFalse);
  });

  group('MouseRegion respects opacity:', () {

    // A widget that contains 3 MouseRegions:
    //                           y
    //   ——————————————————————  0
    //   | ———————————     A  |  20
    //   | | B       |        |
    //   | |     ———————————  |  50
    //   | |     |       C |  |
    //   | ——————|         |  |  100
    //   |       |         |  |
    //   |       ———————————  |  130
    //   ——————————————————————  150
    // x 0 20   50  100   130 150
    Widget tripleRegions({bool? opaqueC, required void Function(String) addLog}) {
      // Same as MouseRegion, but when opaque is null, use the default value.
      Widget mouseRegionWithOptionalOpaque({
        void Function(PointerEnterEvent e)? onEnter,
        void Function(PointerHoverEvent e)? onHover,
        void Function(PointerExitEvent e)? onExit,
        Widget? child,
        bool? opaque,
      }) {
        if (opaque == null) {
          return MouseRegion(onEnter: onEnter, onHover: onHover, onExit: onExit, child: child);
        }
        return MouseRegion(onEnter: onEnter, onHover: onHover, onExit: onExit, opaque: opaque, child: child);
      }

      return Directionality(
        textDirection: TextDirection.ltr,
        child: Align(
          alignment: Alignment.topLeft,
          child: MouseRegion(
            onEnter: (PointerEnterEvent e) { addLog('enterA'); },
            onHover: (PointerHoverEvent e) { addLog('hoverA'); },
            onExit: (PointerExitEvent e) { addLog('exitA'); },
            child: SizedBox(
              width: 150,
              height: 150,
              child: Stack(
                children: <Widget>[
                  Positioned(
                    left: 20,
                    top: 20,
                    width: 80,
                    height: 80,
                    child: MouseRegion(
                      onEnter: (PointerEnterEvent e) { addLog('enterB'); },
                      onHover: (PointerHoverEvent e) { addLog('hoverB'); },
                      onExit: (PointerExitEvent e) { addLog('exitB'); },
                    ),
                  ),
                  Positioned(
                    left: 50,
                    top: 50,
                    width: 80,
                    height: 80,
                    child: mouseRegionWithOptionalOpaque(
                      opaque: opaqueC,
                      onEnter: (PointerEnterEvent e) { addLog('enterC'); },
                      onHover: (PointerHoverEvent e) { addLog('hoverC'); },
                      onExit: (PointerExitEvent e) { addLog('exitC'); },
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      );
    }

    testWidgets('a transparent one should allow MouseRegions behind it to receive pointers', (WidgetTester tester) async {
      final List<String> logs = <String>[];
      await tester.pumpWidget(tripleRegions(
        opaqueC: false,
        addLog: (String log) => logs.add(log),
      ));

      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      addTearDown(gesture.removePointer);
      await tester.pumpAndSettle();

      // Move to the overlapping area.
      await gesture.moveTo(const Offset(75, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['enterA', 'enterB', 'enterC', 'hoverC', 'hoverB', 'hoverA']);
      logs.clear();

      // Move to the B only area.
      await gesture.moveTo(const Offset(25, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['exitC', 'hoverB', 'hoverA']);
      logs.clear();

      // Move back to the overlapping area.
      await gesture.moveTo(const Offset(75, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['enterC', 'hoverC', 'hoverB', 'hoverA']);
      logs.clear();

      // Move to the C only area.
      await gesture.moveTo(const Offset(125, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['exitB', 'hoverC', 'hoverA']);
      logs.clear();

      // Move back to the overlapping area.
      await gesture.moveTo(const Offset(75, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['enterB', 'hoverC', 'hoverB', 'hoverA']);
      logs.clear();

      // Move out.
      await gesture.moveTo(const Offset(160, 160));
      await tester.pumpAndSettle();
      expect(logs, <String>['exitC', 'exitB', 'exitA']);
    });

    testWidgets('an opaque one should prevent MouseRegions behind it receiving pointers', (WidgetTester tester) async {
      final List<String> logs = <String>[];
      await tester.pumpWidget(tripleRegions(
        opaqueC: true,
        addLog: (String log) => logs.add(log),
      ));

      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      addTearDown(gesture.removePointer);
      await tester.pumpAndSettle();

      // Move to the overlapping area.
      await gesture.moveTo(const Offset(75, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['enterA', 'enterC', 'hoverC', 'hoverA']);
      logs.clear();

      // Move to the B only area.
      await gesture.moveTo(const Offset(25, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['exitC', 'enterB', 'hoverB', 'hoverA']);
      logs.clear();

      // Move back to the overlapping area.
      await gesture.moveTo(const Offset(75, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['exitB', 'enterC', 'hoverC', 'hoverA']);
      logs.clear();

      // Move to the C only area.
      await gesture.moveTo(const Offset(125, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['hoverC', 'hoverA']);
      logs.clear();

      // Move back to the overlapping area.
      await gesture.moveTo(const Offset(75, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['hoverC', 'hoverA']);
      logs.clear();

      // Move out.
      await gesture.moveTo(const Offset(160, 160));
      await tester.pumpAndSettle();
      expect(logs, <String>['exitC', 'exitA']);
    });

    testWidgets('opaque should default to true', (WidgetTester tester) async {
      final List<String> logs = <String>[];
      await tester.pumpWidget(tripleRegions(
        addLog: (String log) => logs.add(log),
      ));

      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      addTearDown(gesture.removePointer);
      await tester.pumpAndSettle();

      // Move to the overlapping area.
      await gesture.moveTo(const Offset(75, 75));
      await tester.pumpAndSettle();
      expect(logs, <String>['enterA', 'enterC', 'hoverC', 'hoverA']);
      logs.clear();

      // Move out.
      await gesture.moveTo(const Offset(160, 160));
      await tester.pumpAndSettle();
      expect(logs, <String>['exitC', 'exitA']);
    });
  });

  testWidgets('an empty opaque MouseRegion is effective', (WidgetTester tester) async {
    bool bottomRegionIsHovered = false;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Stack(
          children: <Widget>[
            Align(
              alignment: Alignment.topLeft,
              child: MouseRegion(
                onEnter: (_) { bottomRegionIsHovered = true; },
                onHover: (_) { bottomRegionIsHovered = true; },
                onExit: (_) { bottomRegionIsHovered = true; },
                child: const SizedBox(
                  width: 10,
                  height: 10,
                ),
              ),
            ),
            const MouseRegion(),
          ],
        ),
      ),
    );

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(20, 20));
    addTearDown(gesture.removePointer);

    await gesture.moveTo(const Offset(5, 5));
    await tester.pump();
    await gesture.moveTo(const Offset(20, 20));
    await tester.pump();
    expect(bottomRegionIsHovered, isFalse);
  });

  testWidgets("Changing MouseRegion's callbacks is effective and doesn't repaint", (WidgetTester tester) async {
    final List<String> logs = <String>[];
    const Key key = ValueKey<int>(1);

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(20, 20));
    addTearDown(gesture.removePointer);

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          onEnter: (_) { logs.add('enter1'); },
          onHover: (_) { logs.add('hover1'); },
          onExit: (_) { logs.add('exit1'); },
          child: CustomPaint(
            painter: _DelegatedPainter(onPaint: () { logs.add('paint'); }, key: key),
          ),
        ),
      ),
    ));
    expect(logs, <String>['paint']);
    logs.clear();

    await gesture.moveTo(const Offset(5, 5));
    expect(logs, <String>['enter1', 'hover1']);
    logs.clear();

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          onEnter: (_) { logs.add('enter2'); },
          onHover: (_) { logs.add('hover2'); },
          onExit: (_) { logs.add('exit2'); },
          child: CustomPaint(
            painter: _DelegatedPainter(onPaint: () { logs.add('paint'); }, key: key),
          ),
        ),
      ),
    ));
    expect(logs, isEmpty);

    await gesture.moveTo(const Offset(6, 6));
    expect(logs, <String>['hover2']);
    logs.clear();

    // Compare: It repaints if the MouseRegion is deactivated.
    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          opaque: false,
          child: CustomPaint(
            painter: _DelegatedPainter(onPaint: () { logs.add('paint'); }, key: key),
          ),
        ),
      ),
    ));
    expect(logs, <String>['paint']);
  });

  testWidgets('Changing MouseRegion.opaque is effective and repaints', (WidgetTester tester) async {
    final List<String> logs = <String>[];

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(5, 5));
    addTearDown(gesture.removePointer);

    void _handleHover(PointerHoverEvent _) {}
    void _handlePaintChild() { logs.add('paint'); }

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          onHover: _handleHover,
          child: CustomPaint(painter: _DelegatedPainter(onPaint: _handlePaintChild)),
        ),
      ),
      background: MouseRegion(onEnter: (_) { logs.add('hover-enter'); }),
    ));
    expect(logs, <String>['paint']);
    logs.clear();

    expect(logs, isEmpty);
    logs.clear();

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          opaque: false,
          // Dummy callback so that MouseRegion stays affective after opaque
          // turns false.
          onHover: _handleHover,
          child: CustomPaint(painter: _DelegatedPainter(onPaint: _handlePaintChild)),
        ),
      ),
      background: MouseRegion(onEnter: (_) { logs.add('hover-enter'); }),
    ));

    expect(logs, <String>['paint', 'hover-enter']);
  });

  testWidgets('Changing MouseRegion.cursor is effective and repaints', (WidgetTester tester) async {
    final List<String> logPaints = <String>[];
    final List<String> logEnters = <String>[];

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(100, 100));
    addTearDown(gesture.removePointer);

    void onPaintChild() { logPaints.add('paint'); }

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          cursor: SystemMouseCursors.forbidden,
          onEnter: (_) { logEnters.add('enter'); },
          child: CustomPaint(painter: _DelegatedPainter(onPaint: onPaintChild)),
        ),
      ),
    ));
    await gesture.moveTo(const Offset(5, 5));

    expect(logPaints, <String>['paint']);
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);
    expect(logEnters, <String>['enter']);
    logPaints.clear();
    logEnters.clear();

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          cursor: SystemMouseCursors.text,
          onEnter: (_) { logEnters.add('enter'); },
          child: CustomPaint(painter: _DelegatedPainter(onPaint: onPaintChild)),
        ),
      ),
    ));

    expect(logPaints, <String>['paint']);
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
    expect(logEnters, isEmpty);
    logPaints.clear();
    logEnters.clear();
  });

  testWidgets('Changing whether MouseRegion.cursor is null is effective and repaints', (WidgetTester tester) async {
    final List<String> logEnters = <String>[];
    final List<String> logPaints = <String>[];

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(100, 100));
    addTearDown(gesture.removePointer);

    void onPaintChild() { logPaints.add('paint'); }

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          cursor: SystemMouseCursors.forbidden,
          child: MouseRegion(
            cursor: SystemMouseCursors.text,
            onEnter: (_) { logEnters.add('enter'); },
            child: CustomPaint(painter: _DelegatedPainter(onPaint: onPaintChild)),
          ),
        ),
      ),
    ));
    await gesture.moveTo(const Offset(5, 5));

    expect(logPaints, <String>['paint']);
    expect(logEnters, <String>['enter']);
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
    logPaints.clear();
    logEnters.clear();

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          cursor: SystemMouseCursors.forbidden,
          child: MouseRegion(
            onEnter: (_) { logEnters.add('enter'); },
            child: CustomPaint(painter: _DelegatedPainter(onPaint: onPaintChild)),
          ),
        ),
      ),
    ));

    expect(logPaints, <String>['paint']);
    expect(logEnters, isEmpty);
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);
    logPaints.clear();
    logEnters.clear();

    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        height: 10,
        width: 10,
        child: MouseRegion(
          cursor: SystemMouseCursors.forbidden,
          child: MouseRegion(
            cursor: SystemMouseCursors.text,
            child: CustomPaint(painter: _DelegatedPainter(onPaint: onPaintChild)),
          ),
        ),
      ),
    ));

    expect(logPaints, <String>['paint']);
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
    expect(logEnters, isEmpty);
    logPaints.clear();
    logEnters.clear();
  });

  testWidgets('Does not trigger side effects during a reparent', (WidgetTester tester) async {
    final List<String> logEnters = <String>[];
    final List<String> logExits = <String>[];
    final List<String> logCursors = <String>[];

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(100, 100));
    addTearDown(gesture.removePointer);
    tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.mouseCursor, (_) async {
      logCursors.add('cursor');
    });

    final GlobalKey key = GlobalKey();

    // Pump a row of 2 SizedBox's, each taking 50px of width.
    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        width: 100,
        height: 50,
        child: Row(
          children: <Widget>[
            SizedBox(
              width: 50,
              height: 50,
              child: MouseRegion(
                key: key,
                onEnter: (_) { logEnters.add('enter'); },
                onExit: (_) { logEnters.add('enter'); },
                cursor: SystemMouseCursors.click,
              ),
            ),
            const SizedBox(
              width: 50,
              height: 50,
            ),
          ],
        ),
      ),
    ));

    // Move to the mouse region inside the first box.
    await gesture.moveTo(const Offset(40, 5));

    expect(logEnters, <String>['enter']);
    expect(logExits, isEmpty);
    expect(logCursors, isNotEmpty);
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
    logEnters.clear();
    logExits.clear();
    logCursors.clear();

    // Move MouseRegion to the second box while resizing them so that the
    // mouse is still on the MouseRegion
    await tester.pumpWidget(_Scaffold(
      topLeft: SizedBox(
        width: 100,
        height: 50,
        child: Row(
          children: <Widget>[
            const SizedBox(
              width: 30,
              height: 50,
            ),
            SizedBox(
              width: 70,
              height: 50,
              child: MouseRegion(
                key: key,
                onEnter: (_) { logEnters.add('enter'); },
                onExit: (_) { logEnters.add('enter'); },
                cursor: SystemMouseCursors.click,
              ),
            ),
          ],
        ),
      ),
    ));

    expect(logEnters, isEmpty);
    expect(logExits, isEmpty);
    expect(logCursors, isEmpty);
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
  });

  testWidgets("RenderMouseRegion's debugFillProperties when default", (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    RenderMouseRegion().debugFillProperties(builder);

    final List<String> description = builder.properties.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info)).map((DiagnosticsNode node) => node.toString()).toList();

    expect(description, <String>[
      'parentData: MISSING',
      'constraints: MISSING',
      'size: MISSING',
      'listeners: <none>',
    ]);
  });

  testWidgets("RenderMouseRegion's debugFillProperties when full", (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    RenderMouseRegion(
      onEnter: (PointerEnterEvent event) {},
      onExit: (PointerExitEvent event) {},
      onHover: (PointerHoverEvent event) {},
      cursor: SystemMouseCursors.click,
      validForMouseTracker: false,
      child: RenderErrorBox(),
    ).debugFillProperties(builder);

    final List<String> description = builder.properties.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info)).map((DiagnosticsNode node) => node.toString()).toList();

    expect(description, <String>[
      'parentData: MISSING',
      'constraints: MISSING',
      'size: MISSING',
      'listeners: enter, hover, exit',
      'cursor: SystemMouseCursor(click)',
      'invalid for MouseTracker',
    ]);
  });

  testWidgets('No new frames are scheduled when mouse moves without triggering callbacks', (WidgetTester tester) async {
    await tester.pumpWidget(Center(
      child: MouseRegion(
        child: const SizedBox(
          width: 100.0,
          height: 100.0,
        ),
        onEnter: (PointerEnterEvent details) {},
        onHover: (PointerHoverEvent details) {},
        onExit: (PointerExitEvent details) {},
      ),
    ));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer(location: const Offset(400.0, 300.0));
    addTearDown(gesture.removePointer);
    await tester.pumpAndSettle();
    await gesture.moveBy(const Offset(10.0, 10.0));
    expect(tester.binding.hasScheduledFrame, isFalse);
  });

  // Regression test for https://github.com/flutter/flutter/issues/67044
  testWidgets('Handle mouse events should ignore the detached MouseTrackerAnnotation', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: Center(
        child: Draggable<int>(
          feedback: Container(width: 20, height: 20, color: Colors.blue),
          childWhenDragging: Container(width: 20, height: 20, color: Colors.yellow),
          child: ElevatedButton(child: const Text('Drag me'), onPressed: (){}),
        ),
      ),
    ));

    // Long press the button with mouse.
    final Offset textFieldPos = tester.getCenter(find.byType(Text));
    final TestGesture gesture = await tester.startGesture(
      textFieldPos,
      kind: PointerDeviceKind.mouse,
    );
    addTearDown(gesture.removePointer);
    await tester.pump(const Duration(seconds: 2));
    await tester.pumpAndSettle();

    // Drag the Draggable Widget will replace the child with [childWhenDragging].
    await gesture.moveBy(const Offset(10.0, 10.0));
    await tester.pump(); // Trigger detach the button.

    // Continue drag mouse should not trigger any assert.
    await gesture.moveBy(const Offset(10.0, 10.0));
    expect(tester.takeException(), isNull);
  });
}

// Render widget `topLeft` at the top-left corner, stacking on top of the widget
// `background`.
class _Scaffold extends StatelessWidget {
  const _Scaffold({this.topLeft, this.background});

  final Widget? topLeft;
  final Widget? background;

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: Stack(
        children: <Widget>[
          if (background != null) background!,
          Align(
            alignment: Alignment.topLeft,
            child: topLeft,
          ),
        ],
      ),
    );
  }
}

class _DelegatedPainter extends CustomPainter {
  _DelegatedPainter({this.key, required this.onPaint});
  final Key? key;
  final VoidCallback onPaint;

  @override
  void paint(Canvas canvas, Size size) {
    onPaint();
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) =>
    !(oldDelegate is _DelegatedPainter && key == oldDelegate.key);
}

class _HoverClientWithClosures extends StatefulWidget {
  @override
  _HoverClientWithClosuresState createState() => _HoverClientWithClosuresState();
}

class _HoverClientWithClosuresState extends State<_HoverClientWithClosures> {
  bool _hovering = false;

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: MouseRegion(
        onEnter: (PointerEnterEvent _) {
          setState(() {
            _hovering = true;
          });
        },
        onExit: (PointerExitEvent _) {
          setState(() {
            _hovering = false;
          });
        },
        child: Text(_hovering ? 'HOVERING' : 'not hovering'),
      ),
    );
  }
}

// A column that aligns to the top left.
class _ColumnContainer extends StatelessWidget {
  const _ColumnContainer({
    required this.children,
  }) : assert(children != null);

  final List<Widget> children;

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: children,
      ),
    );
  }
}
