Skip to content

fix(desktop): register with macOS Notification Center at startup#1492

Merged
Kitenite merged 9 commits intosuperset-sh:mainfrom
zoumo:fix-notification
Feb 14, 2026
Merged

fix(desktop): register with macOS Notification Center at startup#1492
Kitenite merged 9 commits intosuperset-sh:mainfrom
zoumo:fix-notification

Conversation

@zoumo
Copy link
Copy Markdown
Contributor

@zoumo zoumo commented Feb 14, 2026

Summary

  • Fix notifications not working on macOS 26.x by registering with Notification Center at startup
  • Electron's Notification API doesn't have requestPermission() - registration happens implicitly via notification.show()
  • Shows a silent notification at startup and closes it immediately to register the app with macOS Notification Center

Problem

On macOS 26.x (Tahoe), the Superset desktop app was not appearing in System Settings > Notifications, causing:

  • No notifications delivered when tasks complete
  • No task status indicators (green progress bar) visible
  • Users unable to configure notification preferences for the app

Solution

Added code to show a silent notification at app startup, which triggers registration with macOS Notification Center:

  • App now appears in System Settings > Notifications
  • Notifications are delivered when tasks complete
  • Task status indicators work correctly

Testing

  • App appears in System Settings > Notifications on macOS 26.x
image
  • Notifications delivered when tasks complete
image
  • LSP check passed

Files Changed

  • apps/desktop/src/main/windows/main.ts - Added registration code (~28 lines)
  • docs/solutions/integration-issues/macos-notification-center-registration.md - Solution documentation

Fixes #1461

Summary by CodeRabbit

  • New Features

    • Added enhanced macOS notification support with automatic registration during app startup.
  • Bug Fixes

    • Fixed timing issues with deep link processing to ensure they are handled correctly after app initialization completes.

On macOS 26.x, the app was not appearing in System Settings > Notifications
because it never explicitly registered with Notification Center.

Electron's Notification API doesn't have a requestPermission() method.
Registration happens implicitly when notification.show() is called.

This fix shows a silent notification at startup to force registration,
then immediately closes it. The app will now appear in System Settings
and notifications will be delivered properly.

Fixes #1461
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change registers the Electron desktop app with macOS's notification center during startup and gates deep link processing until app initialization completes. This ensures the application appears in System Settings > Notifications on macOS.

Changes

Cohort / File(s) Summary
macOS notification registration
apps/desktop/src/main/index.ts
Added registerWithMacOSNotificationCenter() function to register with native macOS notification center at app ready. Expanded Electron imports to include Notification. Imported PLATFORM constant. Introduced appReady state to gate deep link processing until initialization completes, with queuing of early-arriving open-url events.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 On macOS where notifications were lost,
We registered with the system's cost,
Deep links now queue till the app's fully awake,
And notifications appear—no more mistake! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ⚠️ Unable to check for merge conflicts: Failed to fetch base branch: From https://github.com/superset-sh/superset
! [rejected] main -> main (non-fast-forward)
+ cc891c3...e2f4706 main -> origin/main (forced update)
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: registering with macOS Notification Center at startup, which directly addresses the core fix.
Description check ✅ Passed The PR description is comprehensive with clear problem statement, solution explanation, testing evidence, and proper linkage to issue #1461. It follows the template structure.
Linked Issues check ✅ Passed The PR implementation meets all three requirements from issue #1461: app now appears in System Settings > Notifications, notifications are delivered on task completion, and task status indicators (green progress bar) function correctly.
Out of Scope Changes check ✅ Passed All changes are focused on fixing macOS Notification Center registration at startup, which is directly within scope of issue #1461. The documentation file addition is also in scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch fix-notification
  • Post resolved changes as copyable diffs in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@docs/solutions/integration-issues/macos-notification-center-registration.md`:
- Around line 109-115: The Debug Mode docs use the wrong env var and command;
update the section to use SUPERSET_DEBUG=1 and the desktop run command (replace
ELECTRON_DEBUG_NOTIFICATIONS=1 bun run dev with SUPERSET_DEBUG=1 bun run
desktop) so it matches the debug implementation (see the SUPERSET_DEBUG usage in
apps/desktop/src/shared/debug.ts).
🧹 Nitpick comments (1)
apps/desktop/src/main/windows/main.ts (1)

183-209: Wrap the registration block in try-catch for resilience.

This registration is best-effort and runs during MainWindow() startup. If new Notification() or .show() throws unexpectedly (e.g., on a CI/headless environment, or a future Electron version change), it would propagate and break window initialization. A defensive try-catch keeps the critical startup path safe.

Proposed fix
 // Register with macOS Notification Center on startup
 // This ensures the app appears in System Settings > Notifications
 // Fixes https://github.com/superset-sh/superset/issues/1461
 if (PLATFORM.IS_MAC && Notification.isSupported()) {
+  try {
     const registrationNotification = new Notification({
       title: productName,
       body: " ",
       silent: true,
     });

     let handled = false;
     const cleanup = () => {
       if (handled) return;
       handled = true;
       registrationNotification.close();
     };

     registrationNotification.on("show", () => {
       cleanup();
       console.log("[notifications] Registered with Notification Center");
     });

     // Fallback timeout in case macOS doesn't fire events
     setTimeout(cleanup, 1000);

     registrationNotification.show();
+  } catch (error) {
+    console.warn("[notifications] Failed to register with Notification Center:", error);
+  }
 }

Comment thread docs/solutions/integration-issues/macos-notification-center-registration.md Outdated
Update debug command from ELECTRON_DEBUG_NOTIFICATIONS=1 to
SUPERSET_DEBUG=1 to match the actual debug implementation in
apps/desktop/src/shared/debug.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@docs/solutions/integration-issues/macos-notification-center-registration.md`:
- Around line 126-136: Update the Electron Notification Events Reference table's
"close" row to clarify platform reliability: change the Description for the
`close` event from "Notification closed" to something like "Notification closed
(may not be emitted on all platforms — reliability varies, see platform notes)"
or add a brief caveat immediately after the table explaining that the `close`
event is not guaranteed in all scenarios (notably some Windows edge cases);
ensure the change references the `close` event label in the "Electron
Notification Events Reference" table so readers can find the note.

Comment thread docs/solutions/integration-issues/macos-notification-center-registration.md Outdated
On macOS 26.x, the app was not appearing in System Settings > Notifications
because it never explicitly registered with Notification Center.

Electron's Notification API doesn't have a requestPermission() method.
Registration happens implicitly when notification.show() is called.

This fix shows a silent notification at startup to force registration,
then immediately closes it. The app will now appear in System Settings
and notifications will be delivered properly.

Fixes #1461
Update debug command from ELECTRON_DEBUG_NOTIFICATIONS=1 to
SUPERSET_DEBUG=1 to match the actual debug implementation in
apps/desktop/src/shared/debug.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@docs/solutions/integration-issues/macos-notification-center-registration.md`:
- Around line 32-33: Change the definitive phrasing "macOS 26 changes — New
'Liquid Glass' notification architecture may require more explicit registration"
to a neutral observation; for example, replace "New 'Liquid Glass' notification
architecture" with "an observed behavior change in macOS 26.x (sometimes
referred to as 'Liquid Glass')" and use wording like "may require" or "appears
to require" instead of asserting the root cause; if you have an authoritative
source, add a citation after the sentence, otherwise keep the softer language
and update the heading text "macOS 26 changes" to "Observed macOS 26 behavior"
or similar.

Comment on lines +32 to +33
4. **macOS 26 changes** - New "Liquid Glass" notification architecture may require more explicit registration

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Rephrase speculative “Liquid Glass” root cause as an observation.
The current wording implies a confirmed architectural change. Consider softening to “observed behavior change in macOS 26.x” unless you can cite an authoritative source.

🤖 Prompt for AI Agents
In `@docs/solutions/integration-issues/macos-notification-center-registration.md`
around lines 32 - 33, Change the definitive phrasing "macOS 26 changes — New
'Liquid Glass' notification architecture may require more explicit registration"
to a neutral observation; for example, replace "New 'Liquid Glass' notification
architecture" with "an observed behavior change in macOS 26.x (sometimes
referred to as 'Liquid Glass')" and use wording like "may require" or "appears
to require" instead of asserting the root cause; if you have an authoritative
source, add a citation after the sentence, otherwise keep the softer language
and update the heading text "macOS 26 changes" to "Observed macOS 26 behavior"
or similar.

@Kitenite
Copy link
Copy Markdown
Collaborator

Thanks @zoumo, I removed the doc and moved the logic to start instead of per window but otherwise looks great!

@Kitenite Kitenite merged commit e2f4706 into superset-sh:main Feb 14, 2026
5 of 6 checks passed
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/main/index.ts (1)

299-304: ⚠️ Potential issue | 🟡 Minor

Minor race: a deep link arriving during processDeepLink on Line 300 can be lost.

If an open-url event fires while await processDeepLink(pendingDeepLinkUrl) yields (Line 300), the handler (Line 134) overwrites pendingDeepLinkUrl with the new URL. Then Line 301 nulls it out, and the new URL is never processed.

This is an unlikely edge case, but if you'd like to close it:

Possible fix
-		if (pendingDeepLinkUrl) {
-			await processDeepLink(pendingDeepLinkUrl);
-			pendingDeepLinkUrl = null;
-		}
-
-		appReady = true;
+		appReady = true;
+		if (pendingDeepLinkUrl) {
+			const url = pendingDeepLinkUrl;
+			pendingDeepLinkUrl = null;
+			await processDeepLink(url);
+		}

By setting appReady = true first, any subsequent open-url events will be processed directly via processDeepLink (Line 132) instead of being queued and potentially overwritten.

🧹 Nitpick comments (1)
apps/desktop/src/main/index.ts (1)

97-122: Consider clearing the fallback timeout on successful cleanup.

When the "show" event fires promptly, the 1-second setTimeout still lingers. Storing the timer ID and clearing it inside cleanup is a small improvement.

Also, body: " " (a single space) means users may briefly see a notification toast before it's closed. If macOS allows it, an empty string or \u200B (zero-width space) might be less noticeable—though if an empty body prevents registration, the current approach is the right trade-off.

Suggested tweak
 function registerWithMacOSNotificationCenter() {
 	if (!PLATFORM.IS_MAC || !Notification.isSupported()) return;
 
 	const registrationNotification = new Notification({
 		title: app.name,
-		body: " ",
+		body: "\u200B",
 		silent: true,
 	});
 
 	let handled = false;
+	let fallbackTimer: ReturnType<typeof setTimeout> | null = null;
 	const cleanup = () => {
 		if (handled) return;
 		handled = true;
+		if (fallbackTimer) clearTimeout(fallbackTimer);
 		registrationNotification.close();
 	};
 
 	registrationNotification.on("show", () => {
 		cleanup();
 		console.log("[notifications] Registered with Notification Center");
 	});
 
 	// Fallback timeout in case macOS doesn't fire events
-	setTimeout(cleanup, 1000);
+	fallbackTimer = setTimeout(cleanup, 1000);
 
 	registrationNotification.show();
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] Notifications and task status not working on macOS 26.2

2 participants