Skip to content

fix(terminal): improve text selection UX and scroll alignment - #46

Merged
involvex merged 1 commit into
mainfrom
cursor/terminal-selection-improvements-e469
Oct 24, 2026
Merged

involvex merged 1 commit into
mainfrom
cursor/terminal-selection-improvements-e469

Conversation

@involvex

@involvex involvex commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

Improves PocketShell terminal text selection after reviewing the xterm selection flow (long-press/drag, toolbar, handles, and search).

Problems addressed

  • Find-in-terminal broke selection: TerminalSearchSession._scrollToCurrent disposed anchors immediately after setSelection, but xterm takes ownership of those anchors — selection became detached and copy/handles failed after jumping to a match.
  • Handles drifted while scrolling: Selection handles listened for scroll notifications on a sibling overlay, not an ancestor of xterm's Scrollable, so handles did not repaint when scrollback moved.
  • Accidental remote clicks: With "send mouse taps" enabled, taps could still reach vim/tmux while adjusting a selection.

Changes

  • Fix search scroll-to-match to use createAnchorFromOffset without disposing controller-owned anchors.
  • Per-session ScrollController shared by TerminalView and TerminalSelectionHandles.
  • TerminalSelectionInputGuard suspends pointer forwarding while a selection is active.
  • Toolbar uses theme colors, copy clears selection, snackbar shows character count (no clipboard preview).
  • Haptic feedback when dragging selection handles.
  • Shared selectedTerminalText helper and tests.

Test plan

  • flutter analyze
  • flutter test
  • On device: long-press/drag to select, scroll scrollback — handles stay on text
  • Find in terminal → next/prev match — highlight and copy still work
  • Copy from toolbar clears selection; vim does not receive stray taps during selection
Open in Web Open in Cursor 

Summary by Sourcery

Improve terminal text selection behavior across search, scrolling, handle interaction, and copying.

Bug Fixes:

  • Preserve terminal text selection when jumping to search matches.
  • Keep selection handles aligned with terminal content while scrolling.
  • Prevent pointer events from reaching remote sessions while text selection is active.

Enhancements:

  • Improve the selection toolbar with theme-aware styling, selection-clearing copy behavior, and character-count feedback.
  • Add haptic feedback when dragging selection handles and centralize selected-text retrieval.

Documentation:

  • Document the terminal selection and scroll-alignment fixes and updated copy and input behavior in the changelog.

Tests:

  • Add coverage for selected-text retrieval, search selection persistence, and clearing selection after copying.

@changeset-bot

changeset-bot Bot commented Oct 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 977d5b7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@sourcery-ai

sourcery-ai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

The PR updates terminal selection flow by preserving xterm anchor ownership during search, sharing scroll state so handles track scrollback, suppressing remote pointer input during selection, and improving copy/UI feedback with focused tests and changelog entries.

Sequence diagram for terminal selection and guarded input

sequenceDiagram
    actor User
    participant Handles as TerminalSelectionHandles
    participant Controller as TerminalController
    participant Guard as TerminalSelectionInputGuard
    participant Remote as RemoteSession

    User->>Handles: Drag selection handle
    Handles->>Controller: setSelection(...)
    Controller-->>Guard: selection changed
    Guard->>Controller: setSuspendPointerInput(true)
    User->>Remote: Tap or toolbar interaction
    Note over Controller,Remote: Pointer forwarding is suspended while selection exists
    User->>Controller: clearSelection()
    Controller-->>Guard: selection cleared
    Guard->>Controller: setSuspendPointerInput(false)
Loading

Sequence diagram for search selection anchor ownership

sequenceDiagram
    participant Search as TerminalSearchSession
    participant Buffer as TerminalBuffer
    participant Controller as TerminalController

    Search->>Buffer: createAnchorFromOffset(begin)
    Search->>Buffer: createAnchorFromOffset(end)
    Search->>Controller: setSelection(start, end)
    Note over Buffer,Controller: Controller-owned anchors remain valid for copy and handles
Loading

File-Level Changes

Change Details Files
Preserve search-created selection anchors so xterm retains ownership after jumping to a match.
  • Create anchors from buffer offsets and pass them directly to the controller.
  • Add regression coverage confirming search leaves an active selection.
lib/widgets/terminal_search_bar.dart
test/widgets/terminal_search_scroll_selection_test.dart
Keep selection handles synchronized with terminal scrollback through a per-session scroll controller.
  • Create, reuse, and dispose scroll controllers with terminal sessions.
  • Share the controller between TerminalView and selection handles.
  • Repaint handle positions on scroll changes.
lib/screens/home_screen.dart
lib/widgets/terminal_selection_handles.dart
Prevent remote pointer events while a local selection is active.
  • Wrap each terminal in a controller-listening input guard.
  • Toggle xterm pointer suspension with selection lifecycle and clean it up on disposal.
lib/screens/home_screen.dart
lib/widgets/terminal_selection_input_guard.dart
Refine selection toolbar behavior and feedback.
  • Centralize selected-text extraction in a reusable helper.
  • Clear selection after copying and report the copied character count.
  • Use theme surface colors and add haptic feedback when handle dragging begins.
lib/utils/terminal_selection.dart
lib/widgets/terminal_selection_toolbar.dart
lib/widgets/terminal_selection_handles.dart
test/utils/terminal_selection_test.dart
test/widgets/terminal_selection_toolbar_test.dart
Document the terminal selection and interaction changes in the unreleased changelog.
  • Record search-anchor, handle-alignment, copy, and remote-input behavior changes.
CHANGELOG.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@kilo-code-bot

kilo-code-bot Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (11 files)
  • CHANGELOG.md
  • lib/screens/home_screen.dart
  • lib/utils/terminal_selection.dart
  • lib/widgets/terminal_search_bar.dart
  • lib/widgets/terminal_selection_handles.dart
  • lib/widgets/terminal_selection_input_guard.dart
  • lib/widgets/terminal_selection_toolbar.dart
  • pubspec.lock
  • test/utils/terminal_selection_test.dart
  • test/widgets/terminal_search_scroll_selection_test.dart
  • test/widgets/terminal_selection_toolbar_test.dart

Reviewed by free · Input: 25K · Output: 1.1K · Cached: 246.6K

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@involvex
involvex merged commit e06c9fd into main Oct 24, 2026
8 checks passed
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.

1 participant