inject.ActiveBackend reports the backend resolveBackend would pick, not one that has been shown to work. Where those differ, the settings page states something confident and wrong — which is the exact failure the backend readout was added to prevent: with a fallback chain, "it works" and "it works the way you think" are different claims.
Observed
Flatpak build (dev, run 31885650392) on Fedora 44 / niri / Wayland:
GET /api/linux-tools
{"backend": "portal", "present": {"wtype": true, "ydotool": false, ...}}
wtype is bundled and present, but wtypeUsable() fails inside the sandbox — Flatpak's managed Wayland socket filters out the virtual-keyboard protocol, as canType's comment already notes. So resolveBackend falls through to portalUsable(), which is portalPresent() && !portalFailed. On niri xdg-desktop-portal advertises RemoteDesktop with no backend behind it, so portalPresent() is true and the readout says portal.
It cannot type at all in that configuration. docs/flatpak.md says as much: "The sandbox can only type where the RemoteDesktop portal exists."
What actually happens
Behaviour self-corrects. The first dictation attempts the portal, fails, sets portalFailed, and from then on resolveBackend → ydotool → canType false → adjustMode degrades to clipboard-only, which is what "fall back to the clipboard when nothing can type" (a2e3b09) is for. The user gets their text.
So this is a reporting problem, not a delivery one: between startup and the first failed dictation, Vito names a route it has never exercised.
Why it is not a one-line fix
Honestly probing RemoteDesktop means creating a session, and that is exactly the call that raises the permission dialog. Doing it at startup to populate a status field would spend the user's consent prompt on a diagnostic — the same reasoning that made RequestAccessibility a user action on macOS rather than a startup check. docs/linux-portals.md states the rule this comes from: the portal frontend lists interfaces its backend may not implement, so only a real attempt tells you anything.
Options, roughly in order of cost
- Say what it is. Report the backend as unverified until something has succeeded — "portal (not yet used)" — and firm it up after the first delivery. No new portal traffic.
- Probe on demand. A button on the settings page that creates a session and reports the result, so the user chooses to spend the prompt.
- Probe at startup where a session already exists (a stored restore token means the grant is held, so no dialog) and leave it unverified otherwise.
Option 1 alone removes the wrong claim, which is the actual defect here.
Not urgent
Only visible where the portal is advertised but absent — niri and wlroots compositors, in a sandbox. On GNOME and KDE the reported backend is the real one.
inject.ActiveBackendreports the backendresolveBackendwould pick, not one that has been shown to work. Where those differ, the settings page states something confident and wrong — which is the exact failure the backend readout was added to prevent: with a fallback chain, "it works" and "it works the way you think" are different claims.Observed
Flatpak build (
dev, run 31885650392) on Fedora 44 / niri / Wayland:wtypeis bundled and present, butwtypeUsable()fails inside the sandbox — Flatpak's managed Wayland socket filters out the virtual-keyboard protocol, ascanType's comment already notes. SoresolveBackendfalls through toportalUsable(), which isportalPresent() && !portalFailed. On nirixdg-desktop-portaladvertises RemoteDesktop with no backend behind it, soportalPresent()is true and the readout saysportal.It cannot type at all in that configuration.
docs/flatpak.mdsays as much: "The sandbox can only type where the RemoteDesktop portal exists."What actually happens
Behaviour self-corrects. The first dictation attempts the portal, fails, sets
portalFailed, and from then onresolveBackend→ ydotool →canTypefalse →adjustModedegrades to clipboard-only, which is what "fall back to the clipboard when nothing can type" (a2e3b09) is for. The user gets their text.So this is a reporting problem, not a delivery one: between startup and the first failed dictation, Vito names a route it has never exercised.
Why it is not a one-line fix
Honestly probing RemoteDesktop means creating a session, and that is exactly the call that raises the permission dialog. Doing it at startup to populate a status field would spend the user's consent prompt on a diagnostic — the same reasoning that made
RequestAccessibilitya user action on macOS rather than a startup check.docs/linux-portals.mdstates the rule this comes from: the portal frontend lists interfaces its backend may not implement, so only a real attempt tells you anything.Options, roughly in order of cost
Option 1 alone removes the wrong claim, which is the actual defect here.
Not urgent
Only visible where the portal is advertised but absent — niri and wlroots compositors, in a sandbox. On GNOME and KDE the reported backend is the real one.