Skip to content

Desktop Notifications Never Appear on macOS #122

@brooksc

Description

@brooksc

App: Parallel Code v1.9.0
Platform: macOS 26.4.1 (Build 25E253)
Electron: v40.8.5
Node: v25.9.0


Summary

Desktop notifications are enabled in Settings but never fire on macOS. The app does not appear in System Settings > Notifications, which is required for macOS to deliver notifications.

Steps to Reproduce

  1. Launch Parallel Code on macOS
  2. Open Settings and enable "Desktop notifications"
  3. Run a task to completion
  4. Observe: no notification appears
  5. Open System Settings > Notifications — Parallel Code is not listed

Expected Behavior

On first enabling desktop notifications, macOS should prompt the user to allow notifications. After granting permission, the app should appear in System Settings > Notifications and deliver notifications when tasks complete or need attention.

Actual Behavior

No permission prompt is ever shown. No notifications are delivered. The app is absent from System Settings > Notifications.

Root Cause

systemPreferences.requestNotificationPermission() is never called. macOS 10.14+ requires explicit permission before an app can deliver notifications — without this call, the OS silently drops all notification attempts.

The code in electron/ipc/register.ts:781 checks Notification.isSupported(), which returns true regardless of permission status, masking the failure. The notification objects are created and .show() is called, but macOS discards them silently.

Relevant code paths:

  • electron/ipc/register.ts:779–812 — notification IPC handler (missing permission request)
  • electron/ipc/pr-checks.ts:275–302 — PR check notifications (same issue)
  • src/store/desktopNotifications.ts:22 — checks desktopNotificationsEnabled flag but no permission gate

Fix

Call systemPreferences.requestNotificationPermission() in the Electron main process:

  • When the user enables desktop notifications (via a new IPC call from the renderer)
  • On app startup if desktopNotificationsEnabled is already true (to fix existing users)

The method returns a promise resolving to 'granted', 'denied', or 'default', which should be surfaced back to the renderer so the UI can reflect the actual permission state.


I'll take a pass at fixing and submitting later

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions