Skip to content

Add a macOS menubar-only variant of whatRust - #28

Merged
karem505 merged 7 commits into
karem505:masterfrom
janbridley:feat/menubar-app
Oct 22, 2026
Merged

karem505 merged 7 commits into
karem505:masterfrom
janbridley:feat/menubar-app

Conversation

@janbridley

@janbridley janbridley commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

This pull request adds support for a menubar popup window on macOS, mirroring the main pane window but anchored to the menu bar icon. I've also added support to make the menu bar the only pane, so users can decide whether they want the desktop app, the menubar app, or both. Please let me know if this seems suitable for adoption in the main repo, or if you'd like any changes!

@karem505 karem505 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for this, @janbridley. A menu bar mode suits a lightweight client, and the stealth approach (alpha 0, click-through, kept ordered in so WebKit doesn't suspend the page) is a clever answer to WhatsApp dropping its socket. I've reviewed it against current master (v0.6.6). There are a few behaviour problems to fix first, and a rebase is needed.

Blocking

  1. Two live sessions on the same account in popup mode. With menubar_popup on and menubar_only off, the first tray click creates wa-menubar. It loads web.whatsapp.com into the same data store as the first account's window (apply_isolation with that account, and the default store for default). It then stays alive forever, stealthed. So two WhatsApp Web instances share one session's storage. WhatsApp Web normally reacts to that with "WhatsApp is open in another window → Use here", and one of the two instances goes dead. Did you test with the main window and the popup both loaded? Even if it does work, every message would then be notified twice: Recent de-duplicates per window label, so wa-default and wa-menubar both raise a toast. I think the popup should reuse the account's webview rather than run a second one. Alternatively, popup mode could be allowed only when the account window isn't loaded, as in menubar-only mode.

  2. menubar_popup defaults to true. Settings is #[serde(default)], so on upgrade every existing macOS user's tray click silently switches from "raise the window" to the popup. That also triggers (1). Please default it to false so it's opt-in.

  3. Unconditional NSProcessInfo activity. beginActivityWithOptions(UserInitiatedAllowingIdleSystemSleep) is held for the process lifetime on every macOS install, in every mode. That disables App Nap for all users, which costs battery. Please scope it to menu-bar-only mode, where the window is never truly visible. If it's needed in the normal window mode too, that deserves its own PR with evidence that the socket drops without it.

  4. Unread attribution. The popup mirrors accounts.first(), but set_unread attributes wa-menubar's count to ActiveAccount. With several accounts, the popup's unread count lands on whichever account was last focused. Both should use the same account; storing the mirrored account id at creation and using it in set_unread fixes this.

Needs updating for current master

The branch is based on 866e33b, and several things it touches have changed since:

  • Links. Account windows now use on_new_window with route_new_window (#30): web, mailto and tel links go to the OS, and wa.me/invite links stay in-app. They also handle whatsapp:// deep links via links.rs (#23). The popup's builder only has the old on_navigation, so links clicked in the popup won't open. Please build the popup through the same helper as account windows, or share the handler.
  • User agent. On macOS, account windows now use user_agent(), which reports the system's Safari version so WhatsApp offers calls (#15). The popup hard-codes CHROME_UA.
  • Downloads and media. enable_webview_media and the download handler (#21) changed. Again, reusing the account-window construction path avoids drift.
  • set_unread now takes a settled flag and drives the unread fallback (notify::unread_increased). The attribution change needs to slot into that.
  • Settings UI was redesigned in #21 (GNOME-style grouped rows). The two checkboxes need porting to the new markup.
  • ACL. wa-menubar does match the main-remote capability (wa-*), so IPC works. A test in ipc_acl_tests.rs asserting that would be good.

Smaller points

  • Multi-account. menubar_only destroys every account window and reaches only the first account: other accounts get no notifications, and the tray's acct: items all open the same popup. Either restrict menubar-only mode to a single account, or say so clearly next to the setting.
  • Toggle on, then off. settings::apply reopens account windows with start_minimized as the hidden flag. Turning menu-bar-only off from the popup could therefore leave you with no visible window. Showing the active account would be safer.
  • macOS check in Settings. .mac-only relies on a UA regex in the settings window. A small platform field from get_settings (or navigator.platform) is less brittle.

Testing

The core macOS behaviour can't be covered by CI here. What would help most is a short screen recording or a note covering: the popup and main window both loaded at once (item 1), menu-bar-only mode surviving an hour in the background with notifications still arriving, and lock/unlock while the popup is open.


Generated by Claude Code

@janbridley

janbridley commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

After re-reviewing, I don't know that it makes sense to support a menu bar + window mode - it's a lot of complexity for a somewhat ambiguous feature. Menu bar mode is now exclusive with the standard window mode, so users can choose whichever makes more sense for them. All review comments have been addressed. Note that the App Nap setting is UserInitiatedAllowingIdleSystemSleep, so the machine still sleeps/idles/times out correctly in menu bar mode, we just make sure that socket never gets dropped when the window is stealthed. I also removed the current stealth hack with a more robust OS-Native variant, which has existed since OSX14 - this version is very old but still above the project minimum of OSX12.1 so I disable the menu bar options for unsupported OS versions. The result is even less cpu/power usage.

Menubar-only

Note I blocked out my messages pane in the renders to avoid doxxing myself. Everything renders correctly.

Screenshot 2026-10-21 at 9 41 56 AM

Window

Screenshot 2026-10-21 at 9 41 37 AM

Settings

image

@karem505
karem505 merged commit b4b0331 into karem505:master Oct 22, 2026
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