From dc27ee5083967100c9d4958a2461e63431b4cc45 Mon Sep 17 00:00:00 2001 From: Sebastien Tardif Date: Fri, 17 Jul 2026 11:23:52 -0400 Subject: [PATCH] fix: guard delayed drag autoscroll after dispose Future.delayed callbacks in selection drag autoscroll can fire after the editor is removed. The non-null cast on findRenderObject then crashes. Check mounted and use a safe typed cast before scrolling. --- lib/src/_code_selection.dart | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/src/_code_selection.dart b/lib/src/_code_selection.dart index 6df7f6d..449b308 100644 --- a/lib/src/_code_selection.dart +++ b/lib/src/_code_selection.dart @@ -375,11 +375,19 @@ class _CodeSelectionGestureDetectorState extends State<_CodeSelectionGestureDete void _autoScrollWhenDragging() { final Offset? position = _dragPosition; Future.delayed(const Duration(milliseconds: 100), (() { + // Widget may have been disposed while the delayed callback was pending. + if (!mounted) { + return; + } if (_dragPosition == null || position == null) { return; } if (_dragging) { - render.autoScrollWhenDragging(_dragPosition!); + final renderObject = widget.editorKey.currentContext?.findRenderObject(); + if (renderObject is! _CodeFieldRender) { + return; + } + renderObject.autoScrollWhenDragging(_dragPosition!); _extendSelection(_dragPosition!, _SelectionChangedCause.drag); } _autoScrollWhenDragging(); @@ -909,7 +917,12 @@ class _MobileSelectionOverlayController implements _SelectionOverlayController { if (!_startHandleDragging) { return; } - ensureRender.autoScrollWhenDragging(_startHandleDragLastPosition); + // Overlay/controller may outlive the field after dispose. + final renderObject = editorKey.currentContext?.findRenderObject(); + if (renderObject is! _CodeFieldRender) { + return; + } + renderObject.autoScrollWhenDragging(_startHandleDragLastPosition); _handleStartHandleDragUpdate(_startHandleDragLastPosition); _autoScrollWhenStartHandleDragging(); })); @@ -920,7 +933,11 @@ class _MobileSelectionOverlayController implements _SelectionOverlayController { if (!_endHandleDragging) { return; } - ensureRender.autoScrollWhenDragging(_endHandleDragLastPosition); + final renderObject = editorKey.currentContext?.findRenderObject(); + if (renderObject is! _CodeFieldRender) { + return; + } + renderObject.autoScrollWhenDragging(_endHandleDragLastPosition); _handleEndHandleDragUpdate(_endHandleDragLastPosition); _autoScrollWhenEndHandleDragging(); }));