8.2 KiB
Native OS Notification — Testing Status
Companion to TAURI_CEF_FINDINGS_AND_CHANGES.md.
This file is a quick-reference checklist: what is done, what is still needed, and how to test.
What Is Done
tauri-cef (vendored submodule)
| Change | File |
|---|---|
NotifyRenderProcessHandler wired into TauriApp::render_process_handler |
vendor/tauri-cef/crates/tauri-runtime-cef/src/cef_impl.rs |
run_cef_helper_process() uses NotifyApp (not None) |
vendor/tauri-cef/crates/tauri-runtime-cef/src/lib.rs |
notification::unregister(browser_id) called on browser close |
vendor/tauri-cef/crates/tauri-runtime-cef/src/cef_impl.rs |
Dispatch logs added ([cef-notify] dispatch / dropped) |
vendor/tauri-cef/crates/tauri-runtime-cef/src/notification.rs |
on_context_created install logs in runtime shim |
vendor/tauri-cef/crates/tauri-runtime-cef/src/notification.rs |
on_context_created install logs in helper shim |
vendor/tauri-cef/cef-helper/src/notification.rs |
Debug markers: window.__OPENHUMAN_CEF_NOTIFICATION_SHIM, __OPENHUMAN_CEF_NOTIFICATION_ORIGIN |
vendor/tauri-cef/cef-helper/src/notification.rs |
Manual test entry point: window.__openhumanFireNotification(title, opts) |
vendor/tauri-cef/cef-helper/src/notification.rs |
ensure-tauri-cli.sh reinstalls vendored CLI when tauri-cef sources are newer |
scripts/ensure-tauri-cli.sh |
tauri-plugin-notification (vendored to stop init-script conflict)
| Change | File |
|---|---|
Plugin vendored at vendor/tauri-plugin-notification/ |
app/src-tauri/Cargo.toml |
| Plugin dependency switched from git rev to local path | app/src-tauri/Cargo.toml |
.js_init_script(...) call removed from plugin init() |
vendor/tauri-plugin-notification/src/lib.rs |
Why this mattered: Without this change, the plugin injected a JS shim that forwarded new Notification(...) to http://ipc.localhost/plugin:notification|notify. That IPC always fails with 500 in third-party webviews (Slack), overwriting the CEF shim and blocking all notification delivery.
openhuman-cursor app shell
| Change | File |
|---|---|
Default notification toggle set to true |
src/notification_settings/mod.rs |
OPENHUMAN_DISABLE_SLACK_SCANNER=1 env bypass for DevTools inspection |
src/webview_accounts/mod.rs |
| Platform-specific OS notification with click detection added | src/webview_accounts/mod.rs |
macOS: mac-notification-sys + wait_for_click + std::thread::spawn |
src/webview_accounts/mod.rs |
Linux: notify-rust + wait_for_action + std::thread::spawn |
src/webview_accounts/mod.rs |
Windows: fire-and-forget fallback via NotificationExt |
src/webview_accounts/mod.rs |
notification:click Tauri event emitted with { account_id, provider } |
src/webview_accounts/mod.rs |
[notify-click] success logs promoted from debug to info |
src/webview_accounts/mod.rs |
mac-notification-sys = "0.6" added to macOS dependencies |
app/src-tauri/Cargo.toml |
notify-rust added to Linux dependencies |
app/src-tauri/Cargo.toml |
NotificationExt import scoped to #[cfg(all(feature = "cef", windows))] |
src/webview_accounts/mod.rs |
tokio::task::spawn_blocking replaced with std::thread::spawn (fixes tokio panic from CEF callback thread) |
src/webview_accounts/mod.rs |
| Scanner fallback: per-channel unread baseline, delta-based notification synthesis | src/slack_scanner/mod.rs |
What Is Still Needed
1. ✅ Slack scanner registry re-enabled
File: app/src-tauri/src/lib.rs
This fix has already been applied in this PR. ScannerRegistry is now registered in the Tauri app
state, so the scanner-driven fallback notification path is active.
The following was added to lib.rs inside tauri::Builder::default()...manage(...):
// already applied
.manage(Arc::new(slack_scanner::ScannerRegistry::new()))
With this change:
- The scanner tracks per-channel unread counts
- When a channel's unread count increases, the scanner synthesizes a native OS notification
- This is the fallback path because Slack's embedded session does not call
new Notification(...)for real incoming messages
2. Verify end-to-end with a real incoming Slack message
Once the scanner registry is registered:
- Run the app:
cd app && pnpm dev:app - Open the Slack webview — wait for Slack to load fully
- Have someone send you a Slack message from another device
- Watch the log:
tail -f /tmp/openhuman-dev-app.log | grep --line-buffered "notify-cef\|notify-click\|scanner\|unread" - Expected log sequence:
[scanner] unread delta channel=... prev=N new=M [notify-cef][<account_id>] source=... tag=... title_chars=N body_chars=M - OS toast should appear
- Click the toast → expected:
[notify-click][<account_id>] clicked provider=slack - Slack webview should come into focus (frontend routes
notification:click→setActiveAccount→activate_main_window)
3. Verify the CEF shim installs in Slack's page context
Before relying on real messages, confirm the helper shim is active via DevTools:
- Open
brave://inspect - Find the Slack page target → click Inspect
- In Console, run:
window.__OPENHUMAN_CEF_NOTIFICATION_SHIM // should be true window.__OPENHUMAN_CEF_NOTIFICATION_ORIGIN // should be the Slack URL - If both are present, the CEF helper shim installed correctly
4. Verify the manual helper trigger path end-to-end
With DevTools open on the Slack target:
window.__openhumanFireNotification("Slack CEF test", { body: "Manual trigger" })
Expected log:
[cef-notify] dispatch browser_id=N source=Window title="Slack CEF test" origin=...
[notify-cef][<account_id>] source=Window tag= silent=false title_chars=14 body_chars=13
And an OS notification toast should appear. If no toast appears, the blocker is in forward_native_notification in webview_accounts/mod.rs.
5. Clean up debug instrumentation (post-verification)
Once notifications are working reliably, remove:
window.__OPENHUMAN_CEF_NOTIFICATION_SHIMglobal markerwindow.__OPENHUMAN_CEF_NOTIFICATION_ORIGINglobal markerwindow.__openhumanFireNotificationmanual triggerwindow.__OPENHUMAN_CEF_NOTIFICATION_CONSTRUCTORsaved reference[cef-helper-notify]eprintln!calls incef-helper/src/notification.rs(or replace with properlog::debug!)
How To Run The App Correctly
The app must be started with dev:app, not tauri dev directly:
cd app && pnpm dev:app
dev:app sets CEF_PATH=$HOME/Library/Caches/tauri-cef and ensures the vendored cargo-tauri is installed. Without it, the app panics at startup in cef::library_loader with No such file or directory.
Live log location:
tail -f /tmp/openhuman-dev-app.log | grep --line-buffered "notify-cef\|notify-click\|scanner\|unread\|cef-notify"
Key Log Prefixes
| Prefix | Where | Meaning |
|---|---|---|
[cef-helper-notify] on_context_created |
renderer subprocess | shim callback fired for a new JS context |
[cef-helper-notify] installed shims |
renderer subprocess | shim installed in that context |
[cef-helper-notify] execute |
renderer subprocess | new Notification(...) called by page JS |
[cef-notify] dispatch |
browser process | notification IPC received from renderer, handler called |
[cef-notify] dropped |
browser process | notification IPC received but no handler registered |
[notify-cef][id] |
webview_accounts |
notification payload reached app, OS toast being sent |
[notify-click][id] clicked |
webview_accounts |
user clicked OS toast, emitting notification:click |
[webview-accounts] slack ScannerRegistry not in app state |
webview_accounts |
scanner registry is missing — add .manage(ScannerRegistry::new()) in lib.rs |
Frontend Side (Already Wired, No Changes Needed)
app/src/services/webviewAccountService.ts already listens for notification:click:
listen('notification:click', ({ payload }) => {
dispatch(setActiveAccount(payload.account_id));
invoke('activate_main_window');
});
No frontend changes are needed. The click routing will work once the Rust side emits the event.