chore(v2): vendor dependencies for offline/China builds
go mod vendor pins onnxruntime_go v1.12.1, Gio and the rest into v2/vendor so go run/build work without hitting proxy.golang.org (blocked/slow in China). Verified: CGO_ENABLED=1 go build -mod=vendor ./internal/spike and GOOS=windows go build -mod=vendor ./internal/ui both pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+479
@@ -0,0 +1,479 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
// +build darwin,!ios
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "_cgo_export.h"
|
||||
|
||||
__attribute__ ((visibility ("hidden"))) CALayer *gio_layerFactory(BOOL presentWithTrans);
|
||||
|
||||
@interface GioAppDelegate : NSObject<NSApplicationDelegate>
|
||||
@end
|
||||
|
||||
@interface GioWindowDelegate : NSObject<NSWindowDelegate>
|
||||
@end
|
||||
|
||||
@interface GioView : NSView <CALayerDelegate,NSTextInputClient>
|
||||
@property uintptr_t handle;
|
||||
@property BOOL presentWithTrans;
|
||||
@end
|
||||
|
||||
@implementation GioWindowDelegate
|
||||
- (void)windowWillMiniaturize:(NSNotification *)notification {
|
||||
NSWindow *window = (NSWindow *)[notification object];
|
||||
GioView *view = (GioView *)window.contentView;
|
||||
gio_onDraw(view.handle);
|
||||
}
|
||||
- (void)windowDidDeminiaturize:(NSNotification *)notification {
|
||||
NSWindow *window = (NSWindow *)[notification object];
|
||||
GioView *view = (GioView *)window.contentView;
|
||||
gio_onDraw(view.handle);
|
||||
}
|
||||
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
|
||||
NSWindow *window = (NSWindow *)[notification object];
|
||||
GioView *view = (GioView *)window.contentView;
|
||||
gio_onDraw(view.handle);
|
||||
}
|
||||
- (void)windowWillExitFullScreen:(NSNotification *)notification {
|
||||
NSWindow *window = (NSWindow *)[notification object];
|
||||
GioView *view = (GioView *)window.contentView;
|
||||
gio_onDraw(view.handle);
|
||||
}
|
||||
- (void)windowDidChangeScreen:(NSNotification *)notification {
|
||||
NSWindow *window = (NSWindow *)[notification object];
|
||||
CGDirectDisplayID dispID = [[[window screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue];
|
||||
GioView *view = (GioView *)window.contentView;
|
||||
gio_onChangeScreen(view.handle, dispID);
|
||||
}
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification {
|
||||
NSWindow *window = (NSWindow *)[notification object];
|
||||
GioView *view = (GioView *)window.contentView;
|
||||
if ([window firstResponder] == view) {
|
||||
gio_onFocus(view.handle, 1);
|
||||
}
|
||||
}
|
||||
- (void)windowDidResignKey:(NSNotification *)notification {
|
||||
NSWindow *window = (NSWindow *)[notification object];
|
||||
GioView *view = (GioView *)window.contentView;
|
||||
if ([window firstResponder] == view) {
|
||||
gio_onFocus(view.handle, 0);
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFloat dy) {
|
||||
NSPoint p = [view convertPoint:[event locationInWindow] fromView:nil];
|
||||
if (!event.hasPreciseScrollingDeltas) {
|
||||
// dx and dy are in rows and columns.
|
||||
dx *= 10;
|
||||
dy *= 10;
|
||||
}
|
||||
// Origin is in the lower left corner. Convert to upper left.
|
||||
CGFloat height = view.bounds.size.height;
|
||||
gio_onMouse(view.handle, (__bridge CFTypeRef)event, typ, event.buttonNumber, p.x, height - p.y, dx, dy, [event timestamp], [event modifierFlags]);
|
||||
}
|
||||
|
||||
@implementation GioView
|
||||
- (void)setFrameSize:(NSSize)newSize {
|
||||
[super setFrameSize:newSize];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
// drawRect is called when OpenGL is used, displayLayer otherwise.
|
||||
// Don't know why.
|
||||
- (void)drawRect:(NSRect)r {
|
||||
gio_onDraw(self.handle);
|
||||
}
|
||||
- (void)displayLayer:(CALayer *)layer {
|
||||
layer.contentsScale = self.window.backingScaleFactor;
|
||||
gio_onDraw(self.handle);
|
||||
}
|
||||
- (CALayer *)makeBackingLayer {
|
||||
CALayer *layer = gio_layerFactory(self.presentWithTrans);
|
||||
layer.delegate = self;
|
||||
return layer;
|
||||
}
|
||||
- (void)viewDidMoveToWindow {
|
||||
gio_onAttached(self.handle, self.window != nil ? 1 : 0);
|
||||
}
|
||||
- (void)mouseDown:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_DOWN, 0, 0);
|
||||
}
|
||||
- (void)mouseUp:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_UP, 0, 0);
|
||||
}
|
||||
- (void)rightMouseDown:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_DOWN, 0, 0);
|
||||
}
|
||||
- (void)rightMouseUp:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_UP, 0, 0);
|
||||
}
|
||||
- (void)otherMouseDown:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_DOWN, 0, 0);
|
||||
}
|
||||
- (void)otherMouseUp:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_UP, 0, 0);
|
||||
}
|
||||
- (void)mouseMoved:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_MOVE, 0, 0);
|
||||
}
|
||||
- (void)mouseDragged:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_MOVE, 0, 0);
|
||||
}
|
||||
- (void)rightMouseDragged:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_MOVE, 0, 0);
|
||||
}
|
||||
- (void)otherMouseDragged:(NSEvent *)event {
|
||||
handleMouse(self, event, MOUSE_MOVE, 0, 0);
|
||||
}
|
||||
- (void)scrollWheel:(NSEvent *)event {
|
||||
CGFloat dx = -event.scrollingDeltaX;
|
||||
CGFloat dy = -event.scrollingDeltaY;
|
||||
handleMouse(self, event, MOUSE_SCROLL, dx, dy);
|
||||
}
|
||||
- (void)keyDown:(NSEvent *)event {
|
||||
NSString *keys = [event charactersIgnoringModifiers];
|
||||
gio_onKeys(self.handle, (__bridge CFTypeRef)event, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], true);
|
||||
}
|
||||
- (void)flagsChanged:(NSEvent *)event {
|
||||
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
gio_onFlagsChanged(self.handle, [event modifierFlags]);
|
||||
}
|
||||
- (void)keyUp:(NSEvent *)event {
|
||||
NSString *keys = [event charactersIgnoringModifiers];
|
||||
gio_onKeys(self.handle, (__bridge CFTypeRef)event, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], false);
|
||||
}
|
||||
- (void)insertText:(id)string {
|
||||
gio_onText(self.handle, (__bridge CFTypeRef)string);
|
||||
}
|
||||
- (void)doCommandBySelector:(SEL)action {
|
||||
if (!gio_onCommandBySelector(self.handle)) {
|
||||
[super doCommandBySelector:action];
|
||||
}
|
||||
}
|
||||
- (BOOL)hasMarkedText {
|
||||
int res = gio_hasMarkedText(self.handle);
|
||||
return res ? YES : NO;
|
||||
}
|
||||
- (NSRange)markedRange {
|
||||
return gio_markedRange(self.handle);
|
||||
}
|
||||
- (NSRange)selectedRange {
|
||||
return gio_selectedRange(self.handle);
|
||||
}
|
||||
- (void)unmarkText {
|
||||
gio_unmarkText(self.handle);
|
||||
}
|
||||
- (void)setMarkedText:(id)string
|
||||
selectedRange:(NSRange)selRange
|
||||
replacementRange:(NSRange)replaceRange {
|
||||
NSString *str;
|
||||
// string is either an NSAttributedString or an NSString.
|
||||
if ([string isKindOfClass:[NSAttributedString class]]) {
|
||||
str = [string string];
|
||||
} else {
|
||||
str = string;
|
||||
}
|
||||
gio_setMarkedText(self.handle, (__bridge CFTypeRef)str, selRange, replaceRange);
|
||||
}
|
||||
- (NSArray<NSAttributedStringKey> *)validAttributesForMarkedText {
|
||||
return nil;
|
||||
}
|
||||
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range
|
||||
actualRange:(NSRangePointer)actualRange {
|
||||
NSString *str = CFBridgingRelease(gio_substringForProposedRange(self.handle, range, actualRange));
|
||||
return [[NSAttributedString alloc] initWithString:str attributes:nil];
|
||||
}
|
||||
- (void)insertText:(id)string
|
||||
replacementRange:(NSRange)replaceRange {
|
||||
NSString *str;
|
||||
// string is either an NSAttributedString or an NSString.
|
||||
if ([string isKindOfClass:[NSAttributedString class]]) {
|
||||
str = [string string];
|
||||
} else {
|
||||
str = string;
|
||||
}
|
||||
gio_insertText(self.handle, (__bridge CFTypeRef)str, replaceRange);
|
||||
}
|
||||
- (NSUInteger)characterIndexForPoint:(NSPoint)p {
|
||||
return gio_characterIndexForPoint(self.handle, p);
|
||||
}
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)rng
|
||||
actualRange:(NSRangePointer)actual {
|
||||
NSRect r = gio_firstRectForCharacterRange(self.handle, rng, actual);
|
||||
r = [self convertRect:r toView:nil];
|
||||
return [[self window] convertRectToScreen:r];
|
||||
}
|
||||
- (void)applicationWillUnhide:(NSNotification *)notification {
|
||||
gio_onDraw(self.handle);
|
||||
}
|
||||
- (void)applicationDidHide:(NSNotification *)notification {
|
||||
gio_onDraw(self.handle);
|
||||
}
|
||||
- (void)dealloc {
|
||||
gio_onDestroy(self.handle);
|
||||
}
|
||||
- (BOOL) becomeFirstResponder {
|
||||
gio_onFocus(self.handle, 1);
|
||||
return [super becomeFirstResponder];
|
||||
}
|
||||
- (BOOL) resignFirstResponder {
|
||||
gio_onFocus(self.handle, 0);
|
||||
return [super resignFirstResponder];
|
||||
}
|
||||
@end
|
||||
|
||||
// Delegates are weakly referenced from their peers. Nothing
|
||||
// else holds a strong reference to our window delegate, so
|
||||
// keep a single global reference instead.
|
||||
static GioWindowDelegate *globalWindowDel;
|
||||
|
||||
static CVReturn displayLinkCallback(CVDisplayLinkRef dl, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *handle) {
|
||||
gio_onFrameCallback(dl);
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
CFTypeRef gio_createDisplayLink(void) {
|
||||
CVDisplayLinkRef dl;
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&dl);
|
||||
CVDisplayLinkSetOutputCallback(dl, displayLinkCallback, nil);
|
||||
return dl;
|
||||
}
|
||||
|
||||
int gio_startDisplayLink(CFTypeRef dl) {
|
||||
return CVDisplayLinkStart((CVDisplayLinkRef)dl);
|
||||
}
|
||||
|
||||
int gio_stopDisplayLink(CFTypeRef dl) {
|
||||
return CVDisplayLinkStop((CVDisplayLinkRef)dl);
|
||||
}
|
||||
|
||||
void gio_releaseDisplayLink(CFTypeRef dl) {
|
||||
CVDisplayLinkRelease((CVDisplayLinkRef)dl);
|
||||
}
|
||||
|
||||
void gio_setDisplayLinkDisplay(CFTypeRef dl, uint64_t did) {
|
||||
CVDisplayLinkSetCurrentCGDisplay((CVDisplayLinkRef)dl, (CGDirectDisplayID)did);
|
||||
}
|
||||
|
||||
void gio_hideCursor() {
|
||||
@autoreleasepool {
|
||||
[NSCursor hide];
|
||||
}
|
||||
}
|
||||
|
||||
void gio_showCursor() {
|
||||
@autoreleasepool {
|
||||
[NSCursor unhide];
|
||||
}
|
||||
}
|
||||
|
||||
// some cursors are not public, this tries to use a private cursor
|
||||
// and uses fallback when the use of private cursor fails.
|
||||
static void trySetPrivateCursor(SEL cursorName, NSCursor* fallback) {
|
||||
if ([NSCursor respondsToSelector:cursorName]) {
|
||||
id object = [NSCursor performSelector:cursorName];
|
||||
if ([object isKindOfClass:[NSCursor class]]) {
|
||||
[(NSCursor*)object set];
|
||||
return;
|
||||
}
|
||||
}
|
||||
[fallback set];
|
||||
}
|
||||
|
||||
void gio_setCursor(NSUInteger curID) {
|
||||
@autoreleasepool {
|
||||
switch (curID) {
|
||||
case 0: // pointer.CursorDefault
|
||||
[NSCursor.arrowCursor set];
|
||||
break;
|
||||
// case 1: // pointer.CursorNone
|
||||
case 2: // pointer.CursorText
|
||||
[NSCursor.IBeamCursor set];
|
||||
break;
|
||||
case 3: // pointer.CursorVerticalText
|
||||
[NSCursor.IBeamCursorForVerticalLayout set];
|
||||
break;
|
||||
case 4: // pointer.CursorPointer
|
||||
[NSCursor.pointingHandCursor set];
|
||||
break;
|
||||
case 5: // pointer.CursorCrosshair
|
||||
[NSCursor.crosshairCursor set];
|
||||
break;
|
||||
case 6: // pointer.CursorAllScroll
|
||||
// For some reason, using _moveCursor fails on Monterey.
|
||||
// trySetPrivateCursor(@selector(_moveCursor), NSCursor.arrowCursor);
|
||||
[NSCursor.arrowCursor set];
|
||||
break;
|
||||
case 7: // pointer.CursorColResize
|
||||
[NSCursor.resizeLeftRightCursor set];
|
||||
break;
|
||||
case 8: // pointer.CursorRowResize
|
||||
[NSCursor.resizeUpDownCursor set];
|
||||
break;
|
||||
case 9: // pointer.CursorGrab
|
||||
[NSCursor.openHandCursor set];
|
||||
break;
|
||||
case 10: // pointer.CursorGrabbing
|
||||
[NSCursor.closedHandCursor set];
|
||||
break;
|
||||
case 11: // pointer.CursorNotAllowed
|
||||
[NSCursor.operationNotAllowedCursor set];
|
||||
break;
|
||||
case 12: // pointer.CursorWait
|
||||
trySetPrivateCursor(@selector(busyButClickableCursor), NSCursor.arrowCursor);
|
||||
break;
|
||||
case 13: // pointer.CursorProgress
|
||||
trySetPrivateCursor(@selector(busyButClickableCursor), NSCursor.arrowCursor);
|
||||
break;
|
||||
case 14: // pointer.CursorNorthWestResize
|
||||
trySetPrivateCursor(@selector(_windowResizeNorthWestCursor), NSCursor.resizeUpDownCursor);
|
||||
break;
|
||||
case 15: // pointer.CursorNorthEastResize
|
||||
trySetPrivateCursor(@selector(_windowResizeNorthEastCursor), NSCursor.resizeUpDownCursor);
|
||||
break;
|
||||
case 16: // pointer.CursorSouthWestResize
|
||||
trySetPrivateCursor(@selector(_windowResizeSouthWestCursor), NSCursor.resizeUpDownCursor);
|
||||
break;
|
||||
case 17: // pointer.CursorSouthEastResize
|
||||
trySetPrivateCursor(@selector(_windowResizeSouthEastCursor), NSCursor.resizeUpDownCursor);
|
||||
break;
|
||||
case 18: // pointer.CursorNorthSouthResize
|
||||
[NSCursor.resizeUpDownCursor set];
|
||||
break;
|
||||
case 19: // pointer.CursorEastWestResize
|
||||
[NSCursor.resizeLeftRightCursor set];
|
||||
break;
|
||||
case 20: // pointer.CursorWestResize
|
||||
[NSCursor.resizeLeftCursor set];
|
||||
break;
|
||||
case 21: // pointer.CursorEastResize
|
||||
[NSCursor.resizeRightCursor set];
|
||||
break;
|
||||
case 22: // pointer.CursorNorthResize
|
||||
[NSCursor.resizeUpCursor set];
|
||||
break;
|
||||
case 23: // pointer.CursorSouthResize
|
||||
[NSCursor.resizeDownCursor set];
|
||||
break;
|
||||
case 24: // pointer.CursorNorthEastSouthWestResize
|
||||
trySetPrivateCursor(@selector(_windowResizeNorthEastSouthWestCursor), NSCursor.resizeUpDownCursor);
|
||||
break;
|
||||
case 25: // pointer.CursorNorthWestSouthEastResize
|
||||
trySetPrivateCursor(@selector(_windowResizeNorthWestSouthEastCursor), NSCursor.resizeUpDownCursor);
|
||||
break;
|
||||
default:
|
||||
[NSCursor.arrowCursor set];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CFTypeRef gio_createWindow(CFTypeRef viewRef, CGFloat width, CGFloat height) {
|
||||
@autoreleasepool {
|
||||
NSRect rect = NSMakeRect(0, 0, width, height);
|
||||
NSUInteger styleMask = NSTitledWindowMask |
|
||||
NSResizableWindowMask |
|
||||
NSMiniaturizableWindowMask |
|
||||
NSClosableWindowMask;
|
||||
|
||||
NSWindow* window = [[NSWindow alloc] initWithContentRect:rect
|
||||
styleMask:styleMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
[window setAcceptsMouseMovedEvents:YES];
|
||||
NSView *view = (__bridge NSView *)viewRef;
|
||||
[window setContentView:view];
|
||||
window.delegate = globalWindowDel;
|
||||
return (__bridge_retained CFTypeRef)window;
|
||||
}
|
||||
}
|
||||
|
||||
CFTypeRef gio_createView(int presentWithTrans) {
|
||||
@autoreleasepool {
|
||||
NSRect frame = NSMakeRect(0, 0, 0, 0);
|
||||
GioView* view = [[GioView alloc] initWithFrame:frame];
|
||||
view.presentWithTrans = presentWithTrans ? YES : NO;
|
||||
view.wantsLayer = YES;
|
||||
view.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:view
|
||||
selector:@selector(applicationWillUnhide:)
|
||||
name:NSApplicationWillUnhideNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:view
|
||||
selector:@selector(applicationDidHide:)
|
||||
name:NSApplicationDidHideNotification
|
||||
object:nil];
|
||||
return CFBridgingRetain(view);
|
||||
}
|
||||
}
|
||||
|
||||
void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle) {
|
||||
@autoreleasepool {
|
||||
GioView *v = (__bridge GioView *)viewRef;
|
||||
v.handle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
@implementation GioAppDelegate
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
- (void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls {
|
||||
for (NSURL *url in urls) {
|
||||
gio_onOpenURI((__bridge CFTypeRef)url.absoluteString);
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
void gio_main() {
|
||||
@autoreleasepool {
|
||||
[NSApplication sharedApplication];
|
||||
GioAppDelegate *del = [[GioAppDelegate alloc] init];
|
||||
[NSApp setDelegate:del];
|
||||
|
||||
NSMenuItem *mainMenu = [NSMenuItem new];
|
||||
|
||||
NSMenu *menu = [NSMenu new];
|
||||
NSMenuItem *hideMenuItem = [[NSMenuItem alloc] initWithTitle:@"Hide"
|
||||
action:@selector(hide:)
|
||||
keyEquivalent:@"h"];
|
||||
[menu addItem:hideMenuItem];
|
||||
NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
|
||||
action:@selector(terminate:)
|
||||
keyEquivalent:@"q"];
|
||||
[menu addItem:quitMenuItem];
|
||||
[mainMenu setSubmenu:menu];
|
||||
NSMenu *menuBar = [NSMenu new];
|
||||
[menuBar addItem:mainMenu];
|
||||
[NSApp setMainMenu:menuBar];
|
||||
|
||||
globalWindowDel = [[GioWindowDelegate alloc] init];
|
||||
|
||||
[NSApp run];
|
||||
}
|
||||
}
|
||||
|
||||
@interface AppListener : NSObject
|
||||
@end
|
||||
|
||||
static AppListener *appListener;
|
||||
|
||||
@implementation AppListener
|
||||
- (void)launchFinished:(NSNotification *)notification {
|
||||
appListener = nil;
|
||||
gio_onFinishLaunching();
|
||||
}
|
||||
@end
|
||||
|
||||
void gio_init() {
|
||||
@autoreleasepool {
|
||||
appListener = [[AppListener alloc] init];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:appListener
|
||||
selector:@selector(launchFinished:)
|
||||
name:NSApplicationDidFinishLaunchingNotification
|
||||
object:nil];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user