diff --git a/src/sw.ts b/src/sw.ts index 2b713dda2..947d38613 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -149,11 +149,19 @@ self.addEventListener('notificationclick', (event: NotificationEvent) => { event.waitUntil( (async () => { - const windowClients = await self.clients.matchAll({ - type: 'window', - includeUncontrolled: true, - }); - const client = windowClients.find((c): c is WindowClient => 'focus' in c); + const windowClients = ( + await self.clients.matchAll({ + type: 'window', + includeUncontrolled: true, + }) + ).filter((c): c is WindowClient => 'focus' in c); + // #78 — prefer a client that's actually focused, then one that's merely + // visible, before falling back to whatever matchAll() returned first (its + // ordering is unspecified across browsers and not "most recently used"). + const client = + windowClients.find((c) => c.focused) ?? + windowClients.find((c) => c.visibilityState === 'visible') ?? + windowClients[0]; if (client) { await client.focus(); if (path) client.postMessage({ type: 'notificationClick', path });