quine-linux/docs/chromium-dbus-singleton-activation.md
Philip Peterson 30d15773a6 Document iMac19,2 speaker silence and Chromium D-Bus activation gap
Adds docs/imac19-2-speaker-fix.md: internal speakers produce no sound
despite correct HDA-level plumbing (unmuted volume, enabled pin, clean
device open). Traces the likely cause to uninitialized external TAS5764L
amp chips and a CS42L83 companion codec behind the CS8409, via sibling-
model prior art (rojoxstar/imac19-2-cs8409-linux, egorenar/snd-hda-codec-
cs8409#31, network-garden-lab's Fedora-specific iMac18,3 patch). No fix
is packaged yet given the amp-register damage risk and the bigger lift
of patching in-tree kernel source rather than an out-of-tree module.

Also adds docs/chromium-dbus-singleton-activation.md and a new "Software
fork directions" README section indexing forward-looking fork/patch
write-ups separately from the hardware-specific patches already shipped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 23:20:12 -08:00

4.4 KiB

Chromium D-Bus singleton activation (future fork direction)

Not started -- this is a write-up of a problem observed on this machine and the shape a fix would take in a Chromium fork, kept here so the idea isn't lost before anyone has time to act on it. Unlike docs/patched-anaconda-installer.md, there is no fork yet.

Symptom

flatpak run org.chromium.Chromium, launched from KDE Plasma's task manager, appeared to hang indefinitely. What actually happened: the first launch was slow to map its first window (cold profile/cache, GPU process init). Re-clicking the launcher icon while waiting didn't focus/wait on that in-progress launch -- it ran the .desktop file's Exec= line again. This repeated a handful of times, producing five fully independent Chromium process trees (each with its own zygote, GPU process, network/storage service, and renderers) all fighting over the same CPU cores, disk cache, and /dev/dri/renderD128, which made every one of them even slower to start -- compounding into what looked like a permanent hang.

Root cause

Two things stacked:

  1. KDE's task manager has no way to know a launch is in flight without the freedesktop startup-notification protocol or an existing window to match against. With neither available yet, a second click is indistinguishable from a fresh launch request.
  2. Chromium doesn't use D-Bus activation. On Linux it implements its own legacy singleton check (a lock file + Unix domain socket handshake, see chrome/browser/process_singleton_posix.cc upstream) that predates org.freedesktop.Application. That handshake is timeout-based: if the already-running instance doesn't answer fast enough (because it's still starting up, or because Flatpak's per-launch sandbox namespacing gets in the way of the socket), the new process assumes there's no existing instance and cold-starts a full second browser instead of forwarding the "open a window" request.

Neither KDE nor Flatpak are missing a check they're supposed to run themselves -- both already fully support the standard fix (D-Bus activation: DBusActivatable=true in the .desktop file + an org.freedesktop.Application implementation), and other well-behaved Flatpak apps get correct, invisible single-instance behavior for free through it. Chromium (and Electron apps generally) just never adopted that contract, because the existing singleton code is shared, cross-platform logic that already works well enough on Windows/macOS without it.

Direction for a fork

  • Add a Linux-only org.freedesktop.Application implementation to Chromium's browser-process startup, gated behind BUILDFLAG(IS_LINUX) (excluding ChromeOS), that responds to Activate/Open D-Bus calls the same way the existing process-singleton IPC responds to a second launch today.
  • Ship a matching <app-id>.service file so flatpak run (or a native desktop launch) can be delivered via bus activation instead of always exec'ing a fresh chrome binary; wire DBusActivatable=true into the .desktop file.
  • Keep the existing lock-file/socket mechanism as the fallback for non-D-Bus environments (still needed for other embedders, e.g. CEF).
  • Flatpak manifest side: the sandbox needs --own-name=<app-id> (or the equivalent finish-args) for the bus name the service file activates, so this doesn't depend on the fragile shared-socket path across sandbox namespaces at all.

Why this is genuinely a fork, not just a patch to carry

Chromium's process-singleton code is shared across all desktop platforms; Linux-specific D-Bus activation is new surface area with its own maintenance cost, and upstream has historically been conservative about platform-specific branches in that file. Realistic expectation: this stays a downstream patch (in the vein of what Vivaldi/Brave carry) rather than something likely to land upstream quickly, so plan for it to need rebasing across Chromium version bumps.

Stopgap in use today

No fork exists yet, so the actual fix on this machine is external to Chromium: wrap the launcher's Exec= in an flock-guarded script so a second launch blocks (or no-ops) on a lockfile instead of racing the first instance's cold start, and set StartupNotify=true / correctStartupWMClass on the .desktop file so KDE's task manager shows a busy state instead of silently permitting a duplicate launch.