Skip to content

Retry Fn hotkeys after Accessibility approval#583

Merged
basnijholt merged 2 commits into
mainfrom
fix/accessibility-hotkey-retry
Jun 4, 2026
Merged

Retry Fn hotkeys after Accessibility approval#583
basnijholt merged 2 commits into
mainfrom
fix/accessibility-hotkey-retry

Conversation

@basnijholt
Copy link
Copy Markdown
Owner

Summary

  • retry Fn-key event tap registration after macOS Accessibility approval
  • retry on app activation when permission is already trusted
  • keep reset flow from requiring a second quit/open cycle

Verification

  • swift build
  • swift test
  • git diff --check HEAD~1..HEAD

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 4, 2026

Greptile Summary

This PR adds automatic retry of CGEvent tap registration for Fn-key hotkeys after macOS Accessibility permission is granted, eliminating the need for a manual quit/reopen cycle. It introduces a 1-second polling loop (capped at 120 seconds) started at the point of tap creation failure, and also hooks applicationDidBecomeActive as a fast-path to immediately re-register once the user returns to the app after granting permission.

  • scheduleAccessibilityRetry: polls AXIsProcessTrusted() every second for up to 120 s and calls registerFunctionAwareTranscriptionHotkeys as soon as trust is confirmed.
  • retryFunctionAwareHotkeysIfTrusted: provides an instant retry on applicationDidBecomeActive; guarded by registered, eventTap == nil, and AXIsProcessTrusted() so it is safely idempotent.
  • cancelAccessibilityRetry is now the first action in registerFunctionAwareTranscriptionHotkeys (before the early-return guard), ensuring the retry loop is always torn down regardless of whether a tap is already present.

Confidence Score: 5/5

Safe to merge; the retry and fast-path registration logic is well-guarded against double registration and concurrent execution.

Both code paths that can trigger registration (the 1-second polling loop and the applicationDidBecomeActive fast path) are protected by eventTap == nil, so re-entrant or overlapping calls are harmless. The cancelAccessibilityRetry call at the top of registerFunctionAwareTranscriptionHotkeys ensures the polling loop is torn down regardless of entry point. No data-race risk exists because all dispatch work is serialised on the main queue.

No files require special attention.

Important Files Changed

Filename Overview
macos/AgentCLI/Sources/AgentCLI/ConfigurableHotkeyController.swift Adds accessibilityRetryWorkItem polling loop, scheduleAccessibilityRetry/cancelAccessibilityRetry helpers, and retryFunctionAwareHotkeysIfTrusted; double-registration is prevented by the eventTap == nil guard moved to the top of registerFunctionAwareTranscriptionHotkeys.
macos/AgentCLI/Sources/AgentCLI/AppDelegate.swift Adds applicationDidBecomeActive delegate hook that calls retryFunctionAwareHotkeysIfTrusted for a fast-path re-registration when the user returns to the app after granting Accessibility permission.

Sequence Diagram

sequenceDiagram
    participant App as AppDelegate
    participant CHC as ConfigurableHotkeyController
    participant OS as macOS AX/CGEvent

    App->>CHC: registerDefaultHotkeys(runner)
    CHC->>OS: CGEvent.tapCreate
    OS-->>CHC: nil (AX not trusted)
    CHC->>OS: AXIsProcessTrustedWithOptions (prompt)
    CHC->>CHC: scheduleAccessibilityRetry deadline now+120s

    loop every 1s while not trusted and before deadline
        CHC->>OS: AXIsProcessTrusted
        OS-->>CHC: false
        CHC->>CHC: reschedule
    end

    Note over App,OS: User grants Accessibility in System Settings

    alt Fast path via app activation
        OS->>App: applicationDidBecomeActive
        App->>CHC: retryFunctionAwareHotkeysIfTrusted(runner)
        CHC->>CHC: cancelAccessibilityRetry
        CHC->>OS: CGEvent.tapCreate
        OS-->>CHC: tap success
        CHC->>CHC: enable tap
    else Polling path fires first
        CHC->>OS: AXIsProcessTrusted
        OS-->>CHC: true
        CHC->>OS: CGEvent.tapCreate
        OS-->>CHC: tap success
        CHC->>App: statusMessage Accessibility permission enabled
    end
Loading

Reviews (2): Last reviewed commit: "Address accessibility retry review feedb..." | Re-trigger Greptile

Comment thread macos/AgentCLI/Sources/AgentCLI/ConfigurableHotkeyController.swift
Comment thread macos/AgentCLI/Sources/AgentCLI/ConfigurableHotkeyController.swift
@basnijholt basnijholt force-pushed the fix/accessibility-hotkey-retry branch from 0e9914f to e189fdd Compare June 4, 2026 22:34
@basnijholt basnijholt merged commit 7d5cc9f into main Jun 4, 2026
10 checks passed
@basnijholt basnijholt deleted the fix/accessibility-hotkey-retry branch June 4, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant