#54027: fix: restore snap-compatible dbusmenu object path
Description of Change
Chromium's multiplexer refactor changed the dbusmenu object path from /com/canonical/dbusmenu to /org/chromium/DbusMenu.
Under snap strict confinement, the unity7 interface AppArmor rules only permit dbusmenu traffic on the /com/canonical/dbusmenu path:
dbus (receive)
path=/com/canonical/dbusmenu
interface=com.canonical.dbusmenu
Traffic on /org/chromium/DbusMenu is silently dropped by AppArmor (implicit deny - no audit log entry), so the desktop environment panel never receives the menu layout and the tray context menu is non-functional for every snap-confined Electron application.
The bus name half of this problem was already fixed upstream in crrev.com/c/8337991, which switched to unique D-Bus connection names. This patch fixes the remaining dbusmenu path half.
/com/canonical/dbusmenu is the conventional path used by libdbusmenu and expected by all StatusNotifierWatcher implementations. The SNI specification does not mandate a specific dbusmenu object path, so either works outside of snap confinement. Non-snap Electron apps (AppImage, deb, Flatpak, bare metal) aren't affected.
Impact
This affects every strict-confinement Electron snap that uses Tray.setContextMenu() (Slack, VS Code, Signal, etc). The tray icon appears but right-clicking produces no menu.
Why not wait for the snapd fix?
Well, a snapd fix (canonical/snapd#17415) adding /org/chromium/DbusMenu to the unity7 allowlist was merged on September 3rd and released in snapd 2.77. The problem is, Ubuntu LTS users receive snapd updates through Canonical's Stable Release Update (SRU) process, not directly from upstream. Lots of steps in between until it hits LTS. Looking at previous snapd SRU timelines for Ubuntu 24.04:
| Version | Entered -proposed |
Reached -updates |
Time in -proposed |
|---|---|---|---|
| 2.73 | Dec 5 | Jan 7 | ~33 days |
| 2.74.1 | Apr 2 | Apr 16 | ~14 days |
| 2.75.2 | May 7 | May 21 | ~14 days |
| 2.76 | Jul 8 | Jul 20 | ~12 days |
| 2.76.3 | Jul 22 | Aug 20 | ~29 days |
So in this case, snapd 2.77 has not yet entered -proposed for Ubuntu 24.04 (as of September 17th). Based on the pattern above, it could likely take 1-2 months from upstream release before it reaches users via apt upgrade. Also, to get the tray icon to work once it's in LTS, users would also need to manually update their system (or have unattended-upgrades configured) and restart Slack. Very clunky and poor user experience.
In the past I attempted to work around this from the snap packaging side by adding a custom dbus slot for org.chromium to snapcraft.yaml, but the Snap Store's automated review rejected the snap. Turns out custom dbus slots aren't permitted without a manual exception from Canonical, which is a nonstandard process that doesn't scale to every affected Electron app. Also, requesting an exception in this case isn't worthwhile either since the snapd fix is already merged upstream and the exception would become unnecessary once it reaches LTS.
However, an Electron patch ships fast (usually in the next release) and fixes the issue for every snap-confined Electron app automatically - no user action required (well, aside from updating their app), but overall a much better user experience compared to the alternative. I thought about 'well what happens when the snapd change hits LTS and people start updating?' - happily, this patch is safe to carry alongside the snapd fix: restoring /com/canonical/dbusmenu doesn't conflict with snapd adding /org/chromium/DbusMenu to the allowlist, since both paths would be permitted. So this patch just becomes redundant once snapd adoption is sufficient (which, could take a long while), at which point it can be cleanly removed, or just left for say ~6 months to allow for adoption and then removed.
Some Backing Evidence
Snap AppArmor profile confirms only the canonical path is allowed:
# From /var/lib/snapd/apparmor/profiles/snap.slack.slack
dbus (receive)
path=/com/canonical/dbusmenu
interface=org.freedesktop.DBus.Properties
member=Get*
peer=(label="{plasmashell,unconfined}"),
No rules exist for /org/chromium/DbusMenu.
StatusNotifierItem is registered, but menu path is blocked:
# Icon registered with watcher (visible in tray)
$ gdbus call --session --dest org.kde.StatusNotifierWatcher \
--object-path /StatusNotifierWatcher \
--method org.freedesktop.DBus.Properties.Get \
org.kde.StatusNotifierWatcher RegisteredStatusNotifierItems
(<[':1.150@/StatusNotifierItem']>,)
# Menu property points to /org/chromium/DbusMenu (silently blocked by AppArmor)
$ gdbus call --session --dest :1.150 \
--object-path /StatusNotifierItem \
--method org.freedesktop.DBus.Properties.Get \
org.kde.StatusNotifierItem Menu
(<objectpath '/org/chromium/DbusMenu'>,)Confirmed fix: I reinstaled the snap with --devmode (disabling AppArmor confinement) which immediately restored the context menu, proving the path is the sole remaining issue.
Affected projects
Some confirmed affected snap-confined Electron apps:
- Slack Desktop - tray icon visible but context menu non-functional
- Signal Desktop: snapcrafters/signal-desktop#459 - user had to manually edit the AppArmor profile as a workaround
- Prospect Mail: julian-alarcon/prospect-mail#420 - tray icon missing under snap
Basically, this affects snap-confined Electron apps that have upgraded to a Chromium version containing the multiplexer refactor (Chromium 151+).
Related
- Previous PR (bus name + path, closed in favor of upstream bus name fix): #52819
- Upstream bus name fix: crrev.com/c/8337991
- Chromium multiplexer refactor that introduced the change: crrev.com/c/8043132
- Chromium bug: issues.chromium.org/554905106
- snapd fix PR: canonical/snapd#17415
- snapd bug: LP#2161950
Checklist
- I have built and tested this change
- I have filled out the PR description
- I have reviewed and verified the changes
-
npm testpasses - tests are changed or added
- relevant API documentation, tutorials, and examples are updated and follow the documentation style guide
- PR release notes describe the change in a way relevant to app developers, and are capitalized, punctuated, and past tense.
Release Notes
Notes: Fixed the tray context menu not working for snap-confined apps because AppArmor blocked the /org/chromium/DbusMenu path.
Backports
Semver Impact
Semantic Versioning helps users understand the impact of updates:
- Major (X.y.z): Breaking changes that may require code modifications
- Minor (x.Y.z): New features that maintain backward compatibility
- Patch (x.y.Z): Bug fixes that don't change the API
- None: Changes that don't affect using facing parts of Electron