unhover method
Takes the synthetic mouse off the screen, so everything it was hovering gets its exit.
A no-op when nothing is parked, rather than a refusal: "there is no hover
to end" is the state the caller wanted, and nothing about the screen is
ambiguous. The step names what it released so the journal line reads
unhover "Save".
Implementation
Future<DriveStep> unhover({Duration? hold, Duration? settle}) async {
var watch = Stopwatch()..start();
var released = _hovering;
if (released != null) {
await controller.sendEventToBinding(_mouse.removePointer());
_hovering = null;
// Held for the same reason the enter is: a `Tooltip` dismisses on a
// timer too (`_hoverExitDuration`), so an unhover that only settled
// would come back with the tooltip still on screen.
await lane.hold(hold ?? hoverHold);
}
var result = await lane.settle(settle ?? settleBudget);
return DriveStep(
verb: 'unhover',
target: released,
settle: result,
elapsed: watch.elapsed,
);
}