fix(onboarding): require macOS Accessibility grant before first-run completes#703
Merged
Merged
Conversation
…ompletes
On macOS the hotkey needs Accessibility, but first-run onboarding could finish
after Microphone only and drop users into the main UI with a dead hotkey
("nothing happens when I press the key").
Cause: desktop onboarding gated completion on the hotkey *capability* flag
(requiresAccessibilityPermission). That flag is null while the capability IPC
loads, so requiresAccessibility was briefly false — if Mic got granted in that
window, refresh() called onComplete() before Accessibility was ever requested.
App.tsx's startup gate, by contrast, always requires Accessibility, so the two
disagreed.
Fix: gate completion on the real permission status, mirroring App.tsx — macOS
returns granted/denied, every other platform returns notApplicable, so this is
timing-independent and cross-platform safe. Also surface the Accessibility step
whenever it is denied (macOS-only state) and drop the capability dependency from
its grant button, so the step always appears and is actionable even before the
capability finishes loading.
No change on Windows/Linux/Android (Accessibility = notApplicable there).
Contributor
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
appergb
pushed a commit
that referenced
this pull request
Jun 17, 2026
…ing accessibility gate Bundles the two macOS UX fixes already merged into beta: - #702 unify macOS shell top inset with sidebar/background surface - #703 require macOS Accessibility grant before first-run onboarding completes Version synced across package.json, package-lock.json, tauri.conf.json, Cargo.toml, Cargo.lock. Local release build verified (1.3.10-2 installs and runs; top bar seamless; first-run requires Accessibility).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
Problem
On macOS, first-run onboarding could complete after Microphone only and drop the user into the main UI without Accessibility granted — so the global hotkey silently does nothing and the app looks broken.
Cause
DesktopOnboardinggated completion on the hotkey capability flagrequiresAccessibilityPermission:That flag comes from an async IPC and is
nullwhile it loads →requiresAccessibilityis brieflyfalse→aOkistrue. If Microphone gets granted inside that window,refresh()callsonComplete()before Accessibility was ever requested. The accessibility step ({requiresAccessibility && …}) hadn't rendered yet either. MeanwhileApp.tsx's startup gate always requires Accessibility, so the two disagreed.Confirmed in source: macOS
HotkeyCapabilityhasrequires_accessibility_permission: true(types.rs), but the TS fallback/mock default tofalse.Fix (
Onboarding.tsx, desktop path only)App.tsx— timing-independent, capability-flag-independent:check_accessibility()returnsgranted/deniedon macOS andnotApplicableon Windows/Linux/Android, so this requires Accessibility exactly where it's needed.denied(a macOS-only state) in addition to the capability flag, so the step reliably appears even before/if the capability hasn't loaded.disabled, so it's actionable in that same window.Behavior
notApplicable→aOktrue, step hidden → unchanged.Test plan
npx tsc --noEmit— cleanBase:
beta.PR Type
Bug fix
Description
Fix macOS onboarding completing without Accessibility granted
Gate completion on real permission status, not capability flag
Show Accessibility step when denied even before capability loads
Drop capability dependency from grant button disabled state
Diagram Walkthrough
flowchart LR A["Onboarding refresh()"] --> B["Check permissions"] B --> C{"Accessibility = granted or notApplicable?"} C -- "True" --> D{"Microphone = granted or notApplicable?"} D -- "True" --> E["onComplete()"] D -- "False" --> F["Wait for Mic grant"] C -- "False" --> G["Show Accessibility step"] G --> H["User grants Accessibility"] H --> BFile Walkthrough
Onboarding.tsx
Fix Accessibility permission gating and step visibilityopenless-all/app/src/components/Onboarding.tsx
refresh()to gate completion on real accessibility permissionstatus instead of
requiresAccessibilityflagaccessibility === 'denied'capability?.requiresAccessibilityPermissionfrom grant buttondisabledconditiondenied