fix(notifications): reserve grid space for overlay thumbnail so it can't overlap text

The thumbnail was 100px wide but its grid column only reserved 56px, so on
macOS the image spilled ~44px into the content column and overlapped the
title/body. Reserve a minmax(0, 100px) track for the image and make the
image fluid (width: 100%; max-width: 100px; aspect-ratio) so it shrinks to
fit on narrow notifications instead of overlapping the text.
This commit is contained in:
2026-06-05 01:33:58 -07:00
parent b177a2fb4d
commit 486f682563
3 changed files with 76 additions and 5 deletions
@@ -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;
+11 -2
View File
@@ -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,
);
});
+8 -3
View File
@@ -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;