diff --git a/src/main.tsx b/src/main.tsx index cd5e83d..71d69c2 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -10,6 +10,11 @@ import './styles/globals.css'; import 'katex/dist/katex.min.css'; import { initializeDefaultTransports } from './lib/api-client'; +const platform = window.electron?.platform; +if (platform) { + document.documentElement.dataset.platform = platform; +} + initializeDefaultTransports(); ReactDOM.createRoot(document.getElementById('root')!).render( diff --git a/src/styles/globals.css b/src/styles/globals.css index 622925d..1da7010 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -219,6 +219,48 @@ backdrop-filter: blur(18px) saturate(135%); } +/* Chromium's backdrop sampling is disproportionately expensive for transient + * layers in macOS Electron windows. Keep the optimization platform-scoped so + * the shared materials remain unchanged elsewhere. */ +html[data-platform='darwin'] :is( + [role='dialog'], + [role='alertdialog'], + [role='menu'], + [role='listbox'], + [role='tooltip'], + .fixed.inset-0 +), +html[data-platform='darwin'] :is( + [role='dialog'], + [role='alertdialog'], + [role='menu'], + [role='listbox'], + [role='tooltip'], + .fixed.inset-0 +) .glass-surface { + -webkit-backdrop-filter: none !important; + backdrop-filter: none !important; +} + +html[data-platform='darwin'] :is( + [role='dialog'], + [role='alertdialog'], + [role='menu'], + [role='listbox'], + [role='tooltip'], + .fixed.inset-0 +).glass-surface, +html[data-platform='darwin'] :is( + [role='dialog'], + [role='alertdialog'], + [role='menu'], + [role='listbox'], + [role='tooltip'], + .fixed.inset-0 +) .glass-surface { + background-color: hsl(var(--background)); +} + /* Sidebar material: keep the rail visibly white while allowing a restrained * amount of the canvas to show through. A low white alpha reads as gray over * the transparent native window material, so the light surface needs to stay diff --git a/tests/e2e/popup-performance.spec.ts b/tests/e2e/popup-performance.spec.ts new file mode 100644 index 0000000..494c5cf --- /dev/null +++ b/tests/e2e/popup-performance.spec.ts @@ -0,0 +1,62 @@ +import { expect, getStableWindow, test } from './fixtures/electron'; + +type PopupStyles = { + contentBackdropFilter: string; + overlayBackdropFilter: string; +}; + +async function readPopupStyles(page: Awaited>): Promise { + return await page.evaluate(() => { + const content = document.querySelector('[role="dialog"]'); + const overlay = [...document.querySelectorAll('.fixed.inset-0')] + .find((element) => element.getAttribute('role') !== 'dialog'); + if (!overlay || !content) { + throw new Error('Expected the open dialog overlay and content'); + } + + const contentStyle = getComputedStyle(content); + const overlayStyle = getComputedStyle(overlay); + return { + contentBackdropFilter: contentStyle.backdropFilter, + overlayBackdropFilter: overlayStyle.backdropFilter, + }; + }); +} + +test.describe('shared popup rendering cost', () => { + test('disables transient popup backdrop filters only on macOS', async ({ launchElectronApp }) => { + const app = await launchElectronApp({ skipSetup: true }); + + try { + const page = await getStableWindow(app); + const actualPlatform = await page.evaluate(() => window.electron.platform); + await expect(page.locator('html')).toHaveAttribute('data-platform', actualPlatform); + + await expect(page.getByTestId('ai-module-selection-page')).toBeVisible(); + await page.getByTestId('ai-module-option-programming').click(); + await expect(page.getByTestId('main-layout')).toBeVisible(); + await page.getByTestId('sidebar-member-menu-trigger').click(); + await page.getByTestId('sidebar-nav-settings').click(); + await expect(page.getByTestId('settings-page')).toBeVisible(); + await page.getByTestId('settings-reveal-additional').click(); + await expect(page.getByRole('dialog')).toBeVisible(); + + await page.evaluate(() => { + document.documentElement.dataset.platform = 'darwin'; + }); + await expect.poll(() => readPopupStyles(page)).toEqual({ + contentBackdropFilter: 'none', + overlayBackdropFilter: 'none', + }); + + await page.evaluate(() => { + document.documentElement.dataset.platform = 'win32'; + }); + const nonMacStyles = await readPopupStyles(page); + expect(nonMacStyles.contentBackdropFilter).not.toBe('none'); + expect(nonMacStyles.overlayBackdropFilter).not.toBe('none'); + } finally { + await app.evaluate(({ app: electronApp }) => electronApp.quit()); + } + }); +});