Skip to content

Fix: alternate-screen scroll detaches buffer lines, breaking text selection - #240

Open
lordspace wants to merge 3 commits into
TerminalStudio:masterfrom
orbisius:master
Open

Fix: alternate-screen scroll detaches buffer lines, breaking text selection#240
lordspace wants to merge 3 commits into
TerminalStudio:masterfrom
orbisius:master

Conversation

@lordspace

Copy link
Copy Markdown

Fixes #239.

The fix

Buffer.scrollUp shifts lines up a slot with lines[i] = lines[i + n], which
leaves a stale duplicate reference in the source slot. _adoptChild detached
whatever occupied the target slot unconditionally, so the next iteration
detached the line just re-homed one index earlier — after a single
alternate-screen scroll effectively every visible line was detached, and a
selection anchored to a detached line reads back as null.

This detaches the previous occupant only when the slot is still its home.
_attach already rewrites _absoluteIndex, so a re-homed item maps elsewhere
and survives, while an eviction on a full list still detaches exactly as before.

Full diagnosis, reproduction and measurements are in the issue.

Tests

  • test/src/utils/circular_buffer_test.dart — shifting items up a slot keeps
    them attached, and the evicted item still detaches.
  • test/src/core/buffer/alt_screen_selection_test.dart — scrolls the alternate
    screen, then asserts a real selection resolves and yields the right text.

The existing can track index of items test earned its keep here: a first
version of this patch passed the new test but broke that one by sparing an item
that was genuinely being evicted. Both pass now.

The two dependency commits

Drop the discontinued dart_code_metrics dev dependency is a prerequisite,
not housekeeping. The package was discontinued, and it pins test_api versions
that conflict with the current flutter_test — so flutter test cannot resolve
dependencies at all and no test in the package runs on a current Flutter
SDK
. Its analyzer.plugins entry and config block go with it.

Upgrade lints to 6.x and refresh the dependency locklints 3 -> 6 was
the only constraint needing a raise (build_runner, mockito and test
already resolve to their ceilings under the existing ones). Two one-line changes
satisfy the new strict_top_level_inference rule: a return type on the
IndexAwareCircularBuffer index setter, and a parameter type on _onTapDown.

Happy to rebase down to the bug fix alone if you would rather take the
dependency work separately — the fix stands on its own.

Verification

flutter test115 passing. flutter analyze reports only pre-existing
SDK deprecations (withOpacity, OverlayPortal.targetsRootOverlay).

slavi added 3 commits August 13, 2026 01:11
It pins test_api versions that conflict with the current flutter_test, so
flutter test could not resolve dependencies at all — no test in the package
could run. The package was discontinued upstream, and its analyzer plugin plus
config block go with it.
Buffer.scrollUp shifts lines with lines[i] = lines[i + n], leaving a stale
duplicate reference in the source slot. _adoptChild detached whatever occupied
the target slot unconditionally, so the next iteration detached the item just
re-homed one index earlier — after a single alternate-screen scroll effectively
every visible line ended up detached.

A detached line makes CellAnchor.attached false, so TerminalController.selection
returns null: selecting text silently stopped working inside any full-screen
program (less, htop, editors) once it scrolled.

Detach the previous occupant only when this slot is still its home, so an
eviction still detaches while a re-homed item does not.
lints 3 -> 6 is the only constraint that needed raising; build_runner, mockito
and test already resolve to their ceilings under the existing ones. The lock is
refreshed within those constraints (46 transitive packages).

Satisfies the new strict_top_level_inference rule: a return type on the
IndexAwareCircularBuffer index setter and a parameter type on _onTapDown.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text selection doesn't work inside full-screen programs — alternate-screen scroll detaches buffer lines

1 participant