Skip to content

Fix #294007 terminal gap#306133

Open
dripfyyy wants to merge 10 commits intomicrosoft:mainfrom
dripfyyy:fix-294007-terminal-gap
Open

Fix #294007 terminal gap#306133
dripfyyy wants to merge 10 commits intomicrosoft:mainfrom
dripfyyy:fix-294007-terminal-gap

Conversation

@dripfyyy
Copy link
Copy Markdown

Problem

On macOS with high-resolution displays, the integrated terminal could
render a visible gap between the selection highlight and adjacent UI
elements (such as the terminal tabs list or panel divider). This gap
was inconsistent and sensitive to zoom level and devicePixelRatio,
sometimes appearing or disappearing as the zoom changed.

Root Cause

The issue was caused by a mismatch between how xterm.js renders the
terminal content and how VS Code computes the layout of the terminal
container.

Specifically:

  • xterm rendering operates on cell-based dimensions that can result in
    fractional pixel widths when scaled (zoom/DPR)
  • container and adjacent UI elements use DOM layout calculations with
    different rounding behaviour
  • this led to inconsistent alignment at the right edge of the terminal,
    causing a visible gap at certain zoom levels

Fix

Introduce an offset-column rendering approach:

  • xterm renders one additional column to ensure the right edge fully
    covers the available space
  • PTY/process dimensions continue to use the base number of columns to
    preserve correct terminal semantics (e.g. wrapping behaviour)

Additional adjustments:

  • align width calculations between renderer and container
  • subtract one cell width when reporting pixel dimensions to the PTY
  • refine viewport synchronization to run again on the next frame after
    resize/zoom events to stabilize layout

Testing

Added tests to ensure:

  • render column count and PTY column count remain correctly separated
  • process creation uses base dimensions (no offset leakage)
  • computed selection gap remains within acceptable bounds

Result

The selection highlight now consistently aligns with adjacent UI
elements across zoom levels and devicePixelRatio configurations,
eliminating the visual gap.

…om levels

Fixes a rendering inconsistency in the integrated terminal on macOS
high-DPI displays where a visible gap could appear between the
selection highlight and adjacent UI elements (tabs/divider). The gap
was sensitive to zoom level and caused by mismatched pixel alignment
between xterm rendering and container layout.

Introduces an offset-column rendering approach where xterm renders
one additional column while preserving base dimensions for
PTY/process semantics. Aligns terminal and UI boundaries by ensuring
consistent width calculations and accounting for cell width when
communicating dimensions to the PTY.

Refines viewport and resize synchronization and internal gap
computation to ensure consistent behaviour across devicePixelRatio
and zoom levels.

Adds tests to verify:
- separation between render columns and PTY dimensions
- correct process sizing (no offset leakage)
- selection gap remains within acceptable bounds

This ensures the selection highlight consistently aligns with
adjacent UI elements across all zoom/DPR configurations.
Explain the intent behind terminal sizing changes from the
previous fix:

- xterm renders one extra column for right-edge alignment
- PTY/process dimensions continue to use base columns
- viewport sync runs on the next frame after resize/zoom
- selection-gap metric is documented for regression reasoning
- tests include clearer setup and assertion intent comments
Copilot AI review requested due to automatic review settings March 29, 2026 17:46
@dripfyyy
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a macOS high-DPI/zoom-dependent rendering gap at the right edge of the integrated terminal selection highlight by adjusting xterm rendering/layout behavior and adding regression tests around the new sizing approach.

Changes:

  • Introduces an “offset column” approach where xterm renders one extra column while keeping PTY/process dimensions at the base column count.
  • Adds viewport synchronization and selection-gap measurement logic on resize/zoom/selection changes.
  • Updates terminal/xterm styling and adds tests to cover the new column split and selection-gap regression.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/vs/workbench/contrib/terminal/browser/terminalInstance.ts Splits xterm render cols vs PTY cols; adjusts pixel-width reporting; increases max canvas width.
src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts Adds zoom/resize viewport sync, scrollbar lane offsetting, and selection-gap measurement scheduling.
src/vs/workbench/contrib/terminal/browser/media/xterm.css Adds .always-show-scrollbar styling intended to stabilize the right edge.
src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts Adds selection-gap regression test calling internal helper.
src/vs/workbench/contrib/terminal/test/browser/terminalInstance.test.ts Adds tests ensuring xterm render cols and PTY cols remain separated and process creation uses base dims.

Comment thread src/vs/workbench/contrib/terminal/browser/media/xterm.css Outdated
Comment thread src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts Outdated
Comment thread src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
Comment thread src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
Comment thread src/vs/workbench/contrib/terminal/browser/terminalInstance.ts Outdated
Comment thread src/vs/workbench/contrib/terminal/browser/terminalInstance.ts Outdated
dripfyyy and others added 3 commits March 29, 2026 19:33
Conservative upper bound to avoid exceeding typical GPU/browser max texture/canvas widths.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Reserve a consistent right scrollbar lane in terminal layout while
preserving normal xterm UX: auto-hide, fade, hover reveal, and
interaction when visible.

Remove force-visible scrollbar CSS overrides.
Separate lane reservation from visibility state.
Use max configured/measured width for viewport offset.
Avoid queueing redundant deferred viewport sync callbacks when
resize/zoom events fire rapidly.

Preserve behavior: immediate sync plus one deferred sync.

Track and cancel pending viewport-sync RAF on dispose to prevent
stale callbacks after teardown.
@dripfyyy
Copy link
Copy Markdown
Author

dripfyyy commented Apr 9, 2026

Hi @benvillalobos just following up on this PR. Let me know if you have any feedback or if anything is needed from my side. Thanks.

@benvillalobos
Copy link
Copy Markdown
Member

benvillalobos commented Apr 24, 2026

Hey @dripfyyy, thanks submitting this PR! I see there's unresolved copilot feedback. If some are left unresolved intentionally, could you comment your reasoning why?

Adding area owner @meganrogge

@dripfyyy
Copy link
Copy Markdown
Author

Hey @benvillalobos, thanks!
The unresolved Copilot feedback is still there because I’m still looking into it. I’ll keep working on it and follow up once I have a resolution.

@dripfyyy
Copy link
Copy Markdown
Author

Hey @benvillalobos and @meganrogge, just a quick update. I’ve addressed all the Copilot feedback. Let me know if there’s anything else needed from my side or if you have any feedback.

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.

5 participants