fix: diagnose missing Sonoma hidutil remapping

This commit is contained in:
root 2026-10-25 22:07:44 +03:00
parent 85f4317f36
commit 72d500a350
3 changed files with 45 additions and 4 deletions

View file

@ -33,6 +33,25 @@ If the event tap is refused or no F19 events are received, also grant
**Input Monitoring** from the menu. Restart Capswitch after granting
permissions if macOS prompts you to do so.
### macOS Sonoma: grant Input Monitoring to hidutil itself
On macOS 14, an Input Monitoring grant for Capswitch.app may not be
sufficient for its child process /usr/bin/hidutil, which is used to set
the actual global HID mapping. If task doctor reports (null), Caps->F19
is not installed (regardless of whether the app process is running).
Open **System Settings -> Privacy & Security -> Input Monitoring**, click
the + button, then press **Command+Shift+G** in the file picker and enter
**/usr/bin/hidutil**. Select hidutil and enable its Input Monitoring
toggle. This is separate from Capswitch.app. Quit and reopen Capswitch,
then run task doctor again. See also the Sonoma notes for
mvp/mac-remap-keys.
If the mapping remains null, inspect the **Capswitch menu** and capture
the Accessibility / Event tap / HID / Error entries. The application may
be running without having created its event tap at all; Input Monitoring
for hidutil cannot fix missing Accessibility permission.
If you previously used macOS's built-in Caps-to-input-source switching, open
System Settings -> Keyboard -> Text Input -> Edit and uncheck
"Use Caps Lock to switch to and from [last used Latin input source]".

View file

@ -14,7 +14,7 @@ enum HIDRemapError: LocalizedError {
case .unreadableMapping:
return "Cannot safely read the existing HID key mappings; no changes were made."
case .verificationFailed:
return "hidutil did not confirm Caps Lock to F19 remapping."
return "hidutil did not apply Caps → F19. On macOS 14, grant Input Monitoring to /usr/bin/hidutil separately from Capswitch.app, then restart Capswitch."
case let .commandFailed(details):
return "hidutil failed: \(details)"
}

View file

@ -91,14 +91,36 @@ tasks:
defaults read -g TISRomanSwitchState 2>/dev/null || true
defaults read com.apple.HIToolbox TISRomanSwitchState 2>/dev/null || true
echo "=== Global HID remappings ==="
hidutil property --get UserKeyMapping
mapping="$(hidutil property --get UserKeyMapping 2>&1)" || {
echo "$mapping"
echo "ERROR: hidutil could not read UserKeyMapping." >&2
exit 1
}
echo "$mapping"
echo "=== HID keyboard services (may vary by keyboard) ==="
hidutil property --matching '{"PrimaryUsagePage":1,"PrimaryUsage":6}' --get UserKeyMapping || true
echo "=== Running Capswitch processes ==="
pgrep -fl Capswitch || true
echo "=== Diagnosis ==="
case "$mapping" in
*"(null)"* | *"()"*)
echo "NO HID REMAP ACTIVE: physical Caps cannot arrive as F19."
echo "Capswitch can be running without a working event tap or remap."
echo "Check Capswitch menu: Accessibility, Event tap, HID and Error."
echo "On Sonoma, /usr/bin/hidutil may need its OWN Input Monitoring approval."
echo "Grant it via Privacy & Security -> Input Monitoring -> + -> Cmd+Shift+G -> /usr/bin/hidutil."
echo "That is separate from permission for Capswitch.app."
;;
*"HIDKeyboardModifierMappingSrc"*)
echo "Mapping entries exist. Verify Caps -> F19 in the output above."
;;
*)
echo "Unrecognized mapping output. Check the raw values above."
;;
esac
echo "=== Privacy permissions ==="
echo "Inspect Accessibility and Input Monitoring in the Capswitch status menu."
echo "If Input Monitoring is not granted, choose 'Grant Input Monitoring permission'."
echo "The terminal cannot verify the running app's TCC status."
echo "Inspect Accessibility / Input Monitoring / Event tap / Error in its menu."
clean:
desc: Remove build outputs