I'm working with an application that allows the customer to customize what shortcut keys are assigned. One thing I want to do is warn if a shortcut key is chosen that is already in use by Mac OS X.
I'm trying to work with CopySymbolicHotKeys, but I'm not sure that I'm using it correctly as it lists commands as being reserved even though I do not see it listed in the "Keyboard Shortcuts" tab-pane of the "Keyboard & Mouse" System Preferences. I would like to be able to get those shortcuts that are "reserved" for system use, is this the API to use?
I've included a sample of my code below, please look at it an offer any suggestion that may come to your mind.
CFArrayRef hotkeyArray = NULL;
OSStatus status = CopySymbolicHotKeys(&hotkeyArray);
if (noErr == status && NULL != hotkeyArray) {
CFIndex hotKeyCount = CFArrayGetCount(hotkeyArray);
for (CFIndex i = 0; i < hotKeyCount; i++) {
CFDictionaryRef hotKeyDict = (CFDictionaryRef) CFArrayGetValueAtIndex(hotkeyArray, i);
if (hotKeyDict && CFGetTypeID(hotKeyDict) == CFDictionaryGetTypeID()) {
if (kCFBooleanTrue == (CFBooleanRef) CFDictionaryGetValue(hotKeyDict, kHISymbolicHotKeyEnabled)) {
SInt32 keyModifiers = 0;
CFNumberRef cfkeyModifers = (CFNumberRef) CFDictionaryGetValue(hotKeyDict, kHISymbolicHotKeyModifiers);
CFNumberGetValue(cfkeyModifers, kCFNumberSInt32Type, &keyModifiers);
bool keyIsCommandOnly = (keyModifiers == (keyModifiers & cmdKey));
bool keyIsCommandAndOption = (keyModifiers == (keyModifiers & (cmdKey | optionKey)));
CFNumberRef cfKeyCode = (CFNumberRef) CFDictionaryGetValue(hotKeyDict, kHISymbolicHotKeyCode);
short keyCode = 0;
CFNumberGetValue(cfKeyCode, kCFNumberShortType, &keyCode);
CFStringRef keyString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%C"), keyCode);
const char* commandOnlyStr = "Command";
const char* commandAndOptionStr = "Command-Option";
const char* otherStr = "Other Modifier Key";
char* modifierStr = otherStr;
if (keyIsCommandOnly) {
modifierStr = commandOnlyStr;
}
else if (keyIsCommandAndOption) {
modifierStr = commandAndOptionStr;
}
CFStringRef debugString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Mac OS X Reserved Key: %s %@"), modifierStr, keyString);
CFShow(debugString); // Command-O, Command-W and other apparently non-reserved keys are output
CFRelease(debugString);
CFRelease(keyString);
}
}
}
}
CFRelease(hotkeyArray);
I would like to add code that helps to read/write to ~/Library/Preferences/com.apple.symbolichotkeys.plist
file in the way represented by Lyndsey Ferguson using CFPreferencesCopyAppValue()
and than CFDictionaryGetValueIfPresent()
from CFPropertyListRef
. The crucial thing is to know which symbolic hot keys identifier is related with which hot keys in Keyboard Shortcuts preferences pane. Here is the code with descriptive constants that can help you a lot with this:
/**
* Apple Symbolic HotKeys Ids
* To find this symbolic hot keys indices do:
* 1. open Terminal
* 2. restore defaults in System Preferences > Keyboard > Shortcuts
* 3. defaults read com.apple.symbolichotkeys > current.txt
* 4. enable/disable given symbolic hot key in System Preferences > Keyboard > Shortcuts
* 5. defaults read com.apple.symbolichotkeys | diff -C 5 current.txt -
* 6. restore defaults in System Preferences > Keyboard > Shortcuts
*/
enum {
kSHKMoveFocusToTheMenuBar = 7, // Ctrl, F2
kSHKMoveFocusToTheDock = 8, // Ctrl, F3
kSHKMoveFocusToActiveOrNextWindow = 9, // Ctrl, F4
kSHKMoveFocusToTheWindowToolbar = 10, // Ctrl, F5
kSHKMoveFocusToTheFloatingWindow = 11, // Ctrl, F6
kSHKTurnKeyboardAccessOnOrOff = 12, // Ctrl, F1
kSHKChangeTheWayTabMovesFocus = 13, // Ctrl, F7
kSHKTurnZoomOnOrOff = 15, // Opt, Cmd, 8
kSHKZoomIn = 17, // Opt, Cmd, =
kSHKZoomOut = 19, // Opt, Cmd, -
kSHKInvertColors = 21, // Ctrl, Opt, Cmd, 8
kSHKTurnImageSmoothingOnOrOff = 23, // Opt, Cmd, Backslash "\"
kSHKIncreaseContrast = 25, // Ctrl, Opt, Cmd, .
kSHKDecreaseContrast = 26, // Ctrl, Opt, Cmd, ,
kSHKMoveFocusToNextWindow = 27, // Cmd, `
kSHKSavePictureOfScreenAsAFile = 28, // Shift, Cmd, 3
kSHKCopyPictureOfScreenToTheClipboard = 29, // Ctrl, Shift, Cmd, 3
kSHKSavePictureOfSelectedAreaAsAFile = 30, // Shift, Cmd, 4
kSHKCopyPictureOfSelectedAreaToTheClipboard = 31, // Ctrl, Shift, Cmd, 4
kSHKMissionControl = 32, // Ctrl, Arrow Up
kSHKApplicationWindows = 33, // Ctrl, Arrow Down
kSHKShowDesktop = 36, // F11
kSHKMoveFocusToTheWindowDrawer = 51, // Opt, Cmd, `
kSHKTurnDockHidingOnOrOff = 52, // Opt, Cmd, D
kSHKMoveFocusToStatusMenus = 57, // Ctrl, F8
kSHKTurnVoiceOverOnOrOff = 59, // Cmd, F5
kSHKSelectThePreviousInputSource = 60, // Ctrl, Space bar
kSHKSelectNextSourceInInputMenu = 61, // Ctrl, Opt, Space bar
kSHKShowDashboard = 62, // F12
kSHKShowSpotlightSearch = 64, // Cmd, Space bar
kSHKShowFinderSearchWindow = 65, // Opt, Cmd, Space bar
kSHKLookUpInDictionary = 70, // Shift, Cmd, E
kSHKHideAndShowFrontRow = 73, // Cmd, Esc
kSHKActivateSpaces = 75, // F8
kSHKMoveLeftASpace = 79, // Ctrl, Arrow Left
kSHKMoveRightASpace = 81, // Ctrl, Arrow Right
kSHKShowHelpMenu = 98, // Shift, Cmd, /
kSHKSwitchToDesktop1 = 118, // Ctrl, 1
kSHKSwitchToDesktop2 = 119, // Ctrl, 2
kSHKSwitchToDesktop3 = 120, // Ctrl, 3
kSHKSwitchToDesktop4 = 121, // Ctrl, 4
kSHKShowLaunchpad = 160, //
kSHKShowAccessibilityControls = 162, // Opt, Cmd, F5
kSHKShowNotificationCenter = 163, //
kSHKTurnDoNotDisturbOnOrOff = 175, //
kSHKTurnFocusFollowingOnOrOff = 179, //
};
struct symbolic_hot_keys {
int shk_id; // symbolic hot keys identifier
int enabled;
char *type; // usually "standard"
int64_t ASCII_code; // ASCII code of the character or 65535 (0xFFFF) for non-ASCII characters
int64_t virtual_key_code; // virtual key code for the character
int64_t modifier_keys_flags; // the sum of modifier key flags: Shift 17 bit, Ctrl 18 bit, Opt 19 bit, Cmd 20 bit
};
typedef struct symbolic_hot_keys symbolic_hot_keys_t;
// simple mapping of modifier flags
enum {
kMFShift = kCGEventFlagMaskShift,
kMFControl = kCGEventFlagMaskControl,
kMFOption = kCGEventFlagMaskAlternate,
kMFCommand = kCGEventFlagMaskCommand,
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With