Skip to content

Commit

Permalink
Resuce eventWithCGEvent: call.
Browse files Browse the repository at this point in the history
  • Loading branch information
niw committed Feb 18, 2018
1 parent cabcae2 commit fc4b67d
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 22 deletions.
3 changes: 3 additions & 0 deletions HapticKey/Classes/HTKEventTap.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ NS_ASSUME_NONNULL_BEGIN
@protocol HTKEventTapDelegate <NSObject>

@optional
- (void)eventTap:(HTKEventTap *)eventTap didTapCGEvent:(CGEventRef)eventRef;
// Implement this only when the delegate needs to use `NSEvent` for all tapped event.
// In many cases, using `CGEvent` without creating `NSEvent` may be faster and cheap.
- (void)eventTap:(HTKEventTap *)eventTap didTapEvent:(NSEvent *)event;
- (void)eventTapDisabled:(HTKEventTap *)eventTap;

Expand Down
14 changes: 10 additions & 4 deletions HapticKey/Classes/HTKEventTap.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@ static CGEventRef EventTapCallback(CGEventTapProxy proxy, CGEventType type, CGE
break;
}
default: {
// `eventWithCGEvent:` returns an autoreleased `NSEvent` that retains given `CGEvent`.
// without `@autoreleasepool`, this will may leak and also `CGEvent` as well.
NSEvent * const event = [NSEvent eventWithCGEvent:eventRef];

id<HTKEventTapDelegate> const delegate = eventTap.delegate;
if ([delegate respondsToSelector:@selector(eventTap:didTapCGEvent:)]) {
[delegate eventTap:eventTap didTapCGEvent:eventRef];
}

if ([delegate respondsToSelector:@selector(eventTap:didTapEvent:)]) {
// `eventWithCGEvent:` is relatively expensive.
// Do not implement `eventTap:didTapEvent:` if it's not needed.
// NOTE: `eventWithCGEvent:` returns an autoreleased `NSEvent` that retains given `CGEvent`.
// without `@autoreleasepool`, this will may leak and also `CGEvent` as well.
NSEvent * const event = [NSEvent eventWithCGEvent:eventRef];

[delegate eventTap:eventTap didTapEvent:event];
}
break;
Expand Down
15 changes: 10 additions & 5 deletions HapticKey/Classes/HTKFunctionKeyEventListener.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,18 @@ - (BOOL)isEnabled

// MARK: - HTKEventTapDelegate

- (void)eventTap:(HTKEventTap *)eventTap didTapEvent:(NSEvent *)event
- (void)eventTap:(HTKEventTap *)eventTap didTapCGEvent:(CGEventRef)eventRef
{
const int64_t keyboardType = CGEventGetIntegerValueField(event.CGEvent, kCGKeyboardEventKeyboardType);
if (keyboardType == kTouchbarKeyboardType && !event.ARepeat) {
const CGEventType eventType = CGEventGetType(eventRef);

const int64_t keyboardType = CGEventGetIntegerValueField(eventRef, kCGKeyboardEventKeyboardType);
const int64_t autorepeat = CGEventGetIntegerValueField(eventRef, kCGKeyboardEventAutorepeat);
const int64_t keycode = CGEventGetIntegerValueField(eventRef, kCGKeyboardEventKeycode);

if (keyboardType == kTouchbarKeyboardType && autorepeat == 0) {
for (NSUInteger index = 0; index < kNumberOfEscAndFunctionKeycodes; index += 1) {
if (kEscAndFunctionKeycodes[index] == event.keyCode) {
switch (event.type) {
if (kEscAndFunctionKeycodes[index] == keycode) {
switch (eventType) {
case NSEventTypeKeyDown:
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseBegin]];
break;
Expand Down
35 changes: 22 additions & 13 deletions HapticKey/Classes/HTKTapGestureEventListener.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
#import "NSTouchDevice.h"

@import AppKit;
@import IOKit;

NS_ASSUME_NONNULL_BEGIN

static const uint32_t kCGEventFieldTouchContxtID = 0x92;

@interface HTKTapGestureEventListener () <HTKEventTapDelegate>

@property (nonatomic, readonly) HTKEventTap *eventTap;
Expand Down Expand Up @@ -47,20 +50,26 @@ - (BOOL)isEnabled

// MARK: - HTKEventTapDelegate

- (void)eventTap:(HTKEventTap *)eventTap didTapEvent:(NSEvent *)event
- (void)eventTap:(HTKEventTap *)eventTap didTapCGEvent:(CGEventRef)eventRef
{
for (NSTouch * const touch in [event allTouches]) {
NSTouchDevice * const touchDevice = touch.device;
if (!touch.resting && touchDevice.deviceType == NSTouchDeviceTypeTouchBar) {
switch (touch.phase) {
case NSTouchPhaseBegan:
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseBegin]];
return;
case NSTouchPhaseEnded:
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseEnd]];
return;
default:
break;
// `eventWithCGEvent:` is relatively expensive.
// Check touch contextID exists or not first. All touches on TouchBar has this ID.
const int64_t contextID = CGEventGetIntegerValueField(eventRef, kCGEventFieldTouchContxtID);
if (contextID != 0) {
NSEvent * const event = [NSEvent eventWithCGEvent:eventRef];
for (NSTouch * const touch in [event allTouches]) {
NSTouchDevice * const touchDevice = touch.device;
if (!touch.resting && touchDevice.deviceType == NSTouchDeviceTypeTouchBar) {
switch (touch.phase) {
case NSTouchPhaseBegan:
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseBegin]];
return;
case NSTouchPhaseEnded:
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseEnd]];
return;
default:
break;
}
}
}
}
Expand Down

0 comments on commit fc4b67d

Please sign in to comment.