Modern framework for managing global keyboard shortcuts compatible with Mac App Store. More details:
Objective-C Ruby Makefile
Latest commit b54c1ed Nov 1, 2016 @zoul zoul committed on GitHub Merge pull request #100 from tonyarnold/enums
Minor fixes and Swift improvements
Permalink
Failed to load latest commit information.
Demo Use modern key mask constants instead of the ones deprecated in 10.12 Oct 28, 2016
Framework Fix return from a NSToolTip method that expects a non-null return value Oct 31, 2016
MASShortcut.xcodeproj Trying to fix conditional key mask definition on 10.12 Oct 28, 2016
Tests Upgrade Projects to Xcode 7 Aug 8, 2016
cs.lproj Added Czech localization. Aug 18, 2015
de.lproj Use correct quote signs for German translation. Feb 14, 2016
en.lproj Added Czech localization. Aug 18, 2015
es.lproj Add ko, nl, pl, ru, es translations Apr 14, 2016
fr.lproj Some suggestions for fr Dec 6, 2015
it.lproj Improve Italian localization Sep 7, 2016
ja.lproj Japanese localization Oct 14, 2015
ko.lproj Add ko, nl, pl, ru, es translations Apr 14, 2016
nl.lproj Add ko, nl, pl, ru, es translations Apr 14, 2016
pl.lproj Add ko, nl, pl, ru, es translations Apr 14, 2016
ru.lproj ru localization update Jul 13, 2016
zh-Hans.lproj Simplified and traditional Chinese localizations. Jan 22, 2016
zh-Hant.lproj Simplified and traditional Chinese localizations. Jan 22, 2016
.gitignore Initial commit with my sources from CodeBox. Jul 6, 2012
.travis.yml Added shared Xcode schemes to help Travis with the build. Jan 13, 2015
CHANGES Release 2.3.6 Oct 30, 2016
CONTRIBUTING.md Link to a commit message writing guide Aug 12, 2016
LICENSE State clearly that the license is the 2-clause BSD Feb 7, 2013
MASShortcut.podspec Release 2.3.6 Oct 30, 2016
Makefile Added Makefile to build from the command line Jul 15, 2016
README.md Added Makefile to build from the command line Jul 15, 2016
Spec.md Talk about shortcut “formatting” instead of “rendering”. Jan 28, 2015

README.md

Build Status Carthage compatible

Intro

Some time ago Cocoa developers used a brilliant framework ShortcutRecorder for managing keyboard shortcuts in application preferences. However, it became incompatible with the new plugin architecture of Xcode 4.

The MASShortcut project introduces a modern API and user interface for recording, storing and using system-wide keyboard shortcuts.

Screenshot of the demo project

Features:

  • Record and display keyboard shortcuts
  • Watch for shortcuts and execute actions, system-wide
  • A nice, documented API
  • Can be configured to be compatible with Shortcut Recorder
  • Can be installed both through CocoaPods and as a Git submodule
  • Mac App Store friendly
  • Works on OS X 10.6 and up
  • Hacking-friendly codebase covered with tests

Partially done:

  • Accessibility support. There’s some basic accessibility code, testers and feedback welcome.
  • Localisation. The English and Czech localization should be complete, there’s basic support for German, French, Spanish, Italian, and Japanese. If you’re a native speaker in one of the mentioned languages, please test the localization and report issues or add missing strings.

Pull requests welcome :)

Installation

You can use CocoaPods, adding the following line to your Podfile:

pod 'MASShortcut'

If you want to stick to the 1.x branch, you can use the version smart match operator:

pod 'MASShortcut', '~> 1'

You can also install via Carthage, or you can use Git submodules and link against the MASShortcut framework manually.

To build from the command line, type 'make release'. The framework will be created in a temporary directory and revealed in Finder when the build is complete.

Usage

I hope, it is really easy:

#import <MASShortcut/Shortcut.h>

// Drop a custom view into XIB, set its class to MASShortcutView
// and its height to 19. If you select another appearance style,
// look up the correct height values in MASShortcutView.h.
@property (nonatomic, weak) IBOutlet MASShortcutView *shortcutView;

// Pick a preference key to store the shortcut between launches
static NSString *const kPreferenceGlobalShortcut = @"GlobalShortcut";

// Associate the shortcut view with user defaults
self.shortcutView.associatedUserDefaultsKey = kPreferenceGlobalShortcut;

// Associate the preference key with an action
[[MASShortcutBinder sharedBinder]
    bindShortcutWithDefaultsKey:kPreferenceGlobalShortcut
    toAction:^{
    // Let me know if you find a better or a more convenient API.
}];

You can see a real usage example in the Demo target. Enjoy!

Shortcut Recorder Compatibility

By default, MASShortcut uses a different User Defaults storage format incompatible with Shortcut Recorder. But it’s easily possible to change that, so that you can replace Shortcut Recorder with MASShortcut without having to migrate the shortcuts previously stored by your apps. There are two parts of the story:

If you bind the recorder control (MASShortcutView) to User defaults, set the Value Transformer field in the Interface Builder to MASDictionaryTransformer. This makes sure the shortcuts are written in the Shortcut Recorder format.

If you use MASShortcutBinder to automatically load shortcuts from User Defaults, set the bindingOptions accordingly:

[[MASShortcutBinder sharedBinder] setBindingOptions:@{NSValueTransformerNameBindingOption:MASDictionaryTransformerName}];

This makes sure that the shortcuts in the Shortcut Recorder format are loaded correctly.

Notifications

By registering for KVO notifications from NSUserDefaultsController, you can get a callback whenever a user changes the shortcut, allowing you to perform any UI updates, or other code handling tasks.

This is just as easy to implement:

// Declare an ivar for key path in the user defaults controller
NSString *_observableKeyPath;

// Make a global context reference
void *kGlobalShortcutContext = &kGlobalShortcutContext;

// Implement when loading view
_observableKeyPath = [@"values." stringByAppendingString:kPreferenceGlobalShortcut];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:_observableKeyPath
                                                             options:NSKeyValueObservingOptionInitial
                                                             context:kGlobalShortcutContext];

// Capture the KVO change and do something
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)obj
                        change:(NSDictionary *)change context:(void *)ctx
{
    if (ctx == kGlobalShortcutContext) {
        NSLog(@"Shortcut has changed");
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:obj change:change context:ctx];
    }
}

// Do not forget to remove the observer
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self
                                                             forKeyPath:_observableKeyPath
                                                                context:kGlobalShortcutContext];

Using in Swift projects

  1. Install as a Pod using the latest CocoaPods with Swift support.
  2. Create a bridging header file using the instructions here
  3. Your bridging header file should contain the following two imports:
#import <Cocoa/Cocoa.h>
#import <MASShortcut/Shortcut.h>

Copyright

MASShortcut is licensed under the 2-clause BSD license.