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);
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top