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
104 changes: 89 additions & 15 deletions MACHView.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <CoreVideo/CVDisplayLink.h>

@interface MACHView : NSView
@end
Expand All @@ -14,7 +15,11 @@ @implementation MACHView {
void (^_scrollWheel_block)(NSEvent *);
void (^_magnify_block)(NSEvent *);
void (^_insertText_block)(NSEvent *, uint32_t);
void (^_render_block)(void);
NSTrackingArea *trackingArea;
dispatch_source_t m_displaySource;
CVDisplayLinkRef m_displayLink;
BOOL _hasRenderLoop;
}

- (BOOL)canBecomeKeyView {
Expand All @@ -25,6 +30,78 @@ - (BOOL)acceptsFirstResponder {
return YES;
}

- (void)dealloc
{
if (self->_hasRenderLoop) {
[self stopRenderLoop];
}
}

- (void)viewDidMoveToWindow
{
[super viewDidMoveToWindow];

if (self->_hasRenderLoop) {

[self stopRenderLoop];

if (self.window)
{
m_displaySource = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0,
0, dispatch_get_main_queue());
dispatch_source_set_event_handler(m_displaySource, ^() { [self render]; });
dispatch_resume(m_displaySource);

CVDisplayLinkCreateWithActiveCGDisplays(&m_displayLink);
CVDisplayLinkSetOutputCallback(m_displayLink, &displayLinkCallback, (__bridge void*)m_displaySource);
CVDisplayLinkStart(m_displayLink);
}
}
}

static CVReturn displayLinkCallback(
CVDisplayLinkRef displayLink,
const CVTimeStamp* now,
const CVTimeStamp* outputTime,
CVOptionFlags flagsIn,
CVOptionFlags* flagsOut,
void* displayLinkContext)
{
@autoreleasepool
{
dispatch_source_t source = (__bridge dispatch_source_t)displayLinkContext;
dispatch_source_merge_data(source, 1);
return kCVReturnSuccess;
}
}

- (void)render
{
if (_render_block)
_render_block();
}

- (void)stopRenderLoop
{
if (m_displaySource)
{
dispatch_source_cancel(m_displaySource);
m_displaySource = nil;
}

if (m_displayLink)
{
CVDisplayLinkStop(m_displayLink);
CVDisplayLinkRelease(m_displayLink);
m_displayLink = nil;
}
}

- (void)setBlock_render:(void (^)(void))render_block
__attribute__((objc_direct)) {
_render_block = render_block;
}

- (void)setBlock_keyDown:(void (^)(NSEvent *))keyDown_block
__attribute__((objc_direct)) {
_keyDown_block = keyDown_block;
Expand Down Expand Up @@ -182,6 +259,13 @@ - (void)doCommandBySelector:(SEL)selector
{
}


-(id)initWithFrame:(NSRect)frame withRenderLoop:(BOOL)loop {
self = [self initWithFrame:frame];
self->_hasRenderLoop = loop;
return self;
}

// This overrides the default initializer and creates a tracking area over the
// views visible rect
- (id)initWithFrame:(NSRect)frame {
Expand All @@ -197,24 +281,14 @@ - (id)initWithFrame:(NSRect)frame {
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];

}
return self;
}

// This is automatically called each time the view size changes
- (void)updateTrackingAreas {
// Remove any existing tracking area
[self removeTrackingArea:trackingArea];
// Create a new tracking area to monitor mouse movement
NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved |
NSTrackingActiveInActiveApp;
NSRect rect = self.visibleRect;
trackingArea = [[NSTrackingArea alloc] initWithRect:rect
options:options
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}





@end
Loading
Loading