From cce63c55fab1480c10171106e3ac5bda9d86f562 Mon Sep 17 00:00:00 2001 From: StarHack Date: Sat, 25 Feb 2023 12:44:16 +0100 Subject: [PATCH] darwin-external-dragndrop: implement external drag n' drop for darwin --- app/os_macos.go | 21 +++++++++++++++++++++ app/os_macos.m | 15 +++++++++++++++ io/router/router.go | 8 ++++++++ 3 files changed, 44 insertions(+) diff --git a/app/os_macos.go b/app/os_macos.go index 516157aaa..68411ea41 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -8,7 +8,11 @@ package app import ( "errors" "image" + "io" + "mime" + "path/filepath" "runtime" + "strings" "time" "unicode" "unicode/utf8" @@ -18,6 +22,7 @@ import ( "gioui.org/io/key" "gioui.org/io/pointer" "gioui.org/io/system" + "gioui.org/io/transfer" "gioui.org/unit" _ "gioui.org/internal/cocoainit" @@ -557,6 +562,22 @@ func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtn C.NSInteger, x, y, dx, }) } +//export gio_onExternalDrop +func gio_onExternalDrop(view C.CFTypeRef, path *C.char) { + fileUrl := C.GoString(path) + w := mustView(view) + + fileExtension := filepath.Ext(fileUrl) + mime := mime.TypeByExtension(fileExtension) + + w.w.Event(transfer.DataEvent{ + Type: mime, + Open: func() io.ReadCloser { + return io.NopCloser(strings.NewReader(fileUrl)) + }, + }) +} + //export gio_onDraw func gio_onDraw(view C.CFTypeRef) { w := mustView(view) diff --git a/app/os_macos.m b/app/os_macos.m index 49964fbf1..dc62b5eaf 100644 --- a/app/os_macos.m +++ b/app/os_macos.m @@ -110,6 +110,20 @@ - (void)mouseMoved:(NSEvent *)event { - (void)mouseDragged:(NSEvent *)event { handleMouse(self, event, MOUSE_MOVE, 0, 0); } +-(NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender +{ + return NSDragOperationCopy; +} +- (void)draggingEnded:(id )sender +{ + NSPasteboard* pbrd = [sender draggingPasteboard]; + NSArray* droppedFiles = [pbrd propertyListForType:NSFilenamesPboardType]; + + for (NSString* filePath in droppedFiles) { + NSURL* url = [NSURL fileURLWithPath:filePath]; + gio_onExternalDrop((__bridge CFTypeRef)self, (char*)[[url path] UTF8String]); + } +} - (void)scrollWheel:(NSEvent *)event { CGFloat dx = -event.scrollingDeltaX; CGFloat dy = -event.scrollingDeltaY; @@ -366,6 +380,7 @@ CFTypeRef gio_createView(void) { @autoreleasepool { NSRect frame = NSMakeRect(0, 0, 0, 0); GioView* view = [[GioView alloc] initWithFrame:frame]; + [view registerForDraggedTypes: [NSArray arrayWithObjects:NSTIFFPboardType, NSFilenamesPboardType, nil]]; view.wantsLayer = YES; view.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize; return CFBridgingRetain(view); diff --git a/io/router/router.go b/io/router/router.go index e3b3be8d9..33dd1dc64 100644 --- a/io/router/router.go +++ b/io/router/router.go @@ -182,6 +182,14 @@ func (q *Router) Queue(events ...event.Event) bool { } case clipboard.Event: q.cqueue.Push(e, &q.handlers) + case transfer.DataEvent: + for tag, handler := range q.pointer.queue.handlers { + for _, mimeType := range (*handler).targetMimes { + if mimeType == e.Type { + q.handlers.Add(tag, e) + } + } + } } } return q.handlers.HadEvents()