[loop cycle 2] fix(notifications): forward service-worker showNotification to native toast#10
Merged
Conversation
…tive toast WhatsApp Web raises some notifications through ServiceWorkerRegistration .showNotification (used when the tab is treated as backgrounded), which the existing window.Notification shim does not intercept — so those notifications never reached the OS notification center. Override the page-side prototype method to forward through the same native `notify` command (inheriting its lock/settings suppression), and stub getNotifications to resolve to [] since we render native toasts rather than in-page Notification objects. The override is installed before any page script runs (Tauri initialization_script), so WhatsApp cannot hold a pre-patch reference; it is origin-guarded and wrapped in its own try/catch so it can never abort the rest of bridge.js. Page-context calls only — notifications fired from inside the service worker's own realm are out of scope for an injected page script. Verified in a real WebKitGTK engine (origin spoofed to web.whatsapp.com): both new Notification(...) and reg.showNotification(...) now produce exactly one native notify with the right title/body; getNotifications resolves to []; the existing Notification path and permission==="granted" are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016o9cWBaPy4zU4BAurUVoTp
karem505
added a commit
that referenced
this pull request
Jun 28, 2026
Bundles six loop-shipped fixes: - perf(dnd): stream dropped files as base64 to cut peak memory on large videos (#9) - fix(notifications): forward service-worker showNotification to the native toast (#10) - feat(calls): expose a minimal window.chrome so WhatsApp enables call buttons (#11) - fix(notifications): de-duplicate burst-repeated native toasts (#12) - fix(dnd): route AVIF/HEIF photos as photos; broaden MIME labels (#13) - fix(calls/capability): return a complete Chrome high-entropy client-hints set (#14) Plus integration: SW notifications share the dedup window; base64_encode is test-only now. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016o9cWBaPy4zU4BAurUVoTp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes a class of missing notifications. WhatsApp Web raises some notifications through the service worker via
ServiceWorkerRegistration.showNotification(...)(used when it treats the tab as backgrounded). The existingwindow.Notificationshim only intercepts the page-sidenew Notification(...)constructor — so the service-worker path slipped past it and those notifications never reached the OS notification center.How
In
bridge.js(section 2b, right after the existing Notification shim), override the page-sideServiceWorkerRegistration.prototype.showNotificationto forward through the same nativenotifycommand the constructor shim already uses, and stubgetNotifications()to resolve to[](we render native toasts, so there's no in-page Notification object to return).initialization_script, so it runs before any page JS → WhatsApp can't capture a pre-patch reference; prototype lookup at call time means instances created later are covered.https://web.whatsapp.com) and wrapped in its own try/catch, so it can never abort the rest ofbridge.js.commands::notify, inheriting its lock-screen and settings suppression unchanged.Verification
Gate 1 — deterministic (
cargo build --locked+cargo test): PASS (51 tests; bridge.js is embedded viainclude_str!).Gate 2 — real-engine behavioral (PyGObject WebKitGTK 2.x harness, origin spoofed to web.whatsapp.com): PASS. With a
__TAURI__.invokerecorder installed:new Notification("DM from Sara",{body:"hey there"})→ 1notifyinvoke ✅reg.showNotification("Group: Family",{body:"3 new messages"})→ 1notifyinvoke ✅showNotificationreturns a Promise ✅ ·getNotifications()→[]✅ ·Notification.permission === "granted"✅ (no regression to the existing path)Gate 3 — generation-blind code review (separate
feature-dev:code-reviewer): APPROVE, severity none, no must-fix. Confirmed: override timing prevents a pre-patch reference; both paths inherit identical Rust-side suppression; try/catch isolated;getNotificationsstub redundant-but-harmless; tag-dedup absence is pre-existing (matches thewindow.Notificationshim), not a regression.🤖 PR-ONLY — do not auto-merge. Releasing whatRust is manual via a
v*tag; this loop never merges, bumps the version, or tags a release. Opened by thewhatrust-fix-loop(cycle 2/6).