Repository navigation
[Bug]: SnapShots never include app text for Flatpak and GTK4 apps on Linux #12597
Description
Activity
Thanks for the unusually complete report — compositor vs AT-SPI PIDs, xa11y vs libatspi dumps, and two independent failure modes with the same calls
SnapShotAccessibility.tsmakes.Confirmed on current
main. This is a real Linux SnapShot accessibility lookup/matcher bug. The screenshot path is fine; Include app text is dropped silently when the reader cannot bind a window.On GNOME the capture PID comes from the compositor (
window.get_pid()inapps/desktop/gnome-extension/extension.js) and is passed throughDesktopSnapShot.tsintoreadCapturedWindowAccessibility. On Linux that function only doesApp.byPid(active.owner.processId). There is no fallback. Misses are swallowed in the worker (run().catch(() => undefined)), so the attachment still hasappName/windowTitleand no accessibility payload.That matches both of your cases:
1. Flatpak — compositor PID ≠ AT-SPI PID
The window owner is the app. The AT-SPI registry lists the tree under Flatpak’s
xdg-dbus-proxy.App.byPid(appPid)raisesXA11Y_SELECTOR_NOT_MATCHED;App.byPid(proxyPid)finds the named window. Because we never fall back toApp.list(), every Flatpak capture loses app text.WindowsForegroundFocusWorkeralready doesbyPid→App.list(), but it still filterscandidate.pid === target.processId, so that pattern would not fix this. xa11y’s own pytest helper already documents the same class of bug (“the process that registers with the accessibility API is not the one you launched”) and matches PID or name.2. GTK4 — unnamed node fails the title gate
findAccessibleWindowinapps/desktop/src/snapShot/snapShot.tsrequires a nonempty title match and bounds (±2). Tests currently reject untitled windows by size alone. For System Monitor the PID and size match, but xa11y returns{ role: "group", name: null }while libatspi still sees a namedframe. The title gate never matches.This is the same matcher family as #10896 (macOS Chrome title suffix) and a cousin of #12103 / #12524 (macOS invalid PID), but those fixes do not cover Linux AT-SPI.
Next step
We can fix both in t3code without waiting on xa11y:
- When
byPidfinds nothing, fall back toApp.list()and reuse the existing title+size matcher. Do not require the compositor PID to equal the AT-SPI PID. - When a PID-scoped lookup has exactly one window whose bounds match, accept it even if
nameis empty (or walk one anonymousgroupwrapper). Keep rejecting ambiguous size-only matches. - Add regression tests for both cases.
The GTK4
frame→ unnamedgroupmapping is still worth an xa11y follow-up, but it should not block the matcher workaround.No workaround on our side today. Docs already say GNOME browsers need toolkit accessibility and a restart; that is necessary but not sufficient here.
- When
- addedacceptedfeature request acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.via-triageFiled through npx t3 triageFiled through npx t3 triage
on Sep 19, 2026 Taking this — working on a fix.
Before submitting
Area
apps/desktop
Steps to reproduce
org.gnome.desktop.interface toolkit-accessibilityset totrue.app.zen_browser.zen) and take a SnapShot of it.Expected behavior
Both attachments carry accessibility data. Both apps expose a full tree on the AT-SPI bus; Zen's has about 1500 elements.
Actual behavior
Both captures arrive with
appNameandwindowTitleonly. The screenshot, flash and animation are fine, and nothing is logged. There are two separate causes. I checked both by calling the bundled@crowecawcaw/xa11ynative module directly from Node, with the same callsSnapShotAccessibility.tsmakes.1. Flatpak apps: the window's PID is not the PID AT-SPI reports.
readCapturedWindowAccessibilitydoesApp.byPid(active.owner.processId). For a Flatpak app the compositor reports the app's own process, but the app reaches the accessibility bus through Flatpak'sxdg-dbus-proxy, so the AT-SPI registry lists the tree under the proxy's PID:There is no fallback, so every Flatpak app ends up without accessibility data.
2. GTK4 apps: the window comes back without a name.
For GNOME System Monitor the PID matches and so does the size, but the element has no name and an unexpected role:
findAccessibleWindowrequires the title to match, so an unnamed window never matches. libatspi sees this window correctly:Atspi.get_desktop(0)→ applicationgnome-system-monitor(pid 210600) → child with roleframe, nameSystem Monitor, 1920x1048. So the name is lost either inside xa11y or becausechildren()returns a different node for GTK4's AT-SPI implementation than for other toolkits.Impact
On a stock GNOME desktop most apps are either Flatpaks or GTK4, so Include app text rarely produces anything on Linux. It fails silently, which makes it look like the app simply has no accessible text.
Version or commit
0.0.42 (AppImage)
Environment
Zorin OS 18 (Ubuntu 24.04 base), GNOME Shell 46.0, Wayland, at-spi2-core from the distro, Flatpak Zen Browser, GNOME System Monitor with libgtk-4 and libadwaita-1.
Workaround
None found.
Possible directions: for (1), when
byPidfinds nothing, fall back toApp.list()and match on title plus size, which is what the window matcher already relies on. For (2), when exactly one window of the right PID has matching bounds, accept it even without a name, or look at why xa11y reports GTK4 frames as unnamed groups.