Windows: desktop notifications can never be enabled — "Desktop notifications are blocked. Enable them in your system settings."
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
On Windows, enabling **Settings → Notifications → Desktop alerts** always fails with
*"Desktop notifications are blocked. Enable them in your system settings."* — even on a
fresh install where the OS has never been asked for permission. There is nothing to
enable in Windows Settings: the app never appears in the notifications app list because
it has never posted a toast.
Root cause is an upstream bug in `tauri-plugin-notification`'s injected JS shim
(reported separately: tauri-apps/plugins-workspace#3512), but Buzz's permission flow
turns it into a hard dead end, and a one-line change on Buzz's side works around it.
## Environment
- Buzz Desktop 0.4.22 (`Buzz_0.4.22_x64-setup_alpha-unsigned.exe`), also present in `main`
- Windows 11 Home 10.0.26200, WebView2 runtime (Evergreen)
- `tauri-plugin-notification` 2.3.3 (per `desktop/src-tauri/Cargo.lock`)
## Steps to reproduce
1. Install Buzz on Windows and complete onboarding.
2. Open **Settings → Notifications** and turn on **Desktop alerts**.
**Expected:** toggle turns on; a toast is shown for the next mention/DM.
**Actual:** toggle snaps back off with the "blocked" error. No OS permission prompt is
shown, and Buzz is absent from Windows Settings → System → Notifications.
## Root cause
`tauri-plugin-notification` injects an init script that replaces `window.Notification`
with a shim. At startup the shim computes its permission state
([`guest-js/init.ts`](https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/init.ts#L12-L18)):
```ts
async function isPermissionGranted(): Promise {
if (window.Notification.permission !== 'default' || __TEMPLATE_windows__) {
return await Promise.resolve(window.Notification.permission === 'granted')
}
return await invoke('plugin:notification|is_permission_granted')
}
```
On Windows `__TEMPLATE_windows__` is `true`, so this always evaluates
`window.Notification.permission === 'granted'` against the shim's own
freshly-initialized `'default'` → `false` → the bootstrap stamps the permission
**`denied`** on every launch, without ever consulting the backend (whose
`permission_state()` unconditionally returns `Granted` on Windows).
Buzz then hits this in `desktop/src/features/notifications/lib/desktop.ts`
(`getDesktopNotificationPermissionState`), which trusts `window.Notification.permission`
first, and in `desktop/src/features/notifications/hooks.ts` (`setDesktopEnabled`),
which only calls `requestDesktopNotificationAccess()` when the state is `"default"`.
Since the state is already `"denied"`, the request that would repair it is never made,
and the user is told to fix it in system settings — where there is nothing to fix.
## Verification
Attached the live app via the WebView2 CDP endpoint
(`WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=9222`):
```
window.Notification.permission → "denied" (tauri shim, fresh launch)
window.Notification.requestPermission() → "granted" (backend happily grants)
window.Notification.permission → "granted" (toggle now works, toasts fire)
```
So the OS and the plugin backend both allow notifications; only the shim's cached
bootstrap value is wrong.
## Suggested fix (Buzz side, until upstream lands)
In `setDesktopEnabled` (hooks.ts), also attempt the permission request when the
reported state is `"denied"` on Windows — `requestPermission()` corrects the shim's
state and returns `"granted"`:
```ts
if (nextPermission === "default" || (nextPermission === "denied" && isWindowsPlatform())) {
nextPermission = await requestDesktopNotificationAccess();
setPermission(nextPermission);
}
```
Alternatively, `getDesktopNotificationPermissionState` could prefer the plugin's
`isPermissionGranted()` over `window.Notification.permission` when running under Tauri.
Happy to send a PR for either variant.
Contributor guide
Research direction
Start in desktop/src/features/notifications/hooks.ts at setDesktopEnabled, then read getDesktopNotificationPermissionState in desktop/src/features/notifications/lib/desktop.ts. Reproduce the Windows notification toggle failure and verify that a denied shim state can be corrected, the toggle stays enabled, and a test notification is delivered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100