From 1fcc861e1b02bff9f807340d478acef9f277fc7e Mon Sep 17 00:00:00 2001 From: Ronie Salgado Date: Fri, 15 Jan 2021 18:51:53 -0300 Subject: [PATCH] I implemented the missing plumbing machinery for translating custom URL schemes in OS X into drop events. --- .../vm/OSX/sqSqueakOSXApplication+events.h | 1 + .../vm/OSX/sqSqueakOSXApplication+events.m | 17 +++++++++ platforms/iOS/vm/OSX/sqSqueakOSXCGView.m | 37 +++++++++++++------ platforms/iOS/vm/OSX/sqSqueakOSXDropAPI.m | 17 +++++++-- platforms/iOS/vm/OSX/sqSqueakOSXMetalView.m | 34 ++++++++++++----- platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m | 36 ++++++++++++------ platforms/iOS/vm/OSX/sqSqueakOSXView.h | 7 ++-- 7 files changed, 110 insertions(+), 39 deletions(-) diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.h b/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.h index 22f103f7bf..11c3d3ba25 100644 --- a/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.h +++ b/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.h @@ -53,5 +53,6 @@ - (int) mapMouseAndModifierStateToSqueakBits: (NSEvent *) event; - (int) translateCocoaModifiersToSqueakModifiers: (NSUInteger) modifiers; - (void) recordDragEvent: (int) dragType numberOfFiles: (int) numFiles where: (NSPoint) local_point windowIndex: (sqInt) windowIndex view:(NSView *)aView; +- (void) recordURLEvent: (int) dragType numberOfFiles: (int) numFiles; - (void) recordWindowEvent: (int) type window: (NSWindow *) window; @end diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.m b/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.m index 8c6b09a6af..22f3fd1aa5 100644 --- a/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.m +++ b/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.m @@ -561,6 +561,23 @@ - (void) recordDragEvent:(int)dragType numberOfFiles:(int)numFiles where:(NSPoin interpreterProxy->signalSemaphoreWithIndex(gDelegateApp.squeakApplication.inputSemaphoreIndex); } +- (void) recordURLEvent:(int)dragType numberOfFiles:(int)numFiles +{ + sqDragDropFilesEvent evt; + + evt.type= EventTypeDragDropFiles; + evt.timeStamp= ioMSecs(); + evt.dragType= dragType; + evt.x = 0; + evt.y = 0; + evt.modifiers= 0; + evt.numFiles= numFiles; + evt.windowIndex = 0; + [self pushEventToQueue: (sqInputEvent *) &evt]; + + interpreterProxy->signalSemaphoreWithIndex(gDelegateApp.squeakApplication.inputSemaphoreIndex); +} + - (void) recordWindowEvent: (int) windowEventType window: (NSWindow *) window { sqWindowEvent evt; diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXCGView.m b/platforms/iOS/vm/OSX/sqSqueakOSXCGView.m index 99e92ae99b..d1493c252a 100644 --- a/platforms/iOS/vm/OSX/sqSqueakOSXCGView.m +++ b/platforms/iOS/vm/OSX/sqSqueakOSXCGView.m @@ -86,6 +86,11 @@ - (void)initialize { dragItems = NULL; clippyIsEmpty = YES; colorspace = CGColorSpaceCreateDeviceRGB(); + + NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; + [appleEventManager setEventHandler:self + andSelector:@selector(handleGetURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass andEventID:kAEGetURL]; } - (void) initializeVariables { @@ -566,8 +571,7 @@ - (NSMutableArray *) filterSqueakImageFilesFromDraggedFiles: (id return results; } - -- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedFiles: (id)info { +- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedURIs: (id)info { NSPasteboard *pboard= [info draggingPasteboard]; NSMutableArray *results = [NSMutableArray arrayWithCapacity: 10]; if ([[pboard types] containsObject: NSFilenamesPboardType]) { @@ -575,14 +579,17 @@ - (NSMutableArray *) filterOutSqueakImageFilesFromDraggedFiles: (id)info { - NSArray *files = [self filterOutSqueakImageFilesFromDraggedFiles: info]; + NSArray *files = [self filterOutSqueakImageFilesFromDraggedURIs: info]; return [files count]; } @@ -616,7 +623,7 @@ - (void) draggingExited: (id)info - (BOOL) performDragOperation: (id)info { if (self.dragCount) { - self.dragItems = [self filterOutSqueakImageFilesFromDraggedFiles: info]; + self.dragItems = [self filterOutSqueakImageFilesFromDraggedURIs: info]; [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: SQDragDrop numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex view: self]; } @@ -642,13 +649,21 @@ - (BOOL) performDragOperation: (id)info { return YES; } -- (NSString*) dragFileNameStringAtIndex: (sqInt) index { - if (!self.dragItems) - return NULL; - if (index < 1 || index > [self.dragItems count]) +- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent +{ + NSString* urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; + NSURL *url = [NSURL URLWithString: urlString]; + dragItems = [NSMutableArray arrayWithCapacity: 1]; + [dragItems addObject: url]; + + [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordURLEvent: SQDragDrop numberOfFiles: 1]; +} + +- (NSURL*) dragURIAtIndex: (sqInt) index { + if (!self.dragItems || index < 1 || index > [self.dragItems count]) return NULL; - NSString *filePath = [self.dragItems objectAtIndex: (NSUInteger) index - 1]; - return filePath; + + return (self.dragItems)[(NSUInteger) index - 1]; } diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXDropAPI.m b/platforms/iOS/vm/OSX/sqSqueakOSXDropAPI.m index ff471039d7..5e694f4d9d 100644 --- a/platforms/iOS/vm/OSX/sqSqueakOSXDropAPI.m +++ b/platforms/iOS/vm/OSX/sqSqueakOSXDropAPI.m @@ -51,13 +51,22 @@ sqInt dropShutdown(void) { }; char *dropRequestFileName(sqInt dropIndex) { - /* return file name or NULL if error */ NSView *view = [((sqSqueakOSXScreenAndWindow*)((__bridge NSWindow *)windowHandleFromIndex(1)).delegate) getMainViewOnWindow]; - NSString *fileNameString = [view dragFileNameStringAtIndex: dropIndex]; - return (char *) [fileNameString UTF8String]; + NSURL *dragURIAtIndex = [view dragURIAtIndex: dropIndex]; + if(!dragURIAtIndex || !dragURIAtIndex.fileURL) + return NULL; + + return (char *) [dragURIAtIndex.path UTF8String]; } -char *dropRequestURI(sqInt dropIndex) { return NULL; } +char *dropRequestURI(sqInt dropIndex) { + NSView *view = [((sqSqueakOSXScreenAndWindow*)((__bridge NSWindow *)windowHandleFromIndex(1)).delegate) getMainViewOnWindow]; + NSURL *dragURIAtIndex = [view dragURIAtIndex: dropIndex]; + if(!dragURIAtIndex) + return NULL; + + return (char *) [dragURIAtIndex.absoluteString UTF8String]; +} /* note: dropRequestFileHandle needs to bypass plugin security checks when implemented */ sqInt dropRequestFileHandle(sqInt dropIndex) { diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXMetalView.m b/platforms/iOS/vm/OSX/sqSqueakOSXMetalView.m index acfdf21288..b367f2df61 100644 --- a/platforms/iOS/vm/OSX/sqSqueakOSXMetalView.m +++ b/platforms/iOS/vm/OSX/sqSqueakOSXMetalView.m @@ -169,6 +169,11 @@ - (void)initialize { colorspace = CGColorSpaceCreateDeviceRGB(); [self initializeSqueakColorMap]; [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(didEnterFullScreen:) name:@"NSWindowDidEnterFullScreenNotification" object:nil]; + + NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; + [appleEventManager setEventHandler:self + andSelector:@selector(handleGetURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass andEventID:kAEGetURL]; } - (void) didEnterFullScreen: (NSNotification*) aNotification { @@ -781,8 +786,7 @@ - (NSMutableArray *) filterSqueakImageFilesFromDraggedFiles: (id return results; } - -- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedFiles: (id)info { +- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedURIs: (id)info { NSPasteboard *pboard= [info draggingPasteboard]; NSMutableArray *results = [NSMutableArray arrayWithCapacity: 10]; if ([[pboard types] containsObject: NSFilenamesPboardType]) { @@ -790,14 +794,17 @@ - (NSMutableArray *) filterOutSqueakImageFilesFromDraggedFiles: (id)info { - NSArray *files = [self filterOutSqueakImageFilesFromDraggedFiles: info]; + NSArray *files = [self filterOutSqueakImageFilesFromDraggedURIs: info]; return [files count]; } @@ -836,7 +843,7 @@ - (void) draggingExited: (id)info - (BOOL) performDragOperation: (id)info { // NSLog(@"performDragOperation %@",info); if (self.dragCount) { - self.dragItems = [self filterOutSqueakImageFilesFromDraggedFiles: info]; + self.dragItems = [self filterOutSqueakImageFilesFromDraggedURIs: info]; [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: SQDragDrop numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex view: self]; } @@ -860,14 +867,23 @@ - (BOOL) performDragOperation: (id)info { return YES; } -- (NSString*) dragFileNameStringAtIndex: (sqInt) index { - if (!self.dragItems - || index < 1 || index > [self.dragItems count]) +- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent +{ + NSString* urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; + NSURL *url = [NSURL URLWithString: urlString]; + dragItems = [NSMutableArray arrayWithCapacity: 1]; + [dragItems addObject: url]; + + [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordURLEvent: SQDragDrop numberOfFiles: 1]; +} + +- (NSURL*) dragURIAtIndex: (sqInt) index { + if (!self.dragItems || index < 1 || index > [self.dragItems count]) return NULL; + return (self.dragItems)[(NSUInteger) index - 1]; } - - (BOOL)ignoreModifierKeysWhileDragging { return YES; } diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m b/platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m index ef7504f9b1..e9891818ce 100644 --- a/platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m +++ b/platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m @@ -204,6 +204,10 @@ - (void)initialize { [self initializeSqueakColorMap]; [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(didEnterFullScreen:) name:@"NSWindowDidEnterFullScreenNotification" object:nil]; + NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; + [appleEventManager setEventHandler:self + andSelector:@selector(handleGetURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass andEventID:kAEGetURL]; } - (void) didEnterFullScreen: (NSNotification*) aNotification { @@ -999,8 +1003,7 @@ - (NSMutableArray *) filterSqueakImageFilesFromDraggedFiles: (id return results; } - -- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedFiles: (id)info { +- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedURIs: (id)info { NSPasteboard *pboard= [info draggingPasteboard]; NSMutableArray *results = [NSMutableArray arrayWithCapacity: 10]; if ([[pboard types] containsObject: NSFilenamesPboardType]) { @@ -1008,14 +1011,17 @@ - (NSMutableArray *) filterOutSqueakImageFilesFromDraggedFiles: (id)info { - NSArray *files = [self filterOutSqueakImageFilesFromDraggedFiles: info]; + NSArray *files = [self filterOutSqueakImageFilesFromDraggedURIs: info]; return [files count]; } @@ -1054,7 +1060,7 @@ - (void) draggingExited: (id)info - (BOOL) performDragOperation: (id)info { // NSLog(@"performDragOperation %@",info); if (self.dragCount) { - self.dragItems = [self filterOutSqueakImageFilesFromDraggedFiles: info]; + self.dragItems = [self filterOutSqueakImageFilesFromDraggedURIs: info]; [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: SQDragDrop numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex view: self]; } @@ -1080,13 +1086,21 @@ - (BOOL) performDragOperation: (id)info { return YES; } -- (NSString*) dragFileNameStringAtIndex: (sqInt) index { - if (!self.dragItems) - return NULL; - if (index < 1 || index > [self.dragItems count]) +- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent +{ + NSString* urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; + NSURL *url = [NSURL URLWithString: urlString]; + dragItems = [NSMutableArray arrayWithCapacity: 1]; + [dragItems addObject: url]; + + [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordURLEvent: SQDragDrop numberOfFiles: 1]; +} + +- (NSURL*) dragURIAtIndex: (sqInt) index { + if (!self.dragItems || index < 1 || index > [self.dragItems count]) return NULL; - NSString *filePath = (self.dragItems)[(NSUInteger) index - 1]; - return filePath; + + return (self.dragItems)[(NSUInteger) index - 1]; } diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXView.h b/platforms/iOS/vm/OSX/sqSqueakOSXView.h index d893bebe51..dfe01e77c6 100644 --- a/platforms/iOS/vm/OSX/sqSqueakOSXView.h +++ b/platforms/iOS/vm/OSX/sqSqueakOSXView.h @@ -53,12 +53,11 @@ - (void) ioSetFullScreen: (sqInt) fullScreen; - (NSUInteger) countNumberOfNoneSqueakImageFilesInDraggedFiles: (id)info; -- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedFiles: (id)info; +- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedURIs: (id)info; - (NSMutableArray *) filterSqueakImageFilesFromDraggedFiles: (id)info; -- (NSString*) dragFileNameStringAtIndex:(sqInt) index; - +- (NSURL*) dragURIAtIndex:(sqInt) index; - (void) drawThelayers; - (void) preDrawThelayers; - (void) drawImageUsingClip: (CGRect) clip; -@end \ No newline at end of file +@end