Wie erhalte ich programmatisch die Tasten reserviert von Mac OS X
-
21-08-2019 - |
Frage
Ich arbeite mit einer Anwendung, die der Kunde, welche Tastenkombinationen anpassen können zugeordnet sind. Eine Sache, die ich tun möchte, ist zu warnen, wenn eine Schnelltaste gewählt wird, das bereits von Mac OS X ist.
Ich versuche, mit CopySymbolicHotKeys zu arbeiten, aber ich bin mir nicht sicher, dass ich es richtig bin mit, wie es Befehle wie listet auch reserviert werden, obwohl ich es nicht sehe in den „Tastenkombinationen“ aufgelistet Tabulascheibe die „Tastatur & Maus“ Systemeinstellungen. Ich möchte in der Lage sein, diese Verknüpfungen zu erhalten, die „reserviert“ für das System ist, ist dies die API zu verwenden?
Ich habe eine Probe von meinem Code unten enthalten, um es bitte jeder Vorschlag ein Angebot suchen, die in den Sinn kommen können.
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);
Lösung
Ich glaube nicht, dass dies möglich ist.
Der Link diskutiert CopySymbolicHotKeys als auch mit . Allerdings listet die Funktion Tastenkombinationen, die nicht in der Systemeinstellung für Tastenkombinationen aufgeführt sind. Wenn es irgendwie zwischen wirklich reserviert Schlüssel und nur Standardschlüssel zu unterscheiden war, das wäre ideal.
Die beste Antwort scheint die tatsächliche plist-Datei zu parsen, „com.apple.symbolichotkeys.plist“, die ich in Apples Carbon-E-Mail-Diskussionsliste gefunden. Dies setzt jedoch voraus Antwort, dass Sie wissen, was jeder Schlüssel ist (was ich nicht).
Ich fand auch einen Link rel="nofollow beschreiben, was die Zusatztaste Werte sind.
Hier ist der Code, der zum Sperren einer bekannt Taste im System Shortcut Key Preferenes gepostet:
#include <CoreServices/CoreServices.h>
static CFStringRef gApplicationID = CFSTR("com.apple.symbolichotkeys");
static CFStringRef gKeyASHK = CFSTR("AppleSymbolicHotKeys");
static CFStringRef gKey73 = CFSTR("73");
static CFStringRef gKeyEnabled = CFSTR("enabled");
int main(int argc, const char *argv[]) {
#pragma unused (argc, argv)
CFPropertyListRef hotkeysCFPropertyListRef = CFPreferencesCopyAppValue(gKeyASHK, gApplicationID);
if ( !hotkeysCFPropertyListRef ) {
fprintf(stderr,
"%s, CFPreferencesCopyAppValue(\"AppleSymbolicHotKeys\", \"com.apple.symbolichotkeys.plist\" returned NULL.\n",
__PRETTY_FUNCTION__);
return (-1);
}
// make sure it's a dictionary
if ( CFGetTypeID(hotkeysCFPropertyListRef) != CFDictionaryGetTypeID() ) {
fprintf(stderr, "%s, CFGetTypeID(hotkeysCFPropertyListRef) != CFDictionaryGetTypeID().\n", __PRETTY_FUNCTION__);
return (-1);
}
// get the "73" value from that dictionary
CFPropertyListRef hotkey73CFPropertyListRef = NULL;
if ( !CFDictionaryGetValueIfPresent(hotkeysCFPropertyListRef, gKey73, &hotkey73CFPropertyListRef) ) {
fprintf(stderr, "%s, CFDictionaryGetValueIfPresent(...,\"73\",...) returned FALSE.\n", __PRETTY_FUNCTION__);
return (-1);
}
//CFShow(hotkey73CFPropertyListRef);
// make sure it's a dictionary
if ( CFGetTypeID(hotkey73CFPropertyListRef) != CFDictionaryGetTypeID() ) {
fprintf(stderr, "%s, CFGetTypeID(hotkey73CFPropertyListRef) != CFDictionaryGetTypeID().\n", __PRETTY_FUNCTION__);
return (-1);
}
// get the "73" value from that dictionary
CFPropertyListRef hotkey73EnabledCFPropertyListRef = NULL;
if ( !CFDictionaryGetValueIfPresent(hotkey73CFPropertyListRef, gKeyEnabled, &hotkey73EnabledCFPropertyListRef) ) {
fprintf(stderr, "%s, CFDictionaryGetValueIfPresent(...,\"enabled\",...) returned FALSE.\n", __PRETTY_FUNCTION__);
return (-1);
}
//CFShow(hotkey73EnabledCFPropertyListRef);
// make sure it's a boolean
if ( CFGetTypeID(hotkey73EnabledCFPropertyListRef) != CFBooleanGetTypeID() ) {
fprintf(stderr, "%s, CFGetTypeID(hotkey73EnabledCFPropertyListRef) != CFBooleanGetTypeID().\n", __PRETTY_FUNCTION__);
return (-1);
}
// get its value
Boolean value = CFBooleanGetValue(hotkey73EnabledCFPropertyListRef);
CFBooleanRef hotkey73EnabledCFBooleanRef = value ? kCFBooleanFalse : kCFBooleanTrue; // note: toggle value
// create a mutable copy of the hot key 73 dictionary
CFMutableDictionaryRef newHotkey73CFCFMutableDictionaryRef = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, hotkey73CFPropertyListRef);
if ( !newHotkey73CFCFMutableDictionaryRef ) {
fprintf(stderr, "%s, CFDictionaryCreateMutableCopy(..., hotkey73CFPropertyListRef) returned NULL.\n", __PRETTY_FUNCTION__);
return (-1);
}
// set the new value for the "enabled" item
CFDictionarySetValue(newHotkey73CFCFMutableDictionaryRef, gKeyEnabled, hotkey73EnabledCFBooleanRef);
//CFShow(newHotkey73CFCFMutableDictionaryRef);
// create a mutable copy of the hot key dictionary
CFMutableDictionaryRef newHotkeysCFPropertyListRef = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, hotkeysCFPropertyListRef);
if ( !newHotkeysCFPropertyListRef ) {
fprintf(stderr, "%s, CFDictionaryCreateMutableCopy(...,hotkeysCFPropertyListRef) returned NULL.\n", __PRETTY_FUNCTION__);
return (-1);
}
// set the new value for the "73" item
CFDictionarySetValue(newHotkeysCFPropertyListRef, gKey73, newHotkey73CFCFMutableDictionaryRef);
CFRelease(newHotkey73CFCFMutableDictionaryRef);
//CFShow(newHotkeysCFPropertyListRef);
CFPreferencesSetAppValue(gKeyASHK, newHotkeysCFPropertyListRef, gApplicationID);
if ( !CFPreferencesAppSynchronize(gApplicationID) ) {
fprintf(stderr, "%s, CFPreferencesAppSynchronize returned false.\n", __PRETTY_FUNCTION__);
return (-1);
}
// note: value is opposite of what we just set (so invert logic)
printf("%s, /AppleSymbolicHotKeys/73/enabled set to %s.\n", __PRETTY_FUNCTION__, value ? "FALSE" : "TRUE");
return (0);
} // main
Andere Tipps
Ich möchte Code hinzufügen, die zum Lesen / Schreiben hilft durch Lyndsey Ferguson repräsentiert Datei auf dem Weg ~/Library/Preferences/com.apple.symbolichotkeys.plist
mit CFPreferencesCopyAppValue()
und als CFDictionaryGetValueIfPresent()
von CFPropertyListRef
. Entscheidend ist, zu wissen, welche symbolische Hotkeys Kennung mit welchen Hotkeys in Tastenkombinationen Einstellungen Bereich zusammenhängt. Hier ist der Code mit beschreibenden Konstanten, die Ihnen viel dabei helfen können:
/**
* 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,
};
Ich würde nicht wissen, wie es programmically zu tun, aber wenn Hartcodierung eine Option finden Sie eine Liste von MacOSX Abkürzungen finden Sie hier: http://support.apple.com/kb/HT1343 . Ich würde eine Regex verwenden, um die Schlüssel-Kombinationen zu saugen dann konvertieren programmically zu Keysyms / keycodes. Die Seite erscheint von Apple für jede OSX Version aktualisiert werden, so sollten Sie in der Lage sein, einfach den Vorgang mit jedem OSX Update zu wiederholen.