Skip to content

Improve Expert Panel wheel scroll performance#68

Merged
Cassin01 merged 3 commits into
feat/scroll_by_wheelfrom
perf/expert-panel-wheel-scroll
Apr 19, 2026
Merged

Improve Expert Panel wheel scroll performance#68
Cassin01 merged 3 commits into
feat/scroll_by_wheelfrom
perf/expert-panel-wheel-scroll

Conversation

@Cassin01
Copy link
Copy Markdown
Owner

Summary

Follow-up perf pass on PR #67. Three changes localized to src/tower/app.rs and src/tower/widgets/expert_panel_display.rs:

  • Event coalescing in handle_events: drain contiguous wheel events at the same cursor position within a single main-loop iteration, producing exactly one terminal.draw() per wheel burst instead of N.
  • Shallow borrow_lines view in ExpertPanelDisplay::render: replace per-render self.content.clone() (O(total_bytes) memcpy) with a Vec<Line<'_>> of Cow::Borrowed spans, allocating only wrapper structs.
  • Height-proportional wheel step: replace the fixed WHEEL_SCROLL_LINES = 3 with wheel_scroll_lines(panel_height) = clamp(inner/4, 3..=8) so large panels scroll ~quarter-page per notch while small panels preserve the prior 3-line feel.

Design: .macot/specs/expert-panel-wheel-scroll-performance-design.md
Tasks: .macot/specs/expert-panel-wheel-scroll-performance-tasks.md

Test plan

  • make ci — 842 tests passed, clippy clean under -D warnings, fmt-check clean
  • New unit tests: wheel_scroll_lines_* (4), handle_mouse_wheel_* (ticks + direction, 4), coalesce_wheel_events_* (P1–P4, 5), borrow_lines_* (P5–P7, 4), render_shallow_view_matches_cloned_view (render parity, 2)
  • Existing wheel-scroll tests from PR Add mouse wheel scrolling to Expert Panel #67 migrated to the new (WheelDirection, col, row, ticks) signature and wheel_scroll_lines(height) expected value
  • Manual smoke (50-row terminal, 200+ line panel): indicator moves smoothly during burst, CPU lower than PR Add mouse wheel scrolling to Expert Panel #67 HEAD, small-panel floor still 3 lines/notch, wheel-down-past-bottom re-enables auto-scroll

- Coalesce contiguous wheel events at the same cursor position in
  handle_events so a burst of N ticks produces a single terminal.draw.
- Replace per-render self.content.clone() with a shallow borrow_lines
  view that allocates only Vec<Line>/Vec<Span> wrappers and shares
  span content via Cow::Borrowed.
- Make WHEEL_SCROLL_LINES height-proportional (inner / 4, clamped to
  [3, 8]) so large panels scroll ~quarter-page per notch while small
  panels preserve the prior 3-line feel.

Covered by new unit tests for wheel_scroll_lines, coalesce_wheel_events,
borrow_lines, and a render-parity integration test. make ci green
(839 tests passed; clippy and fmt clean).
The scroll indicator printed scroll_offset+1 (the 1-based top-visible
visual line), so at full scroll it read max_scroll+1/visual_line_count
(e.g. 2039/2121 on an 83-row panel) even though the last content line
was already rendered. The wording made it look like scrolling stopped
short of the bottom.

Render the bottom-visible line instead:
  (scroll_offset + visible_height).min(visual_line_count) / total

so the fully-scrolled state reads 2121/2121. Applied in both the
primary render path and the cfg(test) parity helper used by
render_shallow_view_matches_cloned_view so parity holds.
@Cassin01 Cassin01 merged commit 94e62a2 into feat/scroll_by_wheel Apr 19, 2026
@Cassin01 Cassin01 deleted the perf/expert-panel-wheel-scroll branch April 19, 2026 13:37
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