Fix iframe size feedback loop on Linux/Windows (#54)

Compensate for viewport scrollbar width in size change notifications.
On Linux/Windows, scrollbars consume space from the content area, causing
a feedback loop where the iframe progressively shrinks to zero.

- Use window.innerWidth - clientWidth to detect scrollbar width
- Use max of getBoundingClientRect (CSS transforms) and scroll dimensions
  (content overflow) to report accurate size

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Jonathan Hefner 2025-12-01 14:05:35 -06:00 • committed by GitHub
commit 1cf95e53e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -745,6 +745,7 @@ export class App extends Protocol<Request, Notification, Result> {
*/
setupSizeChangeNotifications() {
let scheduled = false;
const sendBodySizeChange = () => {
if (scheduled) {
return;
@ -752,11 +753,17 @@ export class App extends Protocol<Request, Notification, Result> {
scheduled = true;
requestAnimationFrame(() => {
scheduled = false;
const rect = (
document.body.parentElement ?? document.body
).getBoundingClientRect();
const width = Math.ceil(rect.width);
const height = Math.ceil(rect.height);
const el = document.body.parentElement ?? document.body;
const rect = el.getBoundingClientRect();
// Compensate for viewport scrollbar on Linux/Windows where scrollbars
// consume space. window.innerWidth includes scrollbar, clientWidth excludes it.
const scrollbarWidth =
window.innerWidth - document.documentElement.clientWidth;
// Use max of rect (includes CSS transforms) and scroll dimensions (content overflow).
const width = Math.ceil(
Math.max(rect.width, el.scrollWidth) + scrollbarWidth,
);
const height = Math.ceil(Math.max(rect.height, el.scrollHeight));
this.sendSizeChange({ width, height });
});
};