From 816e4dc24ef67d7648e149c0860fe1734d61c7ad Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Wed, 4 Nov 2026 13:22:00 +0100 Subject: [PATCH] fix: measure the window controls again after a resize, so the desktop toolbar keeps its buttons at 800 px --- lib/__tests__/window-controls-host.test.tsx | 22 +++++++++++++++++++++ lib/window-controls-overlay.ts | 10 +++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/__tests__/window-controls-host.test.tsx b/lib/__tests__/window-controls-host.test.tsx index ee7075b60..a0d7267de 100644 --- a/lib/__tests__/window-controls-host.test.tsx +++ b/lib/__tests__/window-controls-host.test.tsx @@ -333,6 +333,28 @@ describe('the window controls over the app', () => { expect(root.hasAttribute(CONTROLS_LEFT_ATTRIBUTE)).toBe(true); }); + // mail-p2-16: the desktop app sends geometrychange while the page still has + // its old width; the controls' share came out of that and stayed wrong. + it('measures again with the new width once the window has resized', () => { + const before = window.innerWidth; + const fake = overlayAt(0, before - 137); + render(); + expect(rightInset()).toBe('137px'); + act(() => { + (fake as unknown as { getTitlebarAreaRect: () => object }).getTitlebarAreaRect = () => ({ x: 0, y: 0, width: 800 - 137, height: 56 }); + fake.dispatchEvent(new Event('geometrychange')); + }); + act(() => { + Object.defineProperty(window, 'innerWidth', { value: 800, configurable: true, writable: true }); + window.dispatchEvent(new Event('resize')); + }); + try { + expect(rightInset()).toBe('137px'); + } finally { + Object.defineProperty(window, 'innerWidth', { value: before, configurable: true, writable: true }); + } + }); + it('follows geometrychange, and takes everything back when the overlay goes', () => { const fake = overlayAt(0, window.innerWidth - 138); render(); diff --git a/lib/window-controls-overlay.ts b/lib/window-controls-overlay.ts index d679f023f..a7b2fd302 100644 --- a/lib/window-controls-overlay.ts +++ b/lib/window-controls-overlay.ts @@ -104,7 +104,15 @@ export function watchTitlebarArea(listener: (area: TitlebarArea | null) => void) if (!current) return () => {}; const onChange = () => listener(readTitlebarArea()); current.addEventListener('geometrychange', onChange); - return () => current.removeEventListener('geometrychange', onChange); + // Electron sends geometrychange before the page has its new width, so the + // controls' share (width minus the strip) came out of the old width: 393 px + // at 1024, 361 at 800, the toolbar folding with room to spare (mail-p2-16). + // The resize that follows has the new width. + window.addEventListener('resize', onChange); + return () => { + current.removeEventListener('geometrychange', onChange); + window.removeEventListener('resize', onChange); + }; } const ROW_CANDIDATES = '[data-window-top-row], [data-composer-header], header, div.h-14, div.min-h-14, div.h-12, div.h-16, div.min-h-16';