diff --git a/src/core/services/overlay-visibility.test.ts b/src/core/services/overlay-visibility.test.ts index edfc5bcd..6fafe2a5 100644 --- a/src/core/services/overlay-visibility.test.ts +++ b/src/core/services/overlay-visibility.test.ts @@ -154,6 +154,63 @@ test('macOS keeps visible overlay hidden while tracker is not ready and emits on assert.ok(!calls.includes('show')); }); +test('macOS dismisses overlay loading OSD when tracker recovers', () => { + const { window, calls } = createMainWindowRecorder(); + let trackerWarning = false; + const osdMessages: string[] = []; + const dismissedOsds: string[] = []; + let tracking = false; + let geometry: WindowTrackerStub['getGeometry'] extends () => infer T ? T : never = null; + const tracker: WindowTrackerStub = { + isTracking: () => tracking, + getGeometry: () => geometry, + isTargetWindowFocused: () => tracking, + }; + + const run = () => + updateVisibleOverlayVisibility({ + visibleOverlayVisible: true, + mainWindow: window as never, + windowTracker: tracker as never, + trackerNotReadyWarningShown: trackerWarning, + setTrackerNotReadyWarningShown: (shown: boolean) => { + trackerWarning = shown; + }, + updateVisibleOverlayBounds: () => { + calls.push('update-bounds'); + }, + ensureOverlayWindowLevel: () => { + calls.push('ensure-level'); + }, + syncPrimaryOverlayWindowLayer: () => { + calls.push('sync-layer'); + }, + enforceOverlayLayerOrder: () => { + calls.push('enforce-order'); + }, + syncOverlayShortcuts: () => { + calls.push('sync-shortcuts'); + }, + isMacOSPlatform: true, + showOverlayLoadingOsd: (message: string) => { + osdMessages.push(message); + }, + dismissOverlayLoadingOsd: () => { + dismissedOsds.push('dismiss'); + }, + } as never); + + run(); + tracking = true; + geometry = { x: 0, y: 0, width: 1280, height: 720 }; + run(); + + assert.deepEqual(osdMessages, ['Overlay loading...']); + assert.deepEqual(dismissedOsds, ['dismiss']); + assert.equal(trackerWarning, false); + assert.ok(calls.includes('show-inactive')); +}); + test('tracked non-macOS overlay stays hidden while tracker is not ready', () => { const { window, calls } = createMainWindowRecorder(); let trackerWarning = false; diff --git a/src/renderer/overlay-notifications.test.ts b/src/renderer/overlay-notifications.test.ts index 7d499fb3..20030558 100644 --- a/src/renderer/overlay-notifications.test.ts +++ b/src/renderer/overlay-notifications.test.ts @@ -207,6 +207,15 @@ test('overlay notification cards use larger display dimensions', () => { overlayNotificationCss, /\.overlay-notification-card\.has-image\s*\{[^}]*min-height:\s*88px;/s, ); - assert.match(overlayNotificationCss, /\.overlay-notification-image\s*\{[^}]*width:\s*100px;/s); - assert.match(overlayNotificationCss, /\.overlay-notification-image\s*\{[^}]*height:\s*56px;/s); + // The has-image card reserves a real grid track for the thumbnail so it + // cannot overlap the text, and the image shrinks to fit within that track. + assert.match( + overlayNotificationCss, + /\.overlay-notification-card\.has-image\s*\{[^}]*grid-template-columns:\s*minmax\(0,\s*100px\)\s+minmax\(0,\s*1fr\)\s+22px;/s, + ); + assert.match(overlayNotificationCss, /\.overlay-notification-image\s*\{[^}]*max-width:\s*100px;/s); + assert.match( + overlayNotificationCss, + /\.overlay-notification-image\s*\{[^}]*aspect-ratio:\s*100 \/ 56;/s, + ); }); diff --git a/src/renderer/style.css b/src/renderer/style.css index 0e275ce1..cd44d810 100644 --- a/src/renderer/style.css +++ b/src/renderer/style.css @@ -259,14 +259,19 @@ body:focus-visible, } .overlay-notification-card.has-image { - grid-template-columns: 56px minmax(0, 1fr) 22px; + /* Reserve a real track for the thumbnail so it never overlaps the text. + minmax(0, 100px) lets the column shrink the image on narrow notifications + instead of letting it spill into the content column. */ + grid-template-columns: minmax(0, 100px) minmax(0, 1fr) 22px; min-height: 88px; padding-left: 14px; } .overlay-notification-image { - width: 100px; - height: 56px; + width: 100%; + max-width: 100px; + aspect-ratio: 100 / 56; + height: auto; align-self: center; display: block; border-radius: 7px;