Retained custom editor webview briefly renders at default iframe size when switching from a text editor

Open
#323,890 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
52/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
typescript
Domain
desktop

Research direction

Reproduce the reveal sequence with the minimal retained custom editor described in the issue, then read overlayWebview.ts, overlayLayoutElement.ts, and webviewElement.ts at the referenced commit. Trace when visibility and anchor-based dimensions are applied during OverlayWebview.claim(). Done means switching back to the retained editor no longer paints at an intermediate viewport size.

Written by the indexing model from the issue text.

Description

Type: Bug

Summary

A retained custom editor webview can briefly paint at a tiny/default iframe-sized viewport when switching back to it from a normal text editor tab.

This is especially visible for complex webview editors with multiple layout regions: canvas/content area, docked side panels, bottom panels, toolbars, persisted panel layout, and components that derive layout from window.innerWidth / window.innerHeight. A transient tiny viewport causes the editor to compose itself incorrectly for a frame or two, then snap back once the final editor bounds are applied.

This does not appear to be the extension resetting the webview HTML or losing React/app state. The webview context is retained. The issue appears to be the retained iframe-backed webview becoming visible before its host overlay has fully resolved to the active editor bounds.

VS Code version

Version: 1.126.0
Commit: 7e7950df89d055b5a378379db9ee14290772148a
OS: macOS 26.5.1 arm64

Minimal repro

Create an extension that registers a custom editor with retainContextWhenHidden: true:

vscode.window.registerCustomEditorProvider(
  'repro.retainedEditor',
  provider,
  {
    webviewOptions: {
      retainContextWhenHidden: true,
    },
  }
);

The webview content should have a viewport-derived layout with multiple regions and log its size across resize/reveal frames, for example:

function record(label) {
  console.log(label, window.innerWidth, window.innerHeight, performance.now());
}

window.addEventListener('resize', () => {
  record('resize');
  requestAnimationFrame(() => record('resize raf 1'));
  requestAnimationFrame(() => requestAnimationFrame(() => record('resize raf 2')));
});

record('load');

Use simple HTML/CSS with a header, main content area, right docked panel, and bottom panel so incorrect intermediate sizing is visible.

Steps:

  1. Open a file handled by the custom editor.
  2. Open a normal text file in the same editor group.
  3. Switch from the text file back to the custom editor.
  4. Repeat the tab switch a few times.

Expected behavior

When a retained custom editor webview is revealed, it should either already have the final editor dimensions before painting, or remain hidden until its host overlay has those final dimensions.

The webview should not briefly lay out against a tiny/default/stale viewport during reveal.

Actual behavior

For one or more frames after switching from a text editor back to the retained custom editor, the webview can paint as if its viewport is much smaller than the editor area, then resize to the final editor bounds.

For complex viewport-derived layouts, this creates a visible top-left/cropped composition before the UI snaps to the correct layout.

Relevant source-level observation

At the VS Code commit above, retained overlay webviews appear to follow this sequence:

  • OverlayWebview.release() hides the overlay content with visibility: hidden; with retainContextWhenHidden, it keeps the underlying webview alive.
  • OverlayWebview.claim() calls _show(targetWindow) before reapplying saved anchor state.
  • _show() makes the retained overlay content visible again.
  • OverlayLayoutElement sizes the overlay using CSS anchor positioning: anchor-size(width) / anchor-size(height).
  • The inner webview iframe is width: 100%; height: 100%.

Relevant files:

So the suspected failure mode is: the retained iframe-backed webview can become visible while the CSS-anchor-sized overlay is still stale or unresolved for the newly active editor location.

Dominant language
TypeScript
Stars
193k
Forks
42.9k
PR merge metrics
PR metrics pending

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/vscode

All issues in microsoft/vscode

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.