Skip to content

Fix notification activation and macOS updates after Electron 44 upgrade - #3692

Closed
salemsayed wants to merge 1 commit into
get-bb:mainfrom
salemsayed:fix/appimage-notification-activation
Closed

salemsayed wants to merge 1 commit into
get-bb:mainfrom
salemsayed:fix/appimage-notification-activation

Conversation

@salemsayed

@salemsayed salemsayed commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

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

Gap remaining after #3659 This PR adds
Electron 44 supports Wayland activation tokens, but the AppImage's bundled old libnotify prevents using the system library's support. Prefer system versioned libnotify while retaining the bundled unversioned fallback.
Clicking a notification can navigate while leaving BB minimized or unfocused. An additive Linux native request that restores, shows and focuses only the notification's owning window.
The macOS app requires version 13, but the custom JSON feed has minimumSystemVersion: null. Publish the equivalent Darwin 22.0.0 requirement in JSON and YAML update feeds for updater compatibility checks.
  • Keep 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.
  • Patch app-builder-lib's AppImage staging to expose legacy libnotify as unversioned 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.
  • Publish Darwin 22.0.0 in JSON and YAML macOS update feeds, matching Upgrade Electron to 44.3.0 with compatible bundled SQLite #3659's macOS 13 minimum while preserving other YAML metadata.
  • Install Electron's lazy development runtime before parallel desktop tests to avoid competing downloads.

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 on 96fddad26. Final AppImage SHA256: 8a5ed4d636e3c19244e1e685dc740fe652e06a786350c92a2581519f407798da.

  • CI passes: build/typecheck/lint, server, app, integration, packages, Linux/macOS bb-app package smoke and PR gates. Mobile E2E and Node compatibility jobs were skipped. The Mac smoke runs the Node package, not signed Electron notifications.
  • Local Turbo: 58/58 tasks; 440 tests passed and one existing skip (desktop 334, notifications 25, launcher 81), with typechecks and AppImage packaging. Includes native SQLite regression and packaged SQLite/offline npm smoke. Frozen install and git diff --check pass.
  • Final AppImage, Ubuntu 26.04 QEMU/KVM native Wayland: GNOME 50.1 and KDE Plasma/KWin 6.6.6 each pass background-window and minimized notification clicks, correct thread, restored focus, reload and thread-read state. 4/4 tested scenarios. Both old 41.7 minimized controls restored/navigated but failed focus.
  • Original Omarchy host: correct BB instance, hidden restoration and cross-workspace activation, 3/3 scenarios. A local frameless guard misread flattened process arguments; its lock was held temporarily to stop it closing test windows. BB kept its normal desktop identity. No installed app or desktop configuration changed.
  • Actual agent completions generated notifications; pointer input clicked them. The real callback/preload/useBbNavigate path 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.

  • macOS 12 is dropped by Electron 44 / Upgrade Electron to 44.3.0 with compatible bundled SQLite #3659. Users must upgrade the OS or retain an older release; this PR adds updater protection. BB already ships arm64-only, and Apple lists the original M1 Macs as Ventura-compatible.
  • macOS notifications require signing from Electron 42 onward. A signed Mac smoke remains outstanding.
  • Older Linux: Upgrade Electron to 44.3.0 with compatible bundled SQLite #3659's SQLite x64 prebuild requires glibc 2.34+ and GLIBCXX_3.4.29. Older systems need compatible native builds.
  • Download/memory cost: the integrated AppImage grows 178.23 → 191.23 MB (+13.00 MB / 7.3%); that includes BB/SQLite changes, not just Electron. Measured private memory grows 2.8%.
  • Wayland: activation needs compositor support and libnotify token support (0.7.10+). The bundled fallback delivers notifications and opens threads but cannot reliably activate a window. The pinned packager patch remains maintenance work.
  • Web/mac retain the renderer focus attempt; mobile WebViews remain excluded and do not embed Electron. Physical macOS/mobile and standalone Xorg remain untested.
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:

Measurement 41.7 44.3 Change
GUI startup, fresh profile / existing server 2,611 ms 2,373 ms 9.1% less time
GUI startup, warm profile / existing server 2,378 ms 2,043 ms 14.1% less time
Repeated thread switching, warm profile 197 ms 154 ms 21.9% less time
Speedometer 3.1 13.73 19.01 38.5% higher score
Desktop private memory, backend excluded 407.6 MiB 419.1 MiB 11.5 MiB / 2.8% more

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.ready at 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.

AGENT GENERATED

@salemsayed
salemsayed force-pushed the fix/appimage-notification-activation branch from 78f461c to 02057cd Compare September 15, 2026 00:17
@salemsayed salemsayed changed the title Upgrade Electron to 44 and fix Linux notification activation Fix AppImage notification activation and desktop update compatibility Sep 15, 2026
@salemsayed
salemsayed marked this pull request as ready for review September 15, 2026 00:37
@salemsayed salemsayed changed the title Fix AppImage notification activation and desktop update compatibility Fix notification activation and macOS updates after Electron 44 upgrade Sep 15, 2026
@SawyerHood

Copy link
Copy Markdown
Collaborator

This is an automated message. We have closed this pull request because it has been open for more than two weeks.

@salemsayed

Copy link
Copy Markdown
Contributor Author

Superseded by #4483: rebased onto current main (b23150d) and re-verified with before/after recordings on GNOME 50.1 and KDE Plasma 6.6.6 Wayland. Current main still loses focus on notification click.

AGENT GENERATED

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>

![GNOME
minimized](https://gist.githubusercontent.com/salemsayed/4a2e59ad2a48180531985d7d20b93138/raw/gnome-minimized.gif)
</details>

<details open>
<summary>KDE, BB minimized (left: main, right: this PR)</summary>

![KDE
minimized](https://gist.githubusercontent.com/salemsayed/4a2e59ad2a48180531985d7d20b93138/raw/kde-minimized.gif)
</details>

<details>
<summary>GNOME and KDE, BB behind another window</summary>

![GNOME
background](https://gist.githubusercontent.com/salemsayed/4a2e59ad2a48180531985d7d20b93138/raw/gnome-background.gif)

![KDE
background](https://gist.githubusercontent.com/salemsayed/4a2e59ad2a48180531985d7d20b93138/raw/kde-background.gif)
</details>

<details>
<summary>Stills: notification shown and result after click</summary>

![GNOME
grid](https://gist.githubusercontent.com/salemsayed/4a2e59ad2a48180531985d7d20b93138/raw/gnome-minimized-grid.png)

![KDE
grid](https://gist.githubusercontent.com/salemsayed/4a2e59ad2a48180531985d7d20b93138/raw/kde-minimized-grid.png)
</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>
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.

2 participants