stopCapture method
Stop input capture.
Implementation
@override
Future<void> stopCapture() async {
if (_isDestroyed || _contextHandle == null) {
await _cleanupCallbacks();
return;
}
if (_keyboardCallbackHandle == null &&
_mouseCallbackHandle == null &&
_gamepadCallbackHandle == null) {
return; // Already stopped
}
final res = bindings.MiniAV_Input_StopCapture(_contextHandle!);
// A non-success code means a native thread did not join
// (MINIAV_ERROR_TIMEOUT on the hook thread or the gamepad thread). The
// hook-thread timeout returns BEFORE the process-wide active-platform
// slot is cleared, so the still-installed low-level hook keeps reading
// these callback pointers. Closing the callables then is a
// use-after-free that aborts the VM; leak them instead.
if (res == bindings.MiniAVResultCode.MINIAV_SUCCESS ||
res == bindings.MiniAVResultCode.MINIAV_ERROR_NOT_RUNNING) {
await _cleanupCallbacks();
} else {
_keyboardCallbackHandle = null; // dropped, deliberately not closed
_mouseCallbackHandle = null;
_gamepadCallbackHandle = null;
print(
'Warning: MiniAV_Input_StopCapture failed: ${res.name} — a capture '
'thread may still be running, so its callbacks are leaked rather '
'than closed.',
);
}
}