Add global keyboard shortcuts for approve/deny permissions#49
Open
lancehambly wants to merge 10 commits into
Open
Add global keyboard shortcuts for approve/deny permissions#49lancehambly wants to merge 10 commits into
lancehambly wants to merge 10 commits into
Conversation
Adds macOS-level keyboard shortcuts (⌘⇧Y to approve, ⌘⇧N to deny) that work system-wide without needing to click the notch UI. Includes configurable shortcut recording in settings, visual flash feedback on the notch, and audio confirmation sounds. New files: - KeyboardShortcut.swift: KeyCombo model with Carbon key code mapping - KeyboardShortcutHandler.swift: Global/local NSEvent monitors - ShortcutFeedback.swift: Visual/audio feedback on shortcut activation - ShortcutSettingsRow.swift: Settings UI with shortcut recorder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two fixes: 1. Replace NSEvent global key monitor with Carbon RegisterEventHotKey for true system-wide hotkeys that work regardless of focused app (NSEvent global monitors cannot reliably capture keyDown events) 2. Always expand notch for pending permissions, even when a terminal is visible — users need to see what tool is requesting approval Also wire reloadShortcuts() to settings UI so hotkeys re-register immediately when changed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Instance list height now scales to content — ~52pt per row instead of a fixed 320pt, clamped between 120-400pt 2. Notch auto-closes 0.8s after all pending permissions are resolved (only when opened via notification, not manual click) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When there are unanswered permission requests and the user's terminal is not visible, clicking outside the island no longer dismisses it. The click still passes through to the underlying app, but the island stays visible so the user doesn't lose sight of pending approvals. If the terminal IS visible (user can see the CLI prompt), outside clicks dismiss as before. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When all permissions are resolved and the island is showing the instances list: retract after 0.8s (keyboard shortcut / notification) or 5s (manually opened). Click-away already works for non-permission states. Does not auto-close if user is in chat or menu view. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous auto-retract only triggered when pending permissions went from non-empty to empty. Completions (waitingForInput) that arrive while the island is open now also schedule a 5s retract if there are no outstanding permission requests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the terminal visibility check from the click-away guard. The island now stays open unconditionally when there are pending permission requests, regardless of whether a terminal is visible. Users running Claude Code will always have a terminal on screen, so the previous check was effectively disabling persistence. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When multiple Claude sessions have pending permission requests:
- Amber accent bar on the left edge of the selected row shows
which session ⌘⇧Y/⌘⇧N will act on
- ⌘⇧↑ / ⌘⇧↓ cycles selection between pending sessions
- Closed notch shows count badge ("2", "3"...) when 2+ pending
- Selection auto-reconciles when sessions resolve or arrive
- Approve/deny shortcuts now target the selected session
instead of blindly picking the first one
New state: NotchViewModel.selectedPendingSessionId
New hotkeys: Carbon RegisterEventHotKey for ⌘⇧↑ and ⌘⇧↓
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The green/red flash now highlights only the specific row that was approved/denied, not the entire notch. The flash overlay sits on InstanceRow and only renders when that row is the selected target. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The green/red glow on approve/deny wasn't necessary — the row disappearing from the list is sufficient feedback. Removes ShortcutFeedback entirely as nothing uses it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rylax
added a commit
to rylax/claude-island
that referenced
this pull request
Mar 9, 2026
Kel-Antony
added a commit
to Kel-Antony/claude-island
that referenced
this pull request
Apr 9, 2026
…arouqaldori#43, farouqaldori#49, farouqaldori#52) Always Allow (farouqaldori#52): - Add permissionApprovedAlways event to SessionStore state machine - Add autoApprovedTools: Set<String> to SessionState — approved tools are silently auto-approved on future requests within the same session - Add Always (green) button to InlineApprovalButtons and ChatApprovalBar - Island stays open when permissions are pending (can't dismiss by clicking away) Keyboard shortcuts (farouqaldori#49): - Add KeyCombo model with Codable + displayString support - Add KeyboardShortcutHandler using Carbon RegisterEventHotKey for true system-wide hotkeys (work regardless of focused app) - ⌘⇧Y = Approve, ⌘⇧N = Deny, ⌘⇧↓/↑ = cycle between pending sessions - Add shortcut settings to AppSettings (UserDefaults backed) - Add selectedPendingSessionId + hasPendingPermissions to NotchViewModel - Show amber left-edge indicator on the keyboard-selected pending row - Instances panel height is now dynamic (52pt per row, clamped 120–400pt) Deployment target (farouqaldori#43): - Lower MACOSX_DEPLOYMENT_TARGET from 15.6 → 15.0
rosuH
pushed a commit
to rosuH/claude-island
that referenced
this pull request
Apr 14, 2026
* feat: add proactive accessibility permission checking - Add AccessibilityPermissionManager singleton to monitor permission state - Show startup alert explaining why permission is needed - Display amber warning icon in closed notch when permission missing - Update AccessibilityRow with amber styling and reactive state - Keep notch visible while accessibility warning is shown - Periodic monitoring detects when user grants permission Fixes farouqaldori#46 * fix: address review comments from PR farouqaldori#49 - Start periodic monitoring immediately when accessibility permission is missing, so UI reliably updates when permission is granted through any path (not just via our alert's "Open Settings" button) - Include accessibilityWarningWidth in expansion calculation for the warning-only case, fixing potential layout compression * fix: improve accessibility permission detection with adaptive polling Use DispatchSourceTimer with adaptive polling (0.5s for 30s, then 2s) instead of Timer for more reliable detection. Add app activation handler in NotchView to restart fast polling when user returns from System Settings. Move from custom alert to macOS system prompt for better UX. * fix: show explanatory alert instead of system dialog on launch Replace promptForPermission() with showPermissionAlert() to match the intended behavior described in the PR. Users now see a custom alert explaining why accessibility permission is needed, with an "Open Settings" button to guide them to grant permission.
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.
Context
Hey! Love this project — the Dynamic Island UX for Claude Code is brilliant. I kept finding myself reaching for keyboard shortcuts to approve/deny permissions without having to mouse up to the notch, especially during fast iteration loops. So I put together this feature as a suggestion.
These are proposed changes only — I don't have any permissions on this repo. Happy for you to take, adapt, cherry-pick, or ignore any of this. Just wanted to share what worked well for me and a colleague.
What this adds
System-wide keyboard shortcuts for approving/denying Claude Code permission requests, plus several UX improvements to the notch behavior around permissions.
Keyboard shortcuts
RegisterEventHotKey, no Accessibility permission requiredMulti-session approval selection
When multiple Claude sessions have pending permission requests simultaneously:
Notch behavior improvements
TerminalVisibilityDetectorcheck that suppressed expansion when a terminal was visible. Users need to see what tool is requesting approval.Design decisions
RegisterEventHotKeyoverNSEvent.addGlobalMonitorForEvents(.keyDown)— the latter doesn't reliably fire for keyboard events when the app isn't focused. Carbon hotkeys are the proper macOS API for this and don't require Accessibility permission.KeyCombomodel isCodableand persisted viaUserDefaults(throughAppSettings) so custom bindings survive app restarts.NotchViewModel— it's UI state, not session state, and needs to be accessible from both SwiftUI views and the shortcut handler.ClaudeInstancesViewso what the user sees matches what they cycle through.Files changed
New files (3)
Models/KeyboardShortcut.swiftKeyCombomodel — key code + modifier flags,Codable, human-readabledisplayString(e.g. "⌘⇧Y"), full Carbon key code → string mappingServices/Shortcuts/KeyboardShortcutHandler.swiftUI/Components/ShortcutSettingsRow.swiftModified files (5)
Core/Settings.swiftshortcutsEnabled,approveShortcut,denyShortcuttoAppSettingswithUserDefaultspersistenceCore/NotchViewModel.swiftselectedPendingSessionId,hasPendingPermissions,reconcilePendingSelection(),cyclePendingSelection(), dynamicinstanceCount-based sizingUI/Views/NotchView.swiftonChange, count badge in closed header, auto-retract timers, always-expand for permissionsUI/Views/NotchMenuView.swiftShortcutSettingsRow()to the appearance settings sectionUI/Views/ClaudeInstancesView.swiftisSelectedparameter toInstanceRow, renders amber left accent bar when selected + waiting for approvalTesting done
Tested manually on macOS 15.6, MacBook Pro with notch:
Screenshots
(Built and tested locally — happy to provide screenshots/recordings if helpful)
Thanks again for building Claude Island — it's become part of my daily workflow. Let me know if you have any questions about the implementation or want me to adjust anything.
🤖 Generated with Claude Code