Preserve explicit wheel scrollback against passive follow

Merged
LA
7mo ago
+120-11

Summary

  • add a regression test for wheel scrolling into scrollback followed by a passive bottom packet
  • treat the next scrollbar update after a Ghostty wheel event as explicit user intent
  • stop passive bottom packets from re-enabling follow while the user is reviewing scrollback

Verification

  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -destination "platform=macOS" -derivedDataPath /tmp/cmux-task-scrollbar-fix-mainline-red3 -only-testing:cmuxTests/GhosttySurfaceOverlayTests/testExplicitWheelScrollKeepsScrollbackPinnedAgainstLaterBottomPacket test
  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -destination "platform=macOS" -derivedDataPath /tmp/cmux-task-scrollbar-fix-mainline-green1 -only-testing:cmuxTests/GhosttySurfaceOverlayTests/testExplicitWheelScrollKeepsScrollbackPinnedAgainstLaterBottomPacket test
  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -destination "platform=macOS" -derivedDataPath /tmp/cmux-task-scrollbar-fix-mainline-green1 -only-testing:cmuxTests/GhosttySurfaceOverlayTests/testTrackpadScrollRoutesToTerminalSurfaceAndPreservesKeyboardFocusPath test-without-building
  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -destination "platform=macOS" -derivedDataPath /tmp/cmux-task-scrollbar-fix-mainline-green1 -only-testing:cmuxTests/GhosttySurfaceOverlayTests/testInactiveOverlayVisibilityTracksRequestedState test-without-building
  • ./scripts/reload.sh --tag task-scrollbar-fix-mainline

Notes

  • replaces the abandoned attempt at https://github.com/manaflow-ai/cmux/pull/1512
  • GhosttySurfaceOverlayTests still has unrelated local failures in testSearchOverlayFocusesSearchFieldAfterDeferredAttach and testSearchOverlayMountDoesNotRetainTerminalSurface when run as a whole class in this environment

Summary by cubic

Fixes scrollback being pulled back to bottom after a wheel scroll. We now treat the next scrollbar update after a wheel event as explicit user intent and keep the viewport pinned.

  • Bug Fixes
    • Post .ghosttyDidReceiveWheelScroll from scrollWheel and track pending explicit wheel intent.
    • On the next scrollbar update, sync once to the user's position and mark userScrolledAwayFromBottom; block passive bottom packets from re-enabling follow.
    • Add regression test testExplicitWheelScrollKeepsScrollbackPinnedAgainstLaterBottomPacket with a helper ScrollbarPostingSurfaceView.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed scrollbar synchronization issue where manually scrolling with the mouse wheel would cause unwanted viewport jumps when new terminal content arrives at the bottom.
  • Tests

    • Added test coverage for explicit mouse wheel scroll behavior and scrollback viewport preservation.