Skip to content

Commit f8b45c3

Browse files
committed
Reduce eventWithCGEvent: call.
1 parent cabcae2 commit f8b45c3

File tree

4 files changed

+45
-22
lines changed

4 files changed

+45
-22
lines changed

HapticKey/Classes/HTKEventTap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ NS_ASSUME_NONNULL_BEGIN
1616
@protocol HTKEventTapDelegate <NSObject>
1717

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

HapticKey/Classes/HTKEventTap.m

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,18 @@ static CGEventRef EventTapCallback(CGEventTapProxy proxy, CGEventType type, CGE
3131
break;
3232
}
3333
default: {
34-
// `eventWithCGEvent:` returns an autoreleased `NSEvent` that retains given `CGEvent`.
35-
// without `@autoreleasepool`, this will may leak and also `CGEvent` as well.
36-
NSEvent * const event = [NSEvent eventWithCGEvent:eventRef];
37-
3834
id<HTKEventTapDelegate> const delegate = eventTap.delegate;
35+
if ([delegate respondsToSelector:@selector(eventTap:didTapCGEvent:)]) {
36+
[delegate eventTap:eventTap didTapCGEvent:eventRef];
37+
}
38+
3939
if ([delegate respondsToSelector:@selector(eventTap:didTapEvent:)]) {
40+
// `eventWithCGEvent:` is relatively expensive.
41+
// Do not implement `eventTap:didTapEvent:` if it's not needed.
42+
// NOTE: `eventWithCGEvent:` returns an autoreleased `NSEvent` that retains given `CGEvent`.
43+
// without `@autoreleasepool`, this will may leak and also `CGEvent` as well.
44+
NSEvent * const event = [NSEvent eventWithCGEvent:eventRef];
45+
4046
[delegate eventTap:eventTap didTapEvent:event];
4147
}
4248
break;

HapticKey/Classes/HTKFunctionKeyEventListener.m

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,18 @@ - (BOOL)isEnabled
5454

5555
// MARK: - HTKEventTapDelegate
5656

57-
- (void)eventTap:(HTKEventTap *)eventTap didTapEvent:(NSEvent *)event
57+
- (void)eventTap:(HTKEventTap *)eventTap didTapCGEvent:(CGEventRef)eventRef
5858
{
59-
const int64_t keyboardType = CGEventGetIntegerValueField(event.CGEvent, kCGKeyboardEventKeyboardType);
60-
if (keyboardType == kTouchbarKeyboardType && !event.ARepeat) {
59+
const CGEventType eventType = CGEventGetType(eventRef);
60+
61+
const int64_t keyboardType = CGEventGetIntegerValueField(eventRef, kCGKeyboardEventKeyboardType);
62+
const int64_t autorepeat = CGEventGetIntegerValueField(eventRef, kCGKeyboardEventAutorepeat);
63+
const int64_t keycode = CGEventGetIntegerValueField(eventRef, kCGKeyboardEventKeycode);
64+
65+
if (keyboardType == kTouchbarKeyboardType && autorepeat == 0) {
6166
for (NSUInteger index = 0; index < kNumberOfEscAndFunctionKeycodes; index += 1) {
62-
if (kEscAndFunctionKeycodes[index] == event.keyCode) {
63-
switch (event.type) {
67+
if (kEscAndFunctionKeycodes[index] == keycode) {
68+
switch (eventType) {
6469
case NSEventTypeKeyDown:
6570
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseBegin]];
6671
break;

HapticKey/Classes/HTKTapGestureEventListener.m

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
#import "NSTouchDevice.h"
1313

1414
@import AppKit;
15+
@import IOKit;
1516

1617
NS_ASSUME_NONNULL_BEGIN
1718

19+
static const uint32_t kCGEventFieldTouchContxtID = 0x92;
20+
1821
@interface HTKTapGestureEventListener () <HTKEventTapDelegate>
1922

2023
@property (nonatomic, readonly) HTKEventTap *eventTap;
@@ -47,20 +50,26 @@ - (BOOL)isEnabled
4750

4851
// MARK: - HTKEventTapDelegate
4952

50-
- (void)eventTap:(HTKEventTap *)eventTap didTapEvent:(NSEvent *)event
53+
- (void)eventTap:(HTKEventTap *)eventTap didTapCGEvent:(CGEventRef)eventRef
5154
{
52-
for (NSTouch * const touch in [event allTouches]) {
53-
NSTouchDevice * const touchDevice = touch.device;
54-
if (!touch.resting && touchDevice.deviceType == NSTouchDeviceTypeTouchBar) {
55-
switch (touch.phase) {
56-
case NSTouchPhaseBegan:
57-
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseBegin]];
58-
return;
59-
case NSTouchPhaseEnded:
60-
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseEnd]];
61-
return;
62-
default:
63-
break;
55+
// `eventWithCGEvent:` is relatively expensive.
56+
// Check touch contextID exists or not first. All touches on TouchBar has this ID.
57+
const int64_t contextID = CGEventGetIntegerValueField(eventRef, kCGEventFieldTouchContxtID);
58+
if (contextID != 0) {
59+
NSEvent * const event = [NSEvent eventWithCGEvent:eventRef];
60+
for (NSTouch * const touch in [event allTouches]) {
61+
NSTouchDevice * const touchDevice = touch.device;
62+
if (!touch.resting && touchDevice.deviceType == NSTouchDeviceTypeTouchBar) {
63+
switch (touch.phase) {
64+
case NSTouchPhaseBegan:
65+
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseBegin]];
66+
return;
67+
case NSTouchPhaseEnded:
68+
[self _htk_main_didListenEvent:[[HTKEvent alloc] initWithPhase:HTKEventPhaseEnd]];
69+
return;
70+
default:
71+
break;
72+
}
6473
}
6574
}
6675
}

0 commit comments

Comments
 (0)