window.moveTo() shrinks window on each reload

#512533947 Status: New Priority: P3 Severity: S3 Regression: M146 (146.0.7679.0)

Summary

A popup window opened with a fixed outer size (for example width=1160,height=900) shrinks on every page reload when the popup calls window.moveTo(0, 0) during load. The position update is correct, but the outer size silently decreases on each F5.

Reproducer

▶ Open opener page ▶ Open popup directly ➚ Issue tracker

Steps

  1. Open repro.html in Chrome stable / canary.
  2. Click Open popup -- a 1160x900 popup opens at (0, 0).
  3. Note outerWidth / outerHeight in the popup.
  4. Press F5 in the popup.
  5. Observe outer size decreases each reload, even though moveTo() should only change position.
trigger

What the popup runs on load

// popup.html
(function() {
  window.moveTo(0, 0);   // runs during page load, not on click
})();

The bug does NOT reproduce when moveTo(0,0) is fired from a user click without reload. It only triggers on the load-then-reload sequence.

Root-cause direction

The renderer-side window.moveTo() implementation in third_party/blink/renderer/core/frame/local_dom_window.cc reads the current outer window rect, replaces just the origin, and sends the whole rect back to the browser:

void LocalDOMWindow::moveTo(int x, int y) const {
  ...
  gfx::Rect window_rect =
      page->GetChromeClient().RootWindowRect(*frame);   // outer rect
  window_rect.set_origin(gfx::Point(x, y));              // position only
  page->GetChromeClient().SetWindowRect(window_rect, *frame);
}

On the browser side, for non-app popups, BrowserView::GetSavedWindowPlacement / SavedBoundsAreContentBounds path treats the rect as content (inner) bounds, not outer. So each round trip:

This is exactly the inner-vs-outer mismatch flagged in the long-standing TODO(crbug.com/40092782) already living in both web_contents_impl.cc and chrome_client_impl.cc.

Links