diff --git a/apps/desktop/e2e/attachment.spec.ts b/apps/desktop/e2e/attachment.spec.ts index 5b98d32bde..7572523575 100644 --- a/apps/desktop/e2e/attachment.spec.ts +++ b/apps/desktop/e2e/attachment.spec.ts @@ -109,7 +109,19 @@ test('a mixed attachment send has the Astryx message hierarchy', async ({ window expect(imageBox!.y + imageBox!.height).toBeLessThanOrEqual(bubbleBox!.y); await image.getByRole('button').click(); - await expect(page.locator('.astryx-lightbox')).toBeVisible(); + const lightbox = page.locator('.astryx-lightbox'); + await expect(lightbox).toBeVisible(); + + // The lightbox close button lands inside the titlebar's drag rect, where the + // OS eats clicks unless the modal is `no-drag`. The overlap is asserted first — + // without it the app-region check would guard nothing. + const titlebar = page.locator('.maka-window-titlebar'); + const [titlebarBox, lightboxBox] = await Promise.all([titlebar.boundingBox(), lightbox.boundingBox()]); + expect(titlebarBox).not.toBeNull(); + expect(lightboxBox).not.toBeNull(); + expect(lightboxBox!.y).toBeLessThan(titlebarBox!.y + titlebarBox!.height); + await expect(lightbox).toHaveCSS('-webkit-app-region', 'no-drag'); + await page.keyboard.press('Escape'); await expect(page.locator('.astryx-lightbox')).not.toBeVisible(); }); diff --git a/apps/desktop/src/renderer/styles/shell-layout.css b/apps/desktop/src/renderer/styles/shell-layout.css index f8e78d9533..762be2ac33 100644 --- a/apps/desktop/src/renderer/styles/shell-layout.css +++ b/apps/desktop/src/renderer/styles/shell-layout.css @@ -259,6 +259,13 @@ -webkit-app-region: drag; } +/* Drag regions are hit-tested from element rects, and the top layer is invisible + to that pass: a `showModal()` dialog paints over the titlebar, but its controls + inside the titlebar rect still reach the OS as window drags. */ +dialog:modal { + -webkit-app-region: no-drag; +} + .maka-shell-topbar-rail { display: flex; align-items: center;