l0ng-aiandl0ng-ai d992d6d9a9 Smooth scrolling: spread a wheel detent over frames instead of jumping it (#382)
* feat(terminal): animate wheel scrolling instead of jumping a notch at once

Sub-line scroll positions were already in place — the view keeps a
fractional remainder and paints the grid shifted by it — but the position
was a function of the event, not of time. A notch arrived and the whole
distance was applied at once, so whether it looked smooth came down to how
fine-grained the platform's deltas happened to be.

A macOS trackpad reports pixels, so it did. A wheel on Windows reports
whole lines (gpui multiplies the notch by the system's scroll-lines
setting, three by default), the fraction came out zero every time, and the
view jumped three lines per notch. The sub-line machinery was present and
never engaged.

A 120-step notch is one discrete pulse; no arithmetic on the delta recovers
a continuous gesture from it. So make position a function of time: a notch
adds to a remaining distance and each frame consumes a share of what is
left, ~120ms to land, exponential, with a sub-pixel remainder snapped
rather than approached since every frame of it costs a repaint.

Line deltas are discrete and get animated; pixel deltas are continuous and
do not — putting an animation between a trackpad and the grid would only
add lag. Mouse reporting and alternate-scroll keep forwarding whole lines,
which cannot be spread over frames either.

The distance in flight is relative rather than an absolute target, so
output arriving mid-scroll shifts the grid without dragging the animation
elsewhere. Everything that moves the view on its own cancels what is in
flight first.

Settings -> Terminal -> Scrolling -> Smooth scrolling, on by default.

Also pin the scratch config dir in the terminal-view test harness: building
a view reads the config, and which test got there first decided whether
that touched the real user directory.

* fix(terminal): tell a trackpad from a wheel by phase, not delta type

The first cut split the two on the delta variant — Lines meant a wheel,
Pixels meant a trackpad. That holds on Windows and Linux. It does not hold
on macOS, which sets hasPreciseScrollingDeltas for a wheel mouse as well, so
a wheel reported pixels, took the trackpad path, and was never animated.

Measured on this machine, one detent arrives as a single ~103px event —
about five lines at a 21px line height, applied in one go. That is a worse
jump than the three lines Windows produced, and it was invisible to a check
based on the delta's type.

Size cannot separate them either: a trackpad flick reaches ~3 lines in one
event while an inched wheel moves ~0.6, so the ranges overlap and any
threshold misclassifies a quarter of the trackpad stream.

Phase can. Only a device that can gesture ever reports Started/Ended; a
wheel is Moved forever, on every backend. So track the gesture instead —
and hold it open on a 150ms idle timer rather than closing it on Ended,
because lifting the fingers is not the end of the stream: the momentum tail
keeps delivering Moved events larger than the gesture that spawned them,
and animating those would smooth what the system already smoothed.

Also skip the animation for jumps under a line. Inching a wheel one detent
at a time lands there, and spreading a half-line move only adds lag to
something that already reads as continuous.

Tests are now shaped after the measured event streams rather than after an
assumption about which variant each device sends.

* chore: trigger a Claude review of this branch

---------

Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
2026-08-07 22:34:32 +08:00
2026-08-02 13:12:09 +08:00

tty7

tty7

A terminal workbench: persistent sessions, remote work, agents.

Pure Rust · GPU rendering on Zed's gpui · VT core from Alacritty


CI Version License Discord

English · 简体中文

Why

  • Performance — ~2× the throughput of Alacritty, Ghostty, or Kitty (benchmarks)
  • Persistent sessions — quit or reboot; your shells and supported agent sessions keep running, no tmux
  • Editor-grade input — suggestions, completion, highlighting, history search
  • Remote development — files, repos, panes, and git data stay on the remote machine
  • Native SSH — profiles, SFTP, port forwarding, and jump hosts
  • Agent-aware — Claude Code, Codex & co.: status, notifications, git context
  • CLI + Skills — agents create panes, run commands, and inspect output

Install

Native builds for each platform on Releases:

macOS …-macos-arm64.dmg · …-x86_64.dmg drag into Applications
Windows …-setup.exe · portable ….zip
Linux …-x86_64.AppImage chmod +x and run — X11/Wayland libraries bundled

What's inside

Editor-grade input ghost suggestions from history · explained tab completion · syntax highlighting · multi-line editing · click places the caret · ⌃ R fuzzy history
Window tabs & splits · ⌘ P palette · ⌘ F scrollback search · nine themes · IME
Agent-aware per-pane detection (~17 CLIs): status dot · notifications · branch + diff · resume after reboot · tray icon when input is needed
Remote workspaces remote files, repos, changes, diffs, worktrees, tabs, and panes · reconnect from any client and continue where you left off
CLI + Skills bundled tty7 CLI · agent skill · pane/workspace control · real PTY commands · output, process, port, and agent status
SSH native russh stack: profiles with keychain secrets · SFTP panel · port forwarding · jump hosts · one-time, unprivileged tty7-server install

Terminal and keybinding reference: docs/features.md. The agent-facing CLI interface is documented in skills/tty7/SKILL.md.

Install the skill with:

npx skills add l0ng-ai/tty7

Benchmarks

Same machine, same day, same 155×40 grid — Apple M1 Pro, macOS 26.3.1, five-run averages (2026-07-04):

tty7 Alacritty Ghostty Kitty
Plaintext I/O — 11 MB cat (lower = better) 95 ms 239 ms 179 ms 185 ms
DOOM-fire frame rate (higher = better) 888 fps 485 fps 552 fps 617 fps
Cold-launch memory 116 MB¹ 105 MB 128 MB 130 MB

¹ GUI 105 MB + the persistent server 11 MB.

Methodology and one-command reproduction: scripts/bench/.


S
Description
A terminal workbench in pure Rust: shells, persistent sessions, SSH, coding agents. GPU-rendered on Zed's gpui, VT core from Alacritty.
Readme Apache-2.0
34 MiB
Languages
Rust 99.1%
Shell 0.5%
PowerShell 0.2%
Inno Setup 0.1%