Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Credits.rtf
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
\ls1\ilvl0\cf0 {\listtext \'95 }{\field{\*\fldinst{HYPERLINK "https://github.com/dimonzozo"}}{\fldrslt Dmitriy}}\
{\listtext \'95 }{\field{\*\fldinst{HYPERLINK "https://github.com/jaysonlane"}}{\fldrslt Jason Lane}}\
{\listtext \'95 }{\field{\*\fldinst{HYPERLINK "https://github.com/tilden"}}{\fldrslt Dan Tilden}}\
}
{\listtext \'95 }{\field{\*\fldinst{HYPERLINK "https://github.com/ErezVolk"}}{\fldrslt Erez Volk}}\
}
27 changes: 12 additions & 15 deletions DDHotKeyCenter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,18 @@

#import <Cocoa/Cocoa.h>

NS_ASSUME_NONNULL_BEGIN

//a convenient typedef for the required signature of a hotkey block callback
typedef void (^DDHotKeyTask)(NSEvent*);

@interface DDHotKey : NSObject

// creates a new hotkey but does not register it
+ (instancetype)hotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags task:(DDHotKeyTask _Nullable)task;
+ (instancetype)hotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags task:(DDHotKeyTask)task;

@property (nonatomic, assign, readonly, nullable) id target;
@property (nonatomic, readonly, nullable) SEL action;
@property (nonatomic, strong, readonly, nullable) id object;
@property (nonatomic, copy, readonly, nullable) DDHotKeyTask task;
@property (nonatomic, assign, readonly) id target;
@property (nonatomic, readonly) SEL action;
@property (nonatomic, strong, readonly) id object;
@property (nonatomic, copy, readonly) DDHotKeyTask task;

@property (nonatomic, readonly) unsigned short keyCode;
@property (nonatomic, readonly) NSUInteger modifierFlags;
Expand All @@ -34,26 +32,26 @@ typedef void (^DDHotKeyTask)(NSEvent*);

@interface DDHotKeyCenter : NSObject

@property (class, readonly, nonnull) DDHotKeyCenter *sharedHotKeyCenter;
+ (instancetype)sharedHotKeyCenter;

/**
Register a hotkey.
*/
- (DDHotKey * _Nullable)registerHotKey:(DDHotKey *)hotKey withError:(NSError **)error;
- (DDHotKey *)registerHotKey:(DDHotKey *)hotKey;

/**
Register a target/action hotkey.
The modifierFlags must be a bitwise OR of NSEventModifierFlagCommand, NSEventModifierFlagOption, NSEventModifierFlagControl, or NSEventModifierFlagShift;
The modifierFlags must be a bitwise OR of NSCommandKeyMask, NSAlternateKeyMask, NSControlKeyMask, or NSShiftKeyMask;
Returns the hotkey registered. If registration failed, returns nil.
*/
- (DDHotKey * _Nullable)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags target:(id)target action:(SEL)action object:(id)object error:(NSError **)error;
- (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags target:(id)target action:(SEL)action object:(id)object;

/**
Register a block callback hotkey.
The modifierFlags must be a bitwise OR of NSEventModifierFlagCommand, NSEventModifierFlagOption, NSEventModifierFlagControl, or NSEventModifierFlagShift;
The modifierFlags must be a bitwise OR of NSCommandKeyMask, NSAlternateKeyMask, NSControlKeyMask, or NSShiftKeyMask;
Returns the hotkey registered. If registration failed, returns nil.
*/
- (DDHotKey * _Nullable)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags task:(DDHotKeyTask)task error:(NSError **)error;
- (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags task:(DDHotKeyTask)task;

/**
See if a hotkey exists with the specified keycode and modifier flags.
Expand Down Expand Up @@ -89,8 +87,7 @@ typedef void (^DDHotKeyTask)(NSEvent*);
/**
Returns a set of currently registered hotkeys
**/
- (NSSet<DDHotKey *> *)registeredHotKeys;
- (NSSet *)registeredHotKeys;

@end

NS_ASSUME_NONNULL_END
42 changes: 15 additions & 27 deletions DDHotKeyCenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ + (instancetype)hotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInte

- (void) dealloc {
[[DDHotKeyCenter sharedHotKeyCenter] unregisterHotKey:self];
[super dealloc];
}

- (NSUInteger)hash {
Expand All @@ -66,10 +65,10 @@ - (BOOL)isEqual:(id)object {

- (NSString *)description {
NSMutableArray *bits = [NSMutableArray array];
if ((_modifierFlags & NSEventModifierFlagControl) > 0) { [bits addObject:@"NSEventModifierFlagControl"]; }
if ((_modifierFlags & NSEventModifierFlagCommand) > 0) { [bits addObject:@"NSEventModifierFlagCommand"]; }
if ((_modifierFlags & NSEventModifierFlagShift) > 0) { [bits addObject:@"NSEventModifierFlagShift"]; }
if ((_modifierFlags & NSEventModifierFlagOption) > 0) { [bits addObject:@"NSEventModifierFlagOption"]; }
if ((_modifierFlags & NSControlKeyMask) > 0) { [bits addObject:@"NSControlKeyMask"]; }
if ((_modifierFlags & NSCommandKeyMask) > 0) { [bits addObject:@"NSCommandKeyMask"]; }
if ((_modifierFlags & NSShiftKeyMask) > 0) { [bits addObject:@"NSShiftKeyMask"]; }
if ((_modifierFlags & NSAlternateKeyMask) > 0) { [bits addObject:@"NSAlternateKeyMask"]; }

NSString *flags = [NSString stringWithFormat:@"(%@)", [bits componentsJoinedByString:@" | "]];
NSString *invokes = @"(block)";
Expand Down Expand Up @@ -143,10 +142,7 @@ - (BOOL)hasRegisteredHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NS
}].count > 0;
}

- (DDHotKey *)_registerHotKey:(DDHotKey *)hotKey withError:(NSError **)error {

error = error ?: &(NSError * __autoreleasing){ nil };

- (DDHotKey *)_registerHotKey:(DDHotKey *)hotKey {
if ([_registeredHotKeys containsObject:hotKey]) {
return hotKey;
}
Expand All @@ -160,10 +156,7 @@ - (DDHotKey *)_registerHotKey:(DDHotKey *)hotKey withError:(NSError **)error {
OSStatus err = RegisterEventHotKey([hotKey keyCode], flags, keyID, GetEventDispatcherTarget(), 0, &carbonHotKey);

//error registering hot key
if (err != 0) {
*error = [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil];
return nil;
}
if (err != 0) { return nil; }

NSValue *refValue = [NSValue valueWithPointer:carbonHotKey];
[hotKey setHotKeyRef:refValue];
Expand All @@ -175,8 +168,8 @@ - (DDHotKey *)_registerHotKey:(DDHotKey *)hotKey withError:(NSError **)error {
return hotKey;
}

- (DDHotKey *)registerHotKey:(DDHotKey *)hotKey withError:(NSError **)error {
return [self _registerHotKey:hotKey withError:error];
- (DDHotKey *)registerHotKey:(DDHotKey *)hotKey {
return [self _registerHotKey:hotKey];
}

- (void)unregisterHotKey:(DDHotKey *)hotKey {
Expand All @@ -190,26 +183,21 @@ - (void)unregisterHotKey:(DDHotKey *)hotKey {
[_registeredHotKeys removeObject:hotKey];
}

- (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags task:(DDHotKeyTask)task error:(NSError **)error {
error = error ?: &(NSError * __autoreleasing){ nil };

- (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags task:(DDHotKeyTask)task {
//we can't add a new hotkey if something already has this combo
if ([self hasRegisteredHotKeyWithKeyCode:keyCode modifierFlags:flags]) { return nil; }
if ([self hasRegisteredHotKeyWithKeyCode:keyCode modifierFlags:flags]) { return NO; }

DDHotKey *newHotKey = [[DDHotKey alloc] init];
[newHotKey _setTask:task];
[newHotKey _setKeyCode:keyCode];
[newHotKey _setModifierFlags:flags];

return [self _registerHotKey:newHotKey withError:error];
return [self _registerHotKey:newHotKey];
}

- (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags target:(id)target action:(SEL)action object:(id)object error:(NSError **)error {

error = error ?: &(NSError * __autoreleasing){ nil };

- (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags target:(id)target action:(SEL)action object:(id)object {
//we can't add a new hotkey if something already has this combo
if ([self hasRegisteredHotKeyWithKeyCode:keyCode modifierFlags:flags]) { return nil; }
if ([self hasRegisteredHotKeyWithKeyCode:keyCode modifierFlags:flags]) { return NO; }

//build the hotkey object:
DDHotKey *newHotKey = [[DDHotKey alloc] init];
Expand All @@ -218,7 +206,7 @@ - (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(N
[newHotKey _setObject:object];
[newHotKey _setKeyCode:keyCode];
[newHotKey _setModifierFlags:flags];
return [self _registerHotKey:newHotKey withError:error];
return [self _registerHotKey:newHotKey];
}

- (void)unregisterHotKeysMatching:(BOOL(^)(DDHotKey *hotkey))matcher {
Expand Down Expand Up @@ -278,7 +266,7 @@ OSStatus dd_hotKeyHandler(EventHandlerCallRef nextHandler, EventRef theEvent, vo
DDHotKey *matchingHotKey = [matchingHotKeys anyObject];

NSEvent *event = [NSEvent eventWithEventRef:theEvent];
NSEvent *keyEvent = [NSEvent keyEventWithType:NSEventTypeKeyUp
NSEvent *keyEvent = [NSEvent keyEventWithType:NSKeyUp
location:[event locationInWindow]
modifierFlags:[event modifierFlags]
timestamp:[event timestamp]
Expand Down
2 changes: 1 addition & 1 deletion DDHotKeyUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@

#import <Foundation/Foundation.h>

extern NSString * _Nonnull DDStringFromKeyCode(unsigned short keyCode, NSUInteger modifiers);
extern NSString *DDStringFromKeyCode(unsigned short keyCode, NSUInteger modifiers);
extern UInt32 DDCarbonModifierFlagsFromCocoaModifiers(NSUInteger flags);
19 changes: 9 additions & 10 deletions DDHotKeyUtilities.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#import "DDHotKeyUtilities.h"
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>

static NSDictionary *_DDKeyCodeToCharacterMap(void);
static NSDictionary *_DDKeyCodeToCharacterMap(void) {
Expand Down Expand Up @@ -74,16 +73,16 @@
NSMutableString *final = [NSMutableString stringWithString:@""];
NSDictionary *characterMap = _DDKeyCodeToCharacterMap();

if (modifiers & NSEventModifierFlagControl) {
if (modifiers & NSControlKeyMask) {
[final appendString:[characterMap objectForKey:@(kVK_Control)]];
}
if (modifiers & NSEventModifierFlagOption) {
if (modifiers & NSAlternateKeyMask) {
[final appendString:[characterMap objectForKey:@(kVK_Option)]];
}
if (modifiers & NSEventModifierFlagShift) {
if (modifiers & NSShiftKeyMask) {
[final appendString:[characterMap objectForKey:@(kVK_Shift)]];
}
if (modifiers & NSEventModifierFlagCommand) {
if (modifiers & NSCommandKeyMask) {
[final appendString:[characterMap objectForKey:@(kVK_Command)]];
}

Expand Down Expand Up @@ -136,10 +135,10 @@

UInt32 DDCarbonModifierFlagsFromCocoaModifiers(NSUInteger flags) {
UInt32 newFlags = 0;
if ((flags & NSEventModifierFlagControl) > 0) { newFlags |= controlKey; }
if ((flags & NSEventModifierFlagCommand) > 0) { newFlags |= cmdKey; }
if ((flags & NSEventModifierFlagShift) > 0) { newFlags |= shiftKey; }
if ((flags & NSEventModifierFlagOption) > 0) { newFlags |= optionKey; }
if ((flags & NSEventModifierFlagCapsLock) > 0) { newFlags |= alphaLock; }
if ((flags & NSControlKeyMask) > 0) { newFlags |= controlKey; }
if ((flags & NSCommandKeyMask) > 0) { newFlags |= cmdKey; }
if ((flags & NSShiftKeyMask) > 0) { newFlags |= shiftKey; }
if ((flags & NSAlternateKeyMask) > 0) { newFlags |= optionKey; }
if ((flags & NSAlphaShiftKeyMask) > 0) { newFlags |= alphaLock; }
return newFlags;
}
2 changes: 2 additions & 0 deletions PreferencesWindowController.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
NSButton *pauseOnSleepButton;
NSButton *pauseOnScreensaverButton;
NSButton *askForTagOnFinishButton;
NSButton *appearDisabledWhilePausedButton;
}

@property (nonatomic, retain) IBOutlet SRRecorderControl *startPauseShortcutRecorder;
Expand All @@ -24,5 +25,6 @@
@property (nonatomic, retain) IBOutlet NSButton *pauseOnSleepButton;
@property (nonatomic, retain) IBOutlet NSButton *pauseOnScreensaverButton;
@property (nonatomic, retain) IBOutlet NSButton *askForTagOnFinishButton;
@property (nonatomic, retain) IBOutlet NSButton *appearDisabledWhilePausedButton;

@end
2 changes: 2 additions & 0 deletions PreferencesWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ @implementation PreferencesWindowController
@synthesize pauseOnSleepButton;
@synthesize pauseOnScreensaverButton;
@synthesize askForTagOnFinishButton;
@synthesize appearDisabledWhilePausedButton;

- (id)initWithWindow:(NSWindow *)window
{
Expand All @@ -44,6 +45,7 @@ - (void)windowDidLoad
[self.pauseOnSleepButton bind:NSValueBinding toObject:defaults withKeyPath:@"values.pauseOnSleep" options:nil];
[self.pauseOnScreensaverButton bind:NSValueBinding toObject:defaults withKeyPath:@"values.pauseOnScreensaver" options:nil];
[self.askForTagOnFinishButton bind:NSValueBinding toObject:defaults withKeyPath:@"values.askForTagOnFinishButton" options:nil];
[self.appearDisabledWhilePausedButton bind:NSValueBinding toObject:defaults withKeyPath:@"values.appearDisabledWhilePaused" options:nil];

[self.startPauseShortcutRecorder clearButtonRect];

Expand Down
Loading