30 Commits

Author SHA1 Message Date
Jacob Greenfield 6f2603c6b6 Rename MASPickAllCocoaModifiers to MASPickModifiersIncludingFn 2022-10-17 21:07:33 -07:00
Jacob Greenfield 8d52bb87c9 Add MASPickAllCocoaModifiers (including fn key) for comparisons 2022-10-17 21:07:33 -07:00
Jacob Greenfield 7fb5f964f1 Add fn key to MASPickCocoaModifiers 2022-10-17 21:07:33 -07:00
Chiahong Hong a90bab0292 Update zh-Hant localization 2022-08-29 22:58:28 -07:00
Dave Nicolson bcdb93900f Revert "Fix 'Double-quoted include "MASxxxxx.h" in framework header, expected angle-bracketed instead' warning"
This reverts commit 031e561ce8.
2022-07-28 09:14:17 -07:00
miximka 031e561ce8 Fix 'Double-quoted include "MASxxxxx.h" in framework header, expected angle-bracketed instead' warning 2022-07-03 12:47:13 -07:00
Ethan Wong 6ddfd5f866 Allow 'Services' menu items to pass the shortcut validation. 2022-04-15 15:13:57 -07:00
Ethan Wong 57ccb01886 Support for generating correct keyEquivalents for function keys. 2021-10-21 23:39:39 +03:00
Maxim Ananov d151094502 Removed an orphaned symlink 2021-09-25 04:40:07 +03:00
Maxim Ananov f186b87231 Removed obsolete MASKeyMasks.h 2021-09-25 01:53:47 +03:00
Maxim Ananov b38e38f892 Fixed .framework compilation 2021-09-24 23:59:33 +03:00
Sanjay Madan ce0c8d85df Fix typo from replacement of deprecated constants 2021-06-27 10:11:28 +01:00
SweetPPro 28f1f6a56d really fix symlinks in include folder 2021-06-27 10:04:29 +01:00
SweetPPro 105614eed0 fixed symlinks in include folder 2021-06-27 10:04:29 +01:00
SweetPPro 3664c4179b Fix Display on macOS Big Sur 2021-06-27 10:04:29 +01:00
SweetPPro 474b730b78 Update README.md with SPM installation and usage 2021-06-27 10:04:29 +01:00
SweetPPro 352c7003f9 fix spm for Swift projects 2021-06-27 10:04:29 +01:00
SweetPPro 1b7ac3dcfa spm support 2021-06-27 10:04:29 +01:00
Vadim Shpakovski 03187327f0 Update Pod spec 2021-03-05 07:36:16 +00:00
Dzmitry Neviadomski 4b3095535d Use replacements instead of deprecated constants. 2021-03-05 07:35:41 +00:00
Dzmitry Neviadomski f082e8a161 Apply Xcode recommended settings. 2021-02-28 22:30:21 +03:00
Michael Tsai 1d8629c8d8 Make MASShortcutView an accessibility element. #152
This makes it possible to select it using VoiceOver and prevents the system from ignoring the accessibility notification that's posted when the shortcut is changed.
2021-01-21 12:37:43 +03:00
Maxim Ananov 592d0deb8d Added regularSquare style to MASShortcutView 2020-10-23 09:53:32 +03:00
Davide Pedron 38df51c808 Update Italian translation
Use the word 'abbreviazione' instead of 'scorciatoia' as Apple's translations.
Fix accent (perchè -> perché).
Use a less formal formal style as in Apple's menu.
2020-05-28 22:56:53 +03:00
Darío Hereñú 2ca3d08911 Update translation (following the Apple Guidelines)
* plus some minor fixes
2019-11-05 00:50:24 +03:00
Darío Hereñú 937ef61302 Some translation are misspelled, so fixed 2019-11-05 00:50:24 +03:00
Vinh Nguyen b3e3b79626 Unbind if newKey is nil 2019-07-29 11:11:44 +03:00
Tomáš Znamenáček 17b6a748f6 Merge pull request #134 from shpakovski/feature/nullability-annotations
Add nullability annotations
2019-06-12 15:39:29 +02:00
Tomáš Znamenáček a6d27c2621 Add nullability annotations to MASShortcutView 2019-06-11 14:47:26 +02:00
Tomáš Znamenáček e02400371f Add nullability annotations to MASShortcut
Mostly it’s safely `nonnull`, I just wasn’t sure for `keyCodeString`
and `keyCodeStringForKeyEquivalent`, so I went for the safe option and
declared those `nullable`.
2019-06-11 14:36:39 +02:00
57 changed files with 335 additions and 183 deletions
+2
View File
@@ -18,3 +18,5 @@ Fastlane/README.md
Fastlane/report.xml
# Finder
.DS_Store
.swiftpm
.build
+16 -1
View File
@@ -1,6 +1,5 @@
#import <Carbon/Carbon.h>
#import <AppKit/AppKit.h>
#import "MASKeyMasks.h"
// These glyphs are missed in Carbon.h
typedef NS_ENUM(unsigned short, kMASShortcutGlyph) {
@@ -24,6 +23,15 @@ typedef NS_ENUM(unsigned short, kMASShortcutGlyph) {
kMASShortcutGlyphSoutheastArrow = 0x2198,
};
// The missing function key definitions for `NS*FunctionKey`s
typedef NS_ENUM(unsigned short, kMASShortcutFuctionKey) {
kMASShortcutEscapeFunctionKey = 0x001B,
kMASShortcutDeleteFunctionKey = 0x0008,
kMASShortcutSpaceFunctionKey = 0x0020,
kMASShortcutReturnFunctionKey = 0x000D,
kMASShortcutTabFunctionKey = 0x0009,
};
NS_INLINE NSString* NSStringFromMASKeyCode(unsigned short ch)
{
return [NSString stringWithFormat:@"%C", ch];
@@ -34,6 +42,13 @@ NS_INLINE NSUInteger MASPickCocoaModifiers(NSUInteger flags)
return (flags & (NSEventModifierFlagControl | NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagCommand));
}
// Used in `-[MASShortcutValidator isShortcut:alreadyTakenInMenu:explanation:]`.
// This prevents incorrectly detecting an overlap with any shortcuts using the `fn` key.
NS_INLINE NSUInteger MASPickModifiersIncludingFn(NSUInteger flags)
{
return (flags & (NSEventModifierFlagControl | NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagCommand | NSEventModifierFlagFunction));
}
NS_INLINE UInt32 MASCarbonModifiersFromCocoaModifiers(NSUInteger cocoaFlags)
{
return
-18
View File
@@ -1,18 +0,0 @@
#import <Availability.h>
// https://github.com/shpakovski/MASShortcut/issues/99
//
// Long story short: NSControlKeyMask and friends were replaced with NSEventModifierFlagControl
// and similar in macOS Sierra. The project builds fine & clean, but including MASShortcut in
// a project with deployment target set to 10.12 results in several deprecation warnings because
// of the control masks. Simply replacing the old symbols with the new ones isnt an option,
// since it breaks the build on older SDKs in Travis, for example.
//
// It should be safe to remove this whole thing once the 10.12 SDK is ubiquitous.
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSEventModifierFlagCommand NSCommandKeyMask
#define NSEventModifierFlagControl NSControlKeyMask
#define NSEventModifierFlagOption NSAlternateKeyMask
#define NSEventModifierFlagShift NSShiftKeyMask
#endif
+6 -6
View File
@@ -45,7 +45,7 @@
to be precise) the `keyCodeString` is `2` on the US keyboard, but `ě` when
the Czech keyboard layout is active. See the spec for details.
*/
@property (nonatomic, readonly) NSString *keyCodeString;
@property (nonatomic, readonly, nullable) NSString *keyCodeString;
/**
A key-code string used in key equivalent matching.
@@ -61,21 +61,21 @@
thats always displayed as `^U`. So the `keyCodeString` returns `Г`
and `keyCodeStringForKeyEquivalent` returns `U`.
*/
@property (nonatomic, readonly) NSString *keyCodeStringForKeyEquivalent;
@property (nonatomic, readonly, nullable) NSString *keyCodeStringForKeyEquivalent;
/**
A string representing the shortcut modifiers, like the `⌘` in `⌘5`.
*/
@property (nonatomic, readonly) NSString *modifierFlagsString;
@property (nonatomic, readonly, nonnull) NSString *modifierFlagsString;
- (instancetype)initWithKeyCode:(NSInteger)code modifierFlags:(NSEventModifierFlags)flags;
+ (instancetype)shortcutWithKeyCode:(NSInteger)code modifierFlags:(NSEventModifierFlags)flags;
- (nonnull instancetype)initWithKeyCode:(NSInteger)code modifierFlags:(NSEventModifierFlags)flags;
+ (nonnull instancetype)shortcutWithKeyCode:(NSInteger)code modifierFlags:(NSEventModifierFlags)flags;
/**
Creates a new shortcut from an `NSEvent` object.
This is just a convenience initializer that reads the key code and modifiers from an `NSEvent`.
*/
+ (instancetype)shortcutWithEvent:(NSEvent *)anEvent;
+ (nonnull instancetype)shortcutWithEvent:(nonnull NSEvent *)anEvent;
@end
+24 -15
View File
@@ -49,10 +49,6 @@ static NSString *const MASShortcutModifierFlags = @"ModifierFlags";
{
NSString *keyCodeString = self.keyCodeString;
if (keyCodeString.length <= 1) {
return keyCodeString.lowercaseString;
}
switch (self.keyCode) {
case kVK_F1: return NSStringFromMASKeyCode(NSF1FunctionKey);
case kVK_F2: return NSStringFromMASKeyCode(NSF2FunctionKey);
@@ -73,9 +69,24 @@ static NSString *const MASShortcutModifierFlags = @"ModifierFlags";
case kVK_F17: return NSStringFromMASKeyCode(NSF17FunctionKey);
case kVK_F18: return NSStringFromMASKeyCode(NSF18FunctionKey);
case kVK_F19: return NSStringFromMASKeyCode(NSF19FunctionKey);
case kVK_Space: return NSStringFromMASKeyCode(0x20);
default: return @"";
case kVK_Space: return NSStringFromMASKeyCode(kMASShortcutSpaceFunctionKey);
case kVK_Escape: return NSStringFromMASKeyCode(kMASShortcutEscapeFunctionKey);
case kVK_Delete: return NSStringFromMASKeyCode(NSBackspaceCharacter);
case kVK_ForwardDelete: return NSStringFromMASKeyCode(NSDeleteFunctionKey);
case kVK_LeftArrow: return NSStringFromMASKeyCode(NSLeftArrowFunctionKey);
case kVK_RightArrow: return NSStringFromMASKeyCode(NSRightArrowFunctionKey);
case kVK_UpArrow: return NSStringFromMASKeyCode(NSUpArrowFunctionKey);
case kVK_DownArrow: return NSStringFromMASKeyCode(NSDownArrowFunctionKey);
case kVK_Help: return NSStringFromMASKeyCode(NSHelpFunctionKey);
case kVK_Home: return NSStringFromMASKeyCode(NSHomeFunctionKey);
case kVK_End: return NSStringFromMASKeyCode(NSEndFunctionKey);
case kVK_PageUp: return NSStringFromMASKeyCode(NSPageUpFunctionKey);
case kVK_PageDown: return NSStringFromMASKeyCode(NSPageDownFunctionKey);
case kVK_Tab: return NSStringFromMASKeyCode(kMASShortcutTabFunctionKey);
case kVK_Return: return NSStringFromMASKeyCode(kMASShortcutReturnFunctionKey);
}
return keyCodeString.lowercaseString;
}
- (NSString *)keyCodeString
@@ -110,7 +121,9 @@ static NSString *const MASShortcutModifierFlags = @"ModifierFlags";
case kVK_RightArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphRightArrow);
case kVK_UpArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphUpArrow);
case kVK_DownArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphDownArrow);
case kVK_Help: return NSStringFromMASKeyCode(kMASShortcutGlyphHelp);
case kVK_Help: return NSStringFromMASKeyCode(kMASShortcutGlyphHelp); // Insert
case kVK_Home: return NSStringFromMASKeyCode(kMASShortcutGlyphNorthwestArrow);
case kVK_End: return NSStringFromMASKeyCode(kMASShortcutGlyphSoutheastArrow);
case kVK_PageUp: return NSStringFromMASKeyCode(kMASShortcutGlyphPageUp);
case kVK_PageDown: return NSStringFromMASKeyCode(kMASShortcutGlyphPageDown);
case kVK_Tab: return NSStringFromMASKeyCode(kMASShortcutGlyphTabRight);
@@ -135,10 +148,6 @@ static NSString *const MASShortcutModifierFlags = @"ModifierFlags";
case kVK_ANSI_KeypadEnter: return NSStringFromMASKeyCode(kMASShortcutGlyphReturn);
case kVK_ANSI_KeypadMinus: return @"-";
case kVK_ANSI_KeypadEquals: return @"=";
// Hardcode
case 119: return NSStringFromMASKeyCode(kMASShortcutGlyphSoutheastArrow);
case 115: return NSStringFromMASKeyCode(kMASShortcutGlyphNorthwestArrow);
}
// Everything else should be printable so look it up in the current ASCII capable keyboard layout
@@ -186,10 +195,10 @@ static NSString *const MASShortcutModifierFlags = @"ModifierFlags";
unichar chars[4];
NSUInteger count = 0;
// These are in the same order as the menu manager shows them
if (self.modifierFlags & NSControlKeyMask) chars[count++] = kControlUnicode;
if (self.modifierFlags & NSAlternateKeyMask) chars[count++] = kOptionUnicode;
if (self.modifierFlags & NSShiftKeyMask) chars[count++] = kShiftUnicode;
if (self.modifierFlags & NSCommandKeyMask) chars[count++] = kCommandUnicode;
if (self.modifierFlags & NSEventModifierFlagControl) chars[count++] = kControlUnicode;
if (self.modifierFlags & NSEventModifierFlagOption) chars[count++] = kOptionUnicode;
if (self.modifierFlags & NSEventModifierFlagShift) chars[count++] = kShiftUnicode;
if (self.modifierFlags & NSEventModifierFlagCommand) chars[count++] = kCommandUnicode;
return (count ? [NSString stringWithCharacters:chars length:count] : @"");
}
+4 -4
View File
@@ -5,10 +5,10 @@
- (void) testEquality
{
MASShortcut *keyA = [MASShortcut shortcutWithKeyCode:1 modifierFlags:NSControlKeyMask];
MASShortcut *keyB = [MASShortcut shortcutWithKeyCode:2 modifierFlags:NSControlKeyMask];
MASShortcut *keyC = [MASShortcut shortcutWithKeyCode:1 modifierFlags:NSAlternateKeyMask];
MASShortcut *keyD = [MASShortcut shortcutWithKeyCode:1 modifierFlags:NSControlKeyMask];
MASShortcut *keyA = [MASShortcut shortcutWithKeyCode:1 modifierFlags:NSEventModifierFlagControl];
MASShortcut *keyB = [MASShortcut shortcutWithKeyCode:2 modifierFlags:NSEventModifierFlagControl];
MASShortcut *keyC = [MASShortcut shortcutWithKeyCode:1 modifierFlags:NSEventModifierFlagOption];
MASShortcut *keyD = [MASShortcut shortcutWithKeyCode:1 modifierFlags:NSEventModifierFlagControl];
XCTAssertTrue([keyA isEqual:keyA], @"Shortcut is equal to itself.");
XCTAssertTrue([keyA isEqual:[keyA copy]], @"Shortcut is equal to its copy.");
XCTAssertFalse([keyA isEqual:keyB], @"Shortcuts not equal when key codes differ.");
+11
View File
@@ -20,6 +20,17 @@
*/
@property(assign) BOOL allowAnyShortcutWithOptionModifier;
/**
Set to `YES` if you want to accept shortcuts that override the Services menu
item.
`NO` by default. Set to `YES` to allow shortcuts to override key equivalents of
Services menu items. This can prevent users from being confused when they can't
find the conflicting menu item since menu items in the Services menu are not
always visible.
*/
@property(assign) BOOL allowOverridingServicesShortcut;
+ (instancetype) sharedValidator;
- (BOOL) isShortcutValid: (MASShortcut*) shortcut;
+9 -5
View File
@@ -31,12 +31,12 @@
if (!hasModifierFlags) return NO;
// Allow any hotkey containing Control or Command modifier
BOOL includesCommand = ((modifiers & NSCommandKeyMask) > 0);
BOOL includesControl = ((modifiers & NSControlKeyMask) > 0);
BOOL includesCommand = ((modifiers & NSEventModifierFlagCommand) > 0);
BOOL includesControl = ((modifiers & NSEventModifierFlagControl) > 0);
if (includesCommand || includesControl) return YES;
// Allow Option key only in selected cases
BOOL includesOption = ((modifiers & NSAlternateKeyMask) > 0);
BOOL includesOption = ((modifiers & NSEventModifierFlagOption) > 0);
if (includesOption) {
// Always allow Option-Space and Option-Escape because they do not have any bind system commands
@@ -52,19 +52,23 @@
- (BOOL) isShortcut: (MASShortcut*) shortcut alreadyTakenInMenu: (NSMenu*) menu explanation: (NSString**) explanation
{
if (self.allowOverridingServicesShortcut && menu == [NSApp servicesMenu]) {
return NO;
}
NSString *keyEquivalent = [shortcut keyCodeStringForKeyEquivalent];
NSEventModifierFlags flags = [shortcut modifierFlags];
for (NSMenuItem *menuItem in menu.itemArray) {
if (menuItem.hasSubmenu && [self isShortcut:shortcut alreadyTakenInMenu:[menuItem submenu] explanation:explanation]) return YES;
BOOL equalFlags = (MASPickCocoaModifiers(menuItem.keyEquivalentModifierMask) == flags);
BOOL equalFlags = (MASPickModifiersIncludingFn(menuItem.keyEquivalentModifierMask) == flags);
BOOL equalHotkeyLowercase = [menuItem.keyEquivalent.lowercaseString isEqualToString:keyEquivalent];
// Check if the cases are different, we know ours is lower and that shift is included in our modifiers
// If theirs is capitol, we need to add shift to their modifiers
if (equalHotkeyLowercase && ![menuItem.keyEquivalent isEqualToString:keyEquivalent]) {
equalFlags = (MASPickCocoaModifiers(menuItem.keyEquivalentModifierMask | NSShiftKeyMask) == flags);
equalFlags = (MASPickModifiersIncludingFn(menuItem.keyEquivalentModifierMask | NSEventModifierFlagShift) == flags);
}
if (equalFlags && equalHotkeyLowercase) {
+1 -1
View File
@@ -8,7 +8,7 @@
- (void) testBasicFunctionality
{
MASHotKey *hotKey = [MASHotKey registeredHotKeyWithShortcut:
[MASShortcut shortcutWithKeyCode:kVK_ANSI_H modifierFlags:NSCommandKeyMask|NSAlternateKeyMask]];
[MASShortcut shortcutWithKeyCode:kVK_ANSI_H modifierFlags:NSEventModifierFlagCommand|NSEventModifierFlagOption]];
XCTAssertNotNil(hotKey, @"Register a simple Cmd-Alt-H hotkey.");
}
@@ -13,7 +13,7 @@
- (void) testShortcutRegistration
{
MASShortcutMonitor *monitor = [MASShortcutMonitor sharedMonitor];
MASShortcut *shortcut = [MASShortcut shortcutWithKeyCode:kVK_ANSI_H modifierFlags:NSCommandKeyMask|NSAlternateKeyMask];
MASShortcut *shortcut = [MASShortcut shortcutWithKeyCode:kVK_ANSI_H modifierFlags:NSEventModifierFlagCommand|NSEventModifierFlagOption];
XCTAssertTrue([monitor registerShortcut:shortcut withAction:NULL], @"Register a shortcut.");
XCTAssertTrue([monitor isShortcutRegistered:shortcut], @"Remember a previously registered shortcut.");
[monitor unregisterShortcut:shortcut];
@@ -8,40 +8,40 @@
"Delete shortcut" = "Borrar atajo";
/* VoiceOver title */
"keyboard shortcut" = "atajo de teklado";
"keyboard shortcut" = "función rápida de teclado";
/* Alert button when shortcut is already used */
"OK" = "OK";
/* Empty shortcut button in normal state */
"Record Shortcut" = "Grabar atajo";
"Record Shortcut" = "Grabar Función rápida";
/* VoiceOver: Shortcut cleared */
"Shortcut cleared" = "Atajo borrado";
"Shortcut cleared" = "Función rápida eliminada";
/* VoiceOver: Shortcut set */
"Shortcut set" = "Atajo creado";
"Shortcut set" = "Función rápida creada";
/* Shortcut glyph name for SPACE key */
"Space" = "Espacio";
/* Title for alert when shortcut is already used */
"The key combination %@ cannot be used" = "La combinación de claves %@ no se puede utilizada";
"The key combination %@ cannot be used" = "La combinación de teclas %@ no puede ser utilizada";
/* Message for alert when shortcut is already used by the system */
"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Esta combinación no se puede utilizar debido a que ya es en us como atajo del sistema.\nSi realmente desea utilizar esta combinación de teclas, la mayoría de los atajos se puede cambiar en el panel de Teclado y Ratón de Preferencias del Sistema.";
"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Esta combinación no puede ser utilizar debido a que es una función rápida del sistema.\nSi realmente desea utilizar esta combinación de teclas, la mayoría de las funciones rápidas se puede cambiar en el Panel de Teclado en las Preferencias del sistema.";
/* Message for alert when shortcut is already used */
"This shortcut cannot be used because it is already used by the menu item %@." = "Este atajo no se puede utilizar debido a que ya es utilizado por el elemento de menú '%@'.";
"This shortcut cannot be used because it is already used by the menu item %@." = "Esta función rápida no se puede utilizar debido a que ya está siendo utilizada por el elemento de menú '%@'.";
/* VoiceOver shortcut help */
"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Para grabar un nuevo atajo, haga clic en este botón, a continuar, escriba el nuevo atajo, o pulse borrar para qutar un atajo existente.";
"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Para grabar una nueva función rápida, haga clic en este botón, y luego teclee la nueva función rápida, o pulse borrar para quitar una función rápida existente.";
/* Non-empty shortcut button in recording state */
"Type New Shortcut" = "Escribir atajo";
"Type New Shortcut" = "Teclee la nueva función rápida";
/* Empty shortcut button in recording state */
"Type Shortcut" = "Escribir atajo";
"Type Shortcut" = "Teclee la función rápida";
/* Cancel action button for non-empty shortcut in recording state */
"Use Old Shortcut" = "Usa atajo anterior";
"Use Old Shortcut" = "Usar una función rápida previa";
@@ -2,25 +2,25 @@
"Cancel" = "Annulla";
/* Tooltip for non-empty shortcut button */
"Click to record new shortcut" = "Cliccare per registrare una nuova combinazione";
"Click to record new shortcut" = "Fai clic per registrare una nuova abbreviazione";
/* Tooltip for hint button near the non-empty shortcut */
"Delete shortcut" = "Cancella scorciatoia";
"Delete shortcut" = "Cancella abbreviazione";
/* VoiceOver title */
"keyboard shortcut" = "Scorciatoia da tastiera";
"keyboard shortcut" = "Abbreviazione da tastiera";
/* Alert button when shortcut is already used */
"OK" = "OK";
/* Empty shortcut button in normal state */
"Record Shortcut" = "Registra scorciatoia";
"Record Shortcut" = "Registra abbreviazione";
/* VoiceOver: Shortcut cleared */
"Shortcut cleared" = "Scorciatoia rimossa";
"Shortcut cleared" = "Abbreviazione rimossa";
/* VoiceOver: Shortcut set */
"Shortcut set" = "Scorciatoia impostata";
"Shortcut set" = "Abbreviazione impostata";
/* Shortcut glyph name for SPACE key */
"Space" = "Spazio";
@@ -29,19 +29,19 @@
"The key combination %@ cannot be used" = "Questa combinazione %@ di tasti non può essere usata";
/* Message for alert when shortcut is already used by the system */
"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Questa combinazione di tasti non può essere usata perchè è già usata da una scorciatoia da tastiera a livello di Sistema.\nSe volete davvero usare questa combinazione di tasti, la maggior parte delle scorciatoie possono essere cambiate nel pannello Tastiera e Mouse delle Preferenze di Sistema.";
"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Questa combinazione di tasti non può essere usata perché già assegnata a un'abbreviazione da tastiera a livello di Sistema.\nSe vuoi davvero usare questa combinazione di tasti, puoi modificare la maggior parte delle abbreviazioni nei pannelli Tastiera e Mouse delle Preferenze di Sistema.";
/* Message for alert when shortcut is already used */
"This shortcut cannot be used because it is already used by the menu item %@." = "Questa combinazione di tasti non può essere usata perchè è già usata dalla voce di menù %@.";
"This shortcut cannot be used because it is already used by the menu item %@." = "Questa combinazione di tasti non può essere usata perché già usata dalla voce di menu %@.";
/* VoiceOver shortcut help */
"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Per registrare una nuova scorciatoia, cliccare su questo pulsante e poi inserire la muova scorciatoia o premere cancella per resettare una scorciatoia esistente.";
"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Per registrare una nuova abbreviazione fai clic su questo pulsante, quindi inserisci i tasti della nuova abbreviazione o premi cancella per ripristinare un'abbreviazione esistente.";
/* Non-empty shortcut button in recording state */
"Type New Shortcut" = "Digita nuova";
"Type New Shortcut" = "Digita nuova abbreviazione";
/* Empty shortcut button in recording state */
"Type Shortcut" = "Digita scorciatoia";
"Type Shortcut" = "Digita abbreviazione";
/* Cancel action button for non-empty shortcut in recording state */
"Use Old Shortcut" = "Usare vecchia";
"Use Old Shortcut" = "Usa abbreviazione precedente";
@@ -2,46 +2,46 @@
"Cancel" = "取消";
/* Tooltip for non-empty shortcut button */
"Click to record new shortcut" = "點選以記錄新快鍵";
"Click to record new shortcut" = "按一下以記錄新快鍵";
/* Tooltip for hint button near the non-empty shortcut */
"Delete shortcut" = "刪除快鍵";
"Delete shortcut" = "刪除快鍵";
/* VoiceOver title */
"keyboard shortcut" = "鍵盤快鍵";
"keyboard shortcut" = "鍵盤快鍵";
/* Alert button when shortcut is already used */
"OK" = "好";
/* Empty shortcut button in normal state */
"Record Shortcut" = "記錄快鍵";
"Record Shortcut" = "記錄快鍵";
/* VoiceOver: Shortcut cleared */
"Shortcut cleared" = "快鍵已清除";
"Shortcut cleared" = "快鍵已清除";
/* VoiceOver: Shortcut set */
"Shortcut set" = "快鍵已設定";
"Shortcut set" = "快鍵已設定";
/* Shortcut glyph name for SPACE key */
"Space" = "空格鍵";
/* Title for alert when shortcut is already used */
"The key combination %@ cannot be used" = "按鍵組合%@無法使用";
"The key combination %@ cannot be used" = "按鍵組合%@無法使用";
/* Message for alert when shortcut is already used by the system */
"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "前按鍵組合無法使用,因為它已經用作其他系統全局快捷鍵。\n如果您真的想使用這個按鍵組合,大部分系統全局快捷鍵能在“系統偏好設定裡的鍵盤”和“滑鼠面板中重設。";
"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "前按鍵組合無法使用,因為它已經用作其他系統全域快速鍵。\n如果您真的想使用按鍵組合,大部分系統全域快速鍵可在「系統偏好設定裡的鍵盤」和「滑鼠面板中變更。";
/* Message for alert when shortcut is already used */
"This shortcut cannot be used because it is already used by the menu item %@." = "前快鍵無法使用,因為它已用作選單項%@的快鍵。";
"This shortcut cannot be used because it is already used by the menu item %@." = "前快鍵無法使用,因為它已用作選單項目「%@的快鍵。";
/* VoiceOver shortcut help */
"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "若要記錄新的快鍵,單擊此按鈕,然後入新的快鍵,或者按delete鍵刪除已經存在的快鍵。";
"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "若要記錄新的快鍵,按一下此按鈕,然後入新的快鍵,或者按delete鍵刪除已經存在的快鍵。";
/* Non-empty shortcut button in recording state */
"Type New Shortcut" = "入新快鍵";
"Type New Shortcut" = "入新快鍵";
/* Empty shortcut button in recording state */
"Type Shortcut" = "入快鍵";
"Type Shortcut" = "入快鍵";
/* Cancel action button for non-empty shortcut in recording state */
"Use Old Shortcut" = "還原快鍵";
"Use Old Shortcut" = "還原快鍵";
+2 -1
View File
@@ -1,4 +1,4 @@
#import "MASKeyMasks.h"
#import <AppKit/AppKit.h>
#import "MASShortcut.h"
#import "MASShortcutValidator.h"
#import "MASShortcutMonitor.h"
@@ -6,3 +6,4 @@
#import "MASDictionaryTransformer.h"
#import "MASShortcutView.h"
#import "MASShortcutView+Bindings.h"
#import "MASShortcutViewButtonCell.h"
+1 -1
View File
@@ -10,4 +10,4 @@
NSLocalizedString throughout the framework, it wouldnt work
properly.
*/
NSString *MASLocalizedString(NSString *key, NSString *comment);
NSString *MASLocalizedString(NSString *key, NSString *comment);
+15 -11
View File
@@ -12,21 +12,25 @@ NSString *MASLocalizedString(NSString *key, NSString *comment) {
static NSBundle *localizationBundle = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSBundle *frameworkBundle = [NSBundle bundleForClass:[MASShortcut class]];
// first we'll check if resources bundle was copied to MASShortcut framework bundle when !use_frameworks option is active
NSURL *cocoaPodsBundleURL = [frameworkBundle URLForResource:@"MASShortcut" withExtension:@"bundle"];
if (cocoaPodsBundleURL) {
localizationBundle = [NSBundle bundleWithURL: cocoaPodsBundleURL];
} else {
// trying to fetch cocoapods bundle from main bundle
cocoaPodsBundleURL = [[NSBundle mainBundle] URLForResource: @"MASShortcut" withExtension:@"bundle"];
#if SWIFT_PACKAGE
localizationBundle = SWIFTPM_MODULE_BUNDLE;
#else
NSBundle *frameworkBundle = [NSBundle bundleForClass:[MASShortcut class]];
// first we'll check if resources bundle was copied to MASShortcut framework bundle when !use_frameworks option is active
NSURL *cocoaPodsBundleURL = [frameworkBundle URLForResource:@"MASShortcut" withExtension:@"bundle"];
if (cocoaPodsBundleURL) {
localizationBundle = [NSBundle bundleWithURL: cocoaPodsBundleURL];
} else {
// fallback to framework bundle
localizationBundle = frameworkBundle;
// trying to fetch cocoapods bundle from main bundle
cocoaPodsBundleURL = [[NSBundle mainBundle] URLForResource: @"MASShortcut" withExtension:@"bundle"];
if (cocoaPodsBundleURL) {
localizationBundle = [NSBundle bundleWithURL: cocoaPodsBundleURL];
} else {
// fallback to framework bundle
localizationBundle = frameworkBundle;
}
}
}
#endif
});
return [localizationBundle localizedStringForKey:key
value:MASPlaceholderLocalizationString
+4 -3
View File
@@ -1,3 +1,4 @@
#import <AppKit/AppKit.h>
#import "MASShortcutView.h"
/**
@@ -17,9 +18,9 @@
*/
@interface MASShortcutView (Bindings)
@property(copy) NSString *associatedUserDefaultsKey;
@property(copy, nullable) NSString *associatedUserDefaultsKey;
- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformer: (NSValueTransformer*) transformer;
- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformerName: (NSString*) transformerName;
- (void) setAssociatedUserDefaultsKey: (nullable NSString*) newKey withTransformer: (nullable NSValueTransformer*) transformer;
- (void) setAssociatedUserDefaultsKey: (nullable NSString*) newKey withTransformerName: (nullable NSString*) transformerName;
@end
+2 -7
View File
@@ -16,14 +16,9 @@
- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformer: (NSValueTransformer*) transformer
{
// Break previous binding if any
NSString *currentKey = [self associatedUserDefaultsKey];
if (currentKey != nil) {
[self unbind:currentKey];
}
// Stop if the new binding is nil
// Break previous binding if the new binding is nil
if (newKey == nil) {
[self unbind:MASShortcutBinding];
return;
}
+9 -6
View File
@@ -1,25 +1,28 @@
#import <AppKit/AppKit.h>
@class MASShortcut, MASShortcutValidator;
extern NSString *const MASShortcutBinding;
extern NSString * _Nonnull const MASShortcutBinding;
typedef NS_ENUM(NSInteger, MASShortcutViewStyle) {
MASShortcutViewStyleDefault = 0, // Height = 19 px
MASShortcutViewStyleTexturedRect, // Height = 25 px
MASShortcutViewStyleRounded, // Height = 43 px
MASShortcutViewStyleFlat
MASShortcutViewStyleFlat,
MASShortcutViewStyleRegularSquare
};
@interface MASShortcutView : NSView
@property (nonatomic, strong) MASShortcut *shortcutValue;
@property (nonatomic, strong) MASShortcutValidator *shortcutValidator;
@property (nonatomic, strong, nullable) MASShortcut *shortcutValue;
@property (nonatomic, strong, nullable) MASShortcutValidator *shortcutValidator;
@property (nonatomic, getter = isRecording) BOOL recording;
@property (nonatomic, getter = isEnabled) BOOL enabled;
@property (nonatomic, copy) void (^shortcutValueChange)(MASShortcutView *sender);
@property (nonatomic, copy, nullable) void (^shortcutValueChange)(MASShortcutView * _Nonnull sender);
@property (nonatomic, assign) MASShortcutViewStyle style;
/// Returns custom class for drawing control.
+ (Class)shortcutCellClass;
+ (nonnull Class)shortcutCellClass;
- (void)setAcceptsFirstResponder:(BOOL)value;
+35 -28
View File
@@ -1,6 +1,7 @@
#import "MASShortcutView.h"
#import "MASShortcutValidator.h"
#import "MASLocalization.h"
#import "MASShortcutViewButtonCell.h"
NSString *const MASShortcutBinding = @"shortcutValue";
@@ -20,7 +21,7 @@ static const CGFloat MASButtonFontSize = 11;
#pragma mark -
@implementation MASShortcutView {
NSButtonCell *_shortcutCell;
MASShortcutViewButtonCell *_shortcutCell;
NSInteger _shortcutToolTipTag;
NSInteger _hintToolTipTag;
NSTrackingArea *_hintArea;
@@ -31,7 +32,7 @@ static const CGFloat MASButtonFontSize = 11;
+ (Class)shortcutCellClass
{
return [NSButtonCell class];
return [MASShortcutViewButtonCell class];
}
- (id)initWithFrame:(CGRect)frameRect
@@ -55,7 +56,7 @@ static const CGFloat MASButtonFontSize = 11;
- (void)commonInit
{
_shortcutCell = [[[self.class shortcutCellClass] alloc] init];
_shortcutCell.buttonType = NSPushOnPushOffButton;
_shortcutCell.buttonType = NSButtonTypePushOnPushOff;
_shortcutCell.font = [[NSFontManager sharedFontManager] convertFont:_shortcutCell.font toSize:MASButtonFontSize];
_shortcutValidator = [MASShortcutValidator sharedValidator];
_enabled = YES;
@@ -97,15 +98,15 @@ static const CGFloat MASButtonFontSize = 11;
{
switch (_style) {
case MASShortcutViewStyleDefault: {
_shortcutCell.bezelStyle = NSRoundRectBezelStyle;
_shortcutCell.bezelStyle = NSBezelStyleRoundRect;
break;
}
case MASShortcutViewStyleTexturedRect: {
_shortcutCell.bezelStyle = NSTexturedRoundedBezelStyle;
_shortcutCell.bezelStyle = NSBezelStyleTexturedRounded;
break;
}
case MASShortcutViewStyleRounded: {
_shortcutCell.bezelStyle = NSRoundedBezelStyle;
_shortcutCell.bezelStyle = NSBezelStyleRounded;
break;
}
case MASShortcutViewStyleFlat: {
@@ -114,6 +115,10 @@ static const CGFloat MASButtonFontSize = 11;
_shortcutCell.bordered = NO;
break;
}
case MASShortcutViewStyleRegularSquare: {
_shortcutCell.bezelStyle = NSBezelStyleRegularSquare;
break;
}
}
}
@@ -201,24 +206,21 @@ static const CGFloat MASButtonFontSize = 11;
_shortcutCell.state = state;
_shortcutCell.enabled = self.enabled;
CGFloat yOffset;
switch (_style) {
case MASShortcutViewStyleDefault: {
[_shortcutCell drawWithFrame:frame inView:self];
case MASShortcutViewStyleTexturedRect:
case MASShortcutViewStyleRounded:
case MASShortcutViewStyleRegularSquare: {
yOffset = 1.0;
break;
}
case MASShortcutViewStyleTexturedRect: {
[_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self];
default:
yOffset = 0.0;
break;
}
case MASShortcutViewStyleRounded: {
[_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self];
break;
}
case MASShortcutViewStyleFlat: {
[_shortcutCell drawWithFrame:frame inView:self];
break;
}
}
[_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, yOffset) inView:self];
}
- (void)drawRect:(CGRect)dirtyRect
@@ -231,7 +233,7 @@ static const CGFloat MASButtonFontSize = 11;
buttonTitle = NSStringFromMASKeyCode(kMASShortcutGlyphClear);
}
if (buttonTitle != nil) {
[self drawInRect:self.bounds withTitle:buttonTitle alignment:NSRightTextAlignment state:NSOffState];
[self drawInRect:self.bounds withTitle:buttonTitle alignment:NSTextAlignmentRight state:NSControlStateValueOff];
}
CGRect shortcutRect;
[self getShortcutRect:&shortcutRect hintRect:NULL];
@@ -242,12 +244,12 @@ static const CGFloat MASButtonFontSize = 11;
? self.shortcutPlaceholder
: MASLocalizedString(@"Type New Shortcut", @"Non-empty shortcut button in recording state")))
: _shortcutValue ? _shortcutValue.description : @"");
[self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:self.isRecording ? NSOnState : NSOffState];
[self drawInRect:shortcutRect withTitle:title alignment:NSTextAlignmentCenter state:self.isRecording ? NSControlStateValueOn : NSControlStateValueOff];
}
else {
if (self.recording)
{
[self drawInRect:self.bounds withTitle:NSStringFromMASKeyCode(kMASShortcutGlyphEscape) alignment:NSRightTextAlignment state:NSOffState];
[self drawInRect:self.bounds withTitle:NSStringFromMASKeyCode(kMASShortcutGlyphEscape) alignment:NSTextAlignmentRight state:NSControlStateValueOff];
CGRect shortcutRect;
[self getShortcutRect:&shortcutRect hintRect:NULL];
@@ -256,12 +258,12 @@ static const CGFloat MASButtonFontSize = 11;
: (self.shortcutPlaceholder.length > 0
? self.shortcutPlaceholder
: MASLocalizedString(@"Type Shortcut", @"Empty shortcut button in recording state")));
[self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:NSOnState];
[self drawInRect:shortcutRect withTitle:title alignment:NSTextAlignmentCenter state:NSControlStateValueOn];
}
else
{
[self drawInRect:self.bounds withTitle:MASLocalizedString(@"Record Shortcut", @"Empty shortcut button in normal state")
alignment:NSCenterTextAlignment state:NSOffState];
alignment:NSTextAlignmentCenter state:NSControlStateValueOff];
}
}
}
@@ -276,7 +278,7 @@ static const CGFloat MASButtonFontSize = 11;
// calculate the intrinsic size without refactoring the code. That would give better results,
// however.
// 120 is an arbitray number that seems to be wide enough for English localization. This
// 120 is an arbitrary number that seems to be wide enough for English localization. This
// may need to be adjusted for other locales/languages.
// NOTE: Simply returning cellSize results in a display that is sometimes correct
@@ -434,7 +436,7 @@ void *kUserDataHint = &kUserDataHint;
static id eventMonitor = nil;
if (shouldActivate) {
__unsafe_unretained MASShortcutView *weakSelf = self;
NSEventMask eventMask = (NSKeyDownMask | NSFlagsChangedMask);
NSEventMask eventMask = (NSEventMaskKeyDown | NSEventMaskFlagsChanged);
eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) {
// Create a shortcut from the event
@@ -459,7 +461,7 @@ void *kUserDataHint = &kUserDataHint;
}
// If the shortcut is Cmd-W or Cmd-Q, cancel recording and pass the event through
else if ((shortcut.modifierFlags == NSCommandKeyMask) && (shortcut.keyCode == kVK_ANSI_W || shortcut.keyCode == kVK_ANSI_Q)) {
else if ((shortcut.modifierFlags == NSEventModifierFlagCommand) && (shortcut.keyCode == kVK_ANSI_W || shortcut.keyCode == kVK_ANSI_Q)) {
weakSelf.recording = NO;
}
@@ -476,7 +478,7 @@ void *kUserDataHint = &kUserDataHint;
NSString *format = MASLocalizedString(@"The key combination %@ cannot be used",
@"Title for alert when shortcut is already used");
NSAlert* alert = [[NSAlert alloc]init];
alert.alertStyle = NSCriticalAlertStyle;
alert.alertStyle = NSAlertStyleCritical;
alert.informativeText = explanation;
alert.messageText = [NSString stringWithFormat:format, shortcut];
[alert addButtonWithTitle:MASLocalizedString(@"OK", @"Alert button when shortcut is already used")];
@@ -579,6 +581,11 @@ void *kUserDataHint = &kUserDataHint;
#pragma mark - Accessibility
- (BOOL)isAccessibilityElement
{
return YES;
}
- (NSString *)accessibilityHelp
{
return MASLocalizedString(@"To record a new shortcut, click this button, and then type the"
+9
View File
@@ -0,0 +1,9 @@
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface MASShortcutViewButtonCell : NSButtonCell
@end
NS_ASSUME_NONNULL_END
+29
View File
@@ -0,0 +1,29 @@
#import "MASShortcutViewButtonCell.h"
@implementation MASShortcutViewButtonCell
-(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
CGRect paddedFrame = cellFrame;
//fix display on Big Sur
if (@available(macOS 11, *)) {
//fix vertical alignment
paddedFrame.origin.y -= 1.0;
//fix cancel button alignment
if (self.alignment == NSTextAlignmentRight &&
(self.bezelStyle == NSBezelStyleTexturedRounded ||
self.bezelStyle == NSBezelStyleRounded)) {
paddedFrame.size.width -= 14.0;
if (self.bezelStyle == NSBezelStyleTexturedRounded)
paddedFrame.origin.x += 7.0;
}
}
[super drawInteriorWithFrame:paddedFrame inView:controlView];
}
@end
@@ -1,3 +1,5 @@
#import <AppKit/AppKit.h>
extern NSString *const MASDictionaryTransformerName;
/**
@@ -12,7 +14,7 @@ extern NSString *const MASDictionaryTransformerName;
that converts any `NSCoding` types to `NSData`, but with shortcuts
it makes sense to use a dictionary instead the defaults look better
when inspected with the `defaults` command-line utility and the
format is compatible with an older sortcut library called Shortcut
format is compatible with an older shortcut library called Shortcut
Recorder.
*/
@interface MASDictionaryTransformer : NSValueTransformer
@@ -9,7 +9,7 @@
XCTAssertNil([transformer transformedValue:nil],
@"Decoding a shortcut from a nil dictionary returns nil.");
XCTAssertNil([transformer transformedValue:(id)@"foo"],
@"Decoding a shortcut from a invalid-type dictionary returns nil.");
@"Decoding a shortcut from an invalid-type dictionary returns nil.");
XCTAssertNil([transformer transformedValue:@{}],
@"Decoding a shortcut from an empty dictionary returns nil.");
XCTAssertNil([transformer transformedValue:@{@"keyCode":@"foo"}],
@@ -57,7 +57,7 @@
/**
Register default shortcuts in user defaults.
This is a convenience frontent to `[NSUserDefaults registerDefaults]`.
This is a convenience frontend to `[NSUserDefaults registerDefaults]`.
The dictionary should contain a map of user defaults keys to appropriate
keyboard shortcuts. The shortcuts will be transformed according to
`bindingOptions` and registered using `registerDefaults`.
+1
View File
@@ -0,0 +1 @@
../User Defaults Storage/MASDictionaryTransformer.h
+1
View File
@@ -0,0 +1 @@
../Monitoring/MASHotKey.h
+1
View File
@@ -0,0 +1 @@
../Model/MASKeyCodes.h
+1
View File
@@ -0,0 +1 @@
../UI/MASLocalization.h
+1
View File
@@ -0,0 +1 @@
../Model/MASShortcut.h
+1
View File
@@ -0,0 +1 @@
../User Defaults Storage/MASShortcutBinder.h
+1
View File
@@ -0,0 +1 @@
../Monitoring/MASShortcutMonitor.h
+1
View File
@@ -0,0 +1 @@
../Model/MASShortcutValidator.h
+1
View File
@@ -0,0 +1 @@
../UI/MASShortcutView+Bindings.h
+1
View File
@@ -0,0 +1 @@
../UI/MASShortcutView.h
+1
View File
@@ -0,0 +1 @@
../UI/MASShortcutViewButtonCell.h
+1
View File
@@ -0,0 +1 @@
../Shortcut.h
+4
View File
@@ -0,0 +1,4 @@
module MASShortcut {
header "Shortcut.h"
export *
}
+1 -1
View File
@@ -1,7 +1,7 @@
# coding: utf-8
Pod::Spec.new do |s|
s.name = 'MASShortcut'
s.version = '2.4.0'
s.version = '2.4.1'
s.summary = 'Modern framework for managing global keyboard shortcuts compatible with Mac App Store'
s.homepage = 'https://github.com/shpakovski/MASShortcut'
s.license = 'BSD 2-clause'
+25 -12
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 48;
objects = {
/* Begin PBXBuildFile section */
@@ -33,7 +33,6 @@
0D827D9F19911A190010B8EF /* MASShortcutValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D827D9D19911A190010B8EF /* MASShortcutValidator.m */; };
0D827DA519912D240010B8EF /* MASShortcutMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D827DA319912D240010B8EF /* MASShortcutMonitor.h */; settings = {ATTRIBUTES = (Public, ); }; };
0D827DAD199132840010B8EF /* MASShortcutBinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D827DAB199132840010B8EF /* MASShortcutBinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
0DA8BCFC1DC37D8000C96EB9 /* MASKeyMasks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DA8BCFB1DC37D8000C96EB9 /* MASKeyMasks.h */; settings = {ATTRIBUTES = (Public, ); }; };
0DC2F17619922798003A0131 /* MASHotKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DC2F17419922798003A0131 /* MASHotKey.h */; };
0DC2F17719922798003A0131 /* MASHotKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DC2F17519922798003A0131 /* MASHotKey.m */; };
0DC2F17C199232EA003A0131 /* MASShortcutMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D827DA419912D240010B8EF /* MASShortcutMonitor.m */; };
@@ -44,6 +43,8 @@
0DC2F190199372B4003A0131 /* MASDictionaryTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DC2F18F199372B4003A0131 /* MASDictionaryTransformerTests.m */; };
0DC2F19819938EFA003A0131 /* MASShortcutView+Bindings.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DC2F19619938EFA003A0131 /* MASShortcutView+Bindings.h */; settings = {ATTRIBUTES = (Public, ); }; };
0DC2F19919938EFA003A0131 /* MASShortcutView+Bindings.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DC2F19719938EFA003A0131 /* MASShortcutView+Bindings.m */; };
50C888F126F8E2FE0086EB9A /* MASShortcutViewButtonCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C888EF26F8E2FE0086EB9A /* MASShortcutViewButtonCell.h */; settings = {ATTRIBUTES = (Public, ); }; };
50C888F226F8E2FE0086EB9A /* MASShortcutViewButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 50C888F026F8E2FE0086EB9A /* MASShortcutViewButtonCell.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -75,7 +76,6 @@
0D2CAB161B8332EE005431FC /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
0D2CAB171B8339F4005431FC /* MASLocalization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASLocalization.h; sourceTree = "<group>"; };
0D2CAB181B8339F4005431FC /* MASLocalization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASLocalization.m; sourceTree = "<group>"; };
0D2CAB1C1B83409C005431FC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
0D2CAB1E1B8340A4005431FC /* cs */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = cs; path = cs.lproj/MainMenu.xib; sourceTree = "<group>"; };
0D2CAB221B834464005431FC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
0D2CAB241B834467005431FC /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -115,7 +115,6 @@
0D827DA419912D240010B8EF /* MASShortcutMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASShortcutMonitor.m; sourceTree = "<group>"; };
0D827DAB199132840010B8EF /* MASShortcutBinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASShortcutBinder.h; sourceTree = "<group>"; };
0D827DAC199132840010B8EF /* MASShortcutBinder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASShortcutBinder.m; sourceTree = "<group>"; };
0DA8BCFB1DC37D8000C96EB9 /* MASKeyMasks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASKeyMasks.h; sourceTree = "<group>"; };
0DC2F17419922798003A0131 /* MASHotKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASHotKey.h; sourceTree = "<group>"; };
0DC2F17519922798003A0131 /* MASHotKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASHotKey.m; sourceTree = "<group>"; };
0DC2F18819925F8F003A0131 /* MASShortcutBinderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASShortcutBinderTests.m; sourceTree = "<group>"; };
@@ -125,6 +124,8 @@
0DC2F19619938EFA003A0131 /* MASShortcutView+Bindings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MASShortcutView+Bindings.h"; sourceTree = "<group>"; };
0DC2F19719938EFA003A0131 /* MASShortcutView+Bindings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MASShortcutView+Bindings.m"; sourceTree = "<group>"; };
0DEDAA021C6BB479001605F5 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
50C888EF26F8E2FE0086EB9A /* MASShortcutViewButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASShortcutViewButtonCell.h; sourceTree = "<group>"; };
50C888F026F8E2FE0086EB9A /* MASShortcutViewButtonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASShortcutViewButtonCell.m; sourceTree = "<group>"; };
57B25C2D1E78E06D0061A9EC /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Localizable.strings; sourceTree = "<group>"; };
57B25C2E1E78E06D0061A9EC /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Localizable.strings; sourceTree = "<group>"; };
6EA6034E1CBF822000A3ED9C /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -134,6 +135,7 @@
76A0597D1C51DC940014B271 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
76A0597E1C51DC9F0014B271 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
EAFFDC811AACFF3300F38834 /* MASShortcut.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = MASShortcut.modulemap; sourceTree = "<group>"; };
ED840EAE25E66B37003F76F7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
ED8737791BCE459800BB1716 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
FDFF016F20CB2FB400CC88F3 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -229,7 +231,8 @@
children = (
0D2CAB151B8332E5005431FC /* Localizable.strings */,
);
path = Resources;
name = Resources;
path = Framework/Resources;
sourceTree = "<group>";
};
0DBA0B9E22A4FAC5008685CD /* Framework */ = {
@@ -250,7 +253,6 @@
0DBA0B9F22A4FACE008685CD /* Model */ = {
isa = PBXGroup;
children = (
0DA8BCFB1DC37D8000C96EB9 /* MASKeyMasks.h */,
0D827D9619910FF70010B8EF /* MASKeyCodes.h */,
0D827D1B1990D55E0010B8EF /* MASShortcut.h */,
0D827D1C1990D55E0010B8EF /* MASShortcut.m */,
@@ -294,6 +296,8 @@
0D2CAB181B8339F4005431FC /* MASLocalization.m */,
0D827D211990D55E0010B8EF /* MASShortcutView.h */,
0D827D221990D55E0010B8EF /* MASShortcutView.m */,
50C888EF26F8E2FE0086EB9A /* MASShortcutViewButtonCell.h */,
50C888F026F8E2FE0086EB9A /* MASShortcutViewButtonCell.m */,
0DC2F19619938EFA003A0131 /* MASShortcutView+Bindings.h */,
0DC2F19719938EFA003A0131 /* MASShortcutView+Bindings.m */,
);
@@ -307,7 +311,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
0DA8BCFC1DC37D8000C96EB9 /* MASKeyMasks.h in Headers */,
0D827D9719910FF70010B8EF /* MASKeyCodes.h in Headers */,
0D827D2B1990D55E0010B8EF /* MASShortcutView.h in Headers */,
0D827D99199110F60010B8EF /* Prefix.pch in Headers */,
@@ -318,6 +321,7 @@
0D827DA519912D240010B8EF /* MASShortcutMonitor.h in Headers */,
0D827DAD199132840010B8EF /* MASShortcutBinder.h in Headers */,
0D2CAB191B8339F4005431FC /* MASLocalization.h in Headers */,
50C888F126F8E2FE0086EB9A /* MASShortcutViewButtonCell.h in Headers */,
0DC2F17619922798003A0131 /* MASHotKey.h in Headers */,
0D827D771990F81E0010B8EF /* Shortcut.h in Headers */,
);
@@ -386,7 +390,7 @@
0D827CCA1990D4420010B8EF /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1010;
LastUpgradeCheck = 1250;
ORGANIZATIONNAME = "Vadim Shpakovski";
TargetAttributes = {
0D827D8219910AFF0010B8EF = {
@@ -395,11 +399,10 @@
};
};
buildConfigurationList = 0D827CCD1990D4420010B8EF /* Build configuration list for PBXProject "MASShortcut" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
compatibilityVersion = "Xcode 8.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
cs,
de,
@@ -415,6 +418,7 @@
nl,
pt,
sv,
Base,
);
mainGroup = 0D827CC91990D4420010B8EF;
productRefGroup = 0D827CD41990D4420010B8EF /* Products */;
@@ -468,6 +472,7 @@
0DC2F18E1993708A003A0131 /* MASDictionaryTransformer.m in Sources */,
0D2CAB1A1B8339F4005431FC /* MASLocalization.m in Sources */,
0DC2F19919938EFA003A0131 /* MASShortcutView+Bindings.m in Sources */,
50C888F226F8E2FE0086EB9A /* MASShortcutViewButtonCell.m in Sources */,
0DC2F17D199232F7003A0131 /* MASShortcutBinder.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -529,8 +534,8 @@
0D2CAB1D1B83409C005431FC /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
0D2CAB1C1B83409C005431FC /* en */,
0D2CAB1E1B8340A4005431FC /* cs */,
ED840EAE25E66B37003F76F7 /* Base */,
);
name = MainMenu.xib;
sourceTree = "<group>";
@@ -573,6 +578,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -627,6 +633,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -669,6 +676,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.github.shpakovski.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
USER_HEADER_SEARCH_PATHS = "\"$SRCROOT/Framework/include\"";
USE_HEADERMAP = NO;
WRAPPER_EXTENSION = framework;
};
name = Debug;
@@ -691,6 +700,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.github.shpakovski.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
USER_HEADER_SEARCH_PATHS = "\"$SRCROOT/Framework/include\"";
USE_HEADERMAP = NO;
WRAPPER_EXTENSION = framework;
};
name = Release;
@@ -699,6 +710,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Demo/Prefix.pch;
@@ -718,6 +730,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Demo/Prefix.pch;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
LastUpgradeVersion = "1250"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -27,8 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
@@ -38,8 +36,8 @@
ReferencedContainer = "container:MASShortcut.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -61,8 +59,6 @@
ReferencedContainer = "container:MASShortcut.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
LastUpgradeVersion = "1250"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -41,6 +41,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D827CD21990D4420010B8EF"
BuildableName = "MASShortcut.framework"
BlueprintName = "MASShortcut"
ReferencedContainer = "container:MASShortcut.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
@@ -53,17 +62,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D827CD21990D4420010B8EF"
BuildableName = "MASShortcut.framework"
BlueprintName = "MASShortcut"
ReferencedContainer = "container:MASShortcut.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -84,8 +82,6 @@
ReferencedContainer = "container:MASShortcut.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Executable
+36
View File
@@ -0,0 +1,36 @@
// swift-tools-version:5.4
import PackageDescription
let package = Package(
name: "MASShortcut",
defaultLocalization: "en",
platforms: [
.macOS(.v10_11),
],
products: [
.library(name: "MASShortcut",
targets: ["MASShortcut"])
],
targets: [
.target(
name: "MASShortcut",
path: "Framework",
exclude: [
"Model/MASShortcutTests.m",
"Monitoring/MASHotKeyTests.m",
"Monitoring/MASShortcutMonitorTests.m",
"User Defaults Storage/MASDictionaryTransformerTests.m",
"User Defaults Storage/MASShortcutBinderTests.m",
"Info.plist",
"MASShortcut.modulemap",
"Prefix.pch"
],
resources: [
.process("Resources")
],
publicHeadersPath: "include"
)
],
swiftLanguageVersions: [.v5]
)
+23 -2
View File
@@ -28,8 +28,14 @@ Partially done:
Pull requests welcome :)
# Installation
### Swift Package Manager
[Swift Package Manager](https://swift.org/package-manager/) is the simplest way to install for Xcode projects. Simply add the following Package Dependency:
https://github.com/shpakovski/MASShortcut
You can use [CocoaPods](http://cocoapods.org/), adding the following line to your Podfile:
### CocoaPods
You can also use [CocoaPods](http://cocoapods.org/), by adding the following line to your Podfile:
pod 'MASShortcut'
@@ -37,6 +43,7 @@ If you want to stick to the 1.x branch, you can use the version smart match oper
pod 'MASShortcut', '~> 1'
### Carthage
You can also install via [Carthage](https://github.com/Carthage/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.
@@ -46,7 +53,7 @@ To build from the command line, type 'make release'. The framework will be creat
I hope, it is really easy:
```objective-c
#import <MASShortcut/Shortcut.h>
#import <Shortcut.h>
// Drop a custom view into XIB, set its class to MASShortcutView
// and its height to 19. If you select another appearance style,
@@ -67,6 +74,12 @@ self.shortcutView.associatedUserDefaultsKey = kPreferenceGlobalShortcut;
}];
```
When you have installed via a method other than Swift Package Manager, then the import is slightly different:
```objective-c
#import <MASShortcut/Shortcut.h>
```
You can see a real usage example in the Demo target. Enjoy!
# Shortcut Recorder Compatibility
@@ -122,6 +135,14 @@ _observableKeyPath = [@"values." stringByAppendingString:kPreferenceGlobalShortc
# Using in Swift projects
Swift Package Manager is the simplest way to import MASShortcut, just import the Module like so:
```
import MASShortcut
```
Alternatively, you can also:
1. Install as a Pod using the latest CocoaPods with Swift support.
2. Create a bridging header file [using the instructions here](http://swiftalicio.us/2014/11/using-cocoapods-from-swift/)
3. Your bridging header file should contain the following [two](https://github.com/shpakovski/MASShortcut/issues/36) imports: