Comment puis-je obtenir par programmation des touches de raccourci réservés par Mac OS X

StackOverflow https://stackoverflow.com/questions/866056

  •  21-08-2019
  •  | 
  •  

Question

Je travaille avec une application qui permet au client de personnaliser les touches de raccourci sont assignées. Une chose que je veux faire est warn si une touche de raccourci est choisi qui est déjà utilisé par Mac OS X.

Je suis en train de travailler avec CopySymbolicHotKeys, mais je ne suis pas sûr que je l'utilise correctement car il énumère les commandes comme étant réservé, même si je ne vois pas listé dans l'onglet volet « Raccourcis clavier » de le système « clavier et souris » Préférences. Je voudrais être en mesure d'obtenir les raccourcis qui sont « réservés » pour l'utilisation du système, est-ce l'API à utiliser?

J'ai inclus un échantillon de mon code ci-dessous, s'il vous plaît le regarder une offre toute suggestion qui peut venir à votre esprit.

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);
Était-ce utile?

La solution

Je ne pense pas que cela soit possible.

Ce lien traite de l'utilisation CopySymbolicHotKeys ainsi . Cependant, la liste fonction des raccourcis clavier qui ne sont pas répertoriés dans la préférence du système pour les raccourcis clavier. S'il y avait someway faire la différence entre en fait et les touches réservées seulement touches standard, ce serait l'idéal.

La meilleure réponse semble être l'analyse du fichier plist réelle, « com.apple.symbolichotkeys.plist » que je trouve dans le courriel de carbone Liste de discussion d'Apple. Cependant, cette réponse suppose que vous savez ce que chaque clé est (que je ne le fais pas).

J'ai aussi trouvé un décrivant ce que le modificateur des valeurs clés.

Voici le code qui a été publié pour la désactivation d'un connu clé dans le système de raccourci clé Preferenes:

#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

Autres conseils

Je voudrais ajouter du code qui aide à lire / écrire dans le fichier ~/Library/Preferences/com.apple.symbolichotkeys.plist manière représentée par Lyndsey Ferguson à l'aide et que CFPreferencesCopyAppValue() de CFDictionaryGetValueIfPresent() CFPropertyListRef. La chose essentielle est de savoir quel identifiant touches de raccourci symbolique est liée avec laquelle les touches de raccourci clavier dans volet Préférences des raccourcis. Voici le code avec des constantes descriptives qui peuvent vous aider beaucoup avec ceci:

/**
 * 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,
};

Je ne sais pas comment le faire programmically mais si dur de codage est une option que vous trouverez une liste des raccourcis MacOSX ici: http://support.apple.com/kb/HT1343 . J'utilise une expression régulière pour aspirer les combinaisons de touches, puis programmically convertir en keysyms / keycodes. La page semble être mis à jour par Apple pour chaque version Mac OS X de sorte que vous devriez être en mesure de répéter facilement le processus avec chaque mise à jour Mac OS X.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top