always place cursor at end of file when switching to edit mode

Removes the unreliable viewport-centre cursor heuristic. Switching to
edit mode now always positions the cursor at text.length and scrolls to
the bottom, whether arriving from a regular tap or a long-press. The
long-press scroll-to-end on initial load (view mode) is unchanged.

Cleans up _cursorAtEnd flag, _editorKey / GlobalKey, _getOffsetAtViewportCenter,
and the public WrappedCodeFieldState / findRenderEditable that were only
needed for the removed feature.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
randogoth 2026-06-19 19:01:21 +03:00
parent db13702e54
commit 14d6b3c44d
2 changed files with 15 additions and 20 deletions

View file

@ -43,7 +43,9 @@ class _WrappedCodeFieldState extends State<WrappedCodeField> {
@override
void dispose() {
_focusNode.dispose();
if (widget.focusNode == null) {
_focusNode.dispose();
}
super.dispose();
}

View file

@ -43,13 +43,11 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
bool _isLoading = true;
bool _autoSaveEnabled = false;
double _fontSize = 16.0;
bool _cursorAtEnd = false;
@override
void initState() {
super.initState();
_mode = widget.initialMode;
_cursorAtEnd = widget.scrollToEnd;
_loadPreferences();
_loadNoteContent();
}
@ -86,18 +84,16 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
_isLoading = false;
});
if (widget.initialMode == NoteMode.edit) {
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (widget.initialMode == NoteMode.edit) {
_controller.selection =
TextSelection.collapsed(offset: _controller.text.length);
_editorFocusNode.requestFocus();
});
} else if (widget.scrollToEnd) {
// Two frames: first renders the content, second has a stable maxScrollExtent.
WidgetsBinding.instance.addPostFrameCallback((_) {
} else if (widget.scrollToEnd) {
// Two frames: first renders content, second has a stable maxScrollExtent.
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToBottom());
});
}
}
});
}
void _scrollToBottom() {
@ -224,15 +220,12 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
break;
case 'Mode Edit':
setState(() { _mode = NoteMode.edit; });
if (_cursorAtEnd) {
_cursorAtEnd = false; // consume once
WidgetsBinding.instance.addPostFrameCallback((_) {
_controller.selection = TextSelection.collapsed(
offset: _controller.text.length);
_editorFocusNode.requestFocus();
_scrollToBottom();
});
}
WidgetsBinding.instance.addPostFrameCallback((_) {
_controller.selection = TextSelection.collapsed(
offset: _controller.text.length);
_editorFocusNode.requestFocus();
_scrollToBottom();
});
break;
case 'Mode Preview':
setState(() { _mode = NoteMode.preview; });