Repository navigation
Fix notification activation and macOS updates after Electron 44 upgrade - #3692
Closed
salemsayed wants to merge 1 commit into
Closed
salemsayed wants to merge 1 commit into
salemsayed wants to merge 1 commit into
Conversation
salemsayed
force-pushed
the
fix/appimage-notification-activation
branch
from
September 15, 2026 00:17
78f461c to
02057cd
Compare
salemsayed
marked this pull request as ready for review
September 15, 2026 00:37
Collaborator
|
Contributor
Author
SawyerHood
added a commit
that referenced
this pull request
Oct 1, 2026
…pdate requirement (#4483) ## Human comments ## What was wrong Replaces #3692, which the stale-PR automation closed without a review. This branch is rebased onto `b23150d88` and re-verified from scratch. **On Linux Wayland, clicking a BB desktop notification opens the right thread but leaves BB minimized or behind other windows.** There are two causes, and both are still present on current `main`: 1. The AppImage bundles an old `libnotify.so.4` in `usr/lib`. It shadows the system library and has no activation-token API (`notify_notification_get_activation_token`). Electron 44 can only forward the compositor's xdg-activation token when that API exists, so GNOME and KWin refuse the focus request. The running 0.43.5 nightly maps `/tmp/.mount_bb_*/usr/lib/libnotify.so.4.0.0`, not the system 0.8.8. 2. The click handler in `plugins/push-notifications/client.ts` only calls renderer `window.focus()`. That can't un-minimize or raise a Wayland toplevel. Separately, `generate-version-feed.mts` still publishes `minimumSystemVersion: null` even though `electron-builder.config.json` requires macOS 13.0.0. The updater therefore can't keep macOS 12 users off releases that won't launch for them. ## What changed - `patches/app-builder-lib@26.15.7.patch`: AppImage staging renames the bundled `libnotify.so.4` to unversioned `libnotify.so`. Electron tries the system's versioned library first and falls back to the bundled copy. `smoke-linux-appimage-lifecycle.mjs` asserts this layout. - `desktop-window-focus.ts`, `main.ts`, `preload.ts`, `desktop-window-command-ipc.ts`, `desktop-contract/info.ts`: new payload-free `focusWindow()` preload method and IPC. Only a registered application webContents may call it, and it restores, shows and focuses that sender's own window. - `push-notifications/client.ts`: on Linux desktop, a notification click also calls `bbDesktop.focusWindow()` when available. `window.focus()` and routing are unchanged. Older shells without the method keep the previous behavior. Web and macOS are unchanged. - `generate-version-feed.mts`: macOS JSON and YAML feeds publish `minimumSystemVersion: 22.0.0` (Darwin for macOS 13) and keep the other YAML metadata. - `apps/desktop/package.json`: `test` installs Electron's lazy runtime first, so parallel desktop tests don't race to download it. No server/daemon wire change and no `HOST_DAEMON_PROTOCOL_VERSION` bump. ## How you verified **Before/after on real desktops.** AppImages were built from upstream `main` `b23150d88` and from this branch. Each was run in a fresh Ubuntu 26.04 QEMU/KVM guest on native Wayland: GNOME Shell 50.1 and KDE Plasma/KWin 6.6.6, both with system libnotify 0.8.8. Each case launched BB fresh against an isolated server built from the same commit, then either minimized BB or covered it with another app's window. A real Codex turn on "Notification target" produced the notification, and the QEMU pointer clicked it. Focus was checked in Electron, in the renderer (`document.hasFocus()`), and in the compositor (the focused window's PID from a GNOME Shell extension or KWin script). | Case | GNOME 50.1 | KDE Plasma 6.6.6 | | --- | --- | --- | | `main`, BB minimized | Opens thread, **stays minimized** | Opens thread, **stays minimized** | | `main`, BB behind another window | Opens thread, **stays behind** | Opens thread, **stays behind** | | This PR, BB minimized | Restored, focused, on thread | Restored, focused, on thread | | This PR, BB behind another window | Raised, focused, on thread | Raised, focused, on thread | | Control: system libnotify, no native focus request | Stays minimized | Stays minimized | | Control: native focus request, legacy libnotify forced via `LD_PRELOAD` | Focus refused; Shell posts "“Notification target” is ready" | Focus refused; task marked as demanding attention | The two controls show that both halves of the fix are needed. Process maps confirm which libnotify each run loaded: `main` loads the AppImage's `libnotify.so.4.0.0`, and this PR loads `/usr/lib/x86_64-linux-gnu/libnotify.so.4.0.0`. <details open> <summary>GNOME, BB minimized (left: main, right: this PR)</summary>  </details> <details open> <summary>KDE, BB minimized (left: main, right: this PR)</summary>  </details> <details> <summary>GNOME and KDE, BB behind another window</summary>   </details> <details> <summary>Stills: notification shown and result after click</summary>   </details> MP4s, the per-case summary and the method are in [this gist](https://gist.github.com/salemsayed/4a2e59ad2a48180531985d7d20b93138). **Tests** (Node 22.19.0 per `.nvmrc`): `pnpm exec turbo run test typecheck --filter=@bb/desktop --filter=bb-plugin-push-notifications --filter=@bb/desktop-contract` passes 12/12 tasks: desktop 454 passed with 1 existing skip, push notifications 24, desktop contract 22. Under Node 26, `client.test.ts` fails on `main` too (`localStorage` is undefined), so that failure is not from this change. `turbo run desktop:build:linux --filter=@bb/desktop` passes, and the extracted AppImage contains `usr/lib/libnotify.so -> libnotify.so.4.0.0` with no `libnotify.so.4`. The feed change is covered by `desktop-version-feed.test.ts`. **Not tested:** signed macOS GUI notifications and updater install on macOS 12, standalone Xorg, and other Linux distributions. On Wayland, focus still needs compositor xdg-activation support and a system libnotify of 0.7.10 or later. Without one, BB falls back to the bundled library: notifications still open the thread, but BB can't take focus. > AGENT GENERATED 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: SawyerHood <sawyerjhood@gmail.com>
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.
Human comments
What was wrong
Electron 44.3.0 and SQLite 13 are already merged in #3659. This PR fixes the remaining AppImage notification and macOS updater gaps. The AppImage still bundles an old libnotify that shadows the system library and loses Wayland activation-token support; BB's click handler still relies on renderer
window.focus()without a native restore/show/focus request; and the custom macOS update feed still publishes no minimum system version despite the app now requiring macOS 13. Our branch already includes #3659 and makes no further Electron or SQLite upgrade.What changed
minimumSystemVersion: null.window.focus()and add a Linux-only native request. Payload-free IPC checks the live application-webContents registry and restores/shows/focuses only the sender's window. The optional preload contract retains old-shell compatibility; routing is unchanged.libnotify.so. Electron first tries system versioned libraries, then this fallback. The lifecycle smoke checks that packaging neither shadows versioned libraries nor drops the fallback.No server/daemon wire change, protocol bump or additional SQLite upgrade.
How you verified
The runtime upgrade alone did not resolve the observed failure: an earlier Electron 44 diagnostic run with the native BB request restored the GNOME window and opened the thread, but Electron, renderer and compositor captures still showed it unfocused while the legacy library was bundled. Using the system library made that click focus correctly. The final packaged results below verify the combined fixes. The earlier renderer-only control on Electron 42 also left the target minimized and unfocused, demonstrating why the BB native request is needed alongside runtime token support.
Application commit
02057cdfe6538dde34456ef82bb20a2ad99abdd6, rebased on96fddad26. Final AppImage SHA256:8a5ed4d636e3c19244e1e685dc740fe652e06a786350c92a2581519f407798da.git diff --checkpass.useBbNavigatepath ran. Electron, renderer and compositor focus were independently captured; screenshots inspected. Process maps confirm system libnotify. GNOME also passes the source-controlled AppImage lifecycle smoke, including owned-server survival after GUI mount removal.Before rebasing, the equivalent package also passed KDE XWayland, owned runtime startup in both VMs, and legacy-fallback delivery/restoration/navigation with the system library unavailable. Those additional cases were not repeated on the final artifact. The existing desktopName warning remains; VM fixtures include a BB desktop entry, so default association on every distribution is not established.
Costs and compatibility
The macOS cutoff and SQLite runtime requirements below were introduced by #3659. This PR adds the matching update-feed requirement; its Linux-specific maintenance cost is the packager patch and system-library dependency for Wayland focus.
Background: Electron upgrade benefits and benchmarks, already delivered by #3659
These measurements compare Electron 41.7 with 44.3 using identical BB code and data. They are benefits of the runtime upgrade already merged in #3659, not performance gains produced by this PR's notification or updater changes. They remain here as supporting background for the runtime choice.
Measured with identical BB code and data, changing only Electron 41.7.0 to 44.3.0:
Full report, exact harness, raw samples and uncertainty intervals. Linux i5-11400 / UHD 730, native Wayland, same application archive/server, 3 projects / 120 threads / 20,345 events. Six paired launches per profile condition and version, alternating order; three full Speedometer runs per version, ten iterations each. One pair was repeated because a window lost focus, with original samples retained. Steady CPU was effectively unchanged. These are local GUI/engine measurements, not Mac, FUSE-mount, backend-startup or model-inference benchmarks.
There are specific upstream mechanisms behind the performance case: startup snapshots and cached preload bytecode without blocking startup IPC, plus ThinLTO. Electron's separate Linux experiment measured
app.readyat 197.8 → 148.7 ms with snapshots (24 samples/build), and Speedometer at 22.08 → 24.99 with ThinLTO (+13.2%). These are upstream results, not BB measurements; they do not establish how much of BB's combined improvement comes from each patch. Updated 42 releases also include these improvements. V8 builtins PGO is excluded from the claimed delta because it was already backported to 41.Other concrete returns:
Why retain 44 rather than stop at 42? As of September 15, the official schedule gives 42 another 35 support days (October 20), 43 another 112 (January 5), and 44 another 168 (March 2). 41 is already end-of-life. The current stable line receives all fixes; the oldest supported line receives security fixes only. 43 remains a reasonable temporary choice if macOS 12 support is mandatory. Scheduled dates can change.