Skip to content

Commit

Permalink
darwin-external-dragndrop: implement external drag n' drop for darwin
Browse files Browse the repository at this point in the history
  • Loading branch information
StarHack committed Apr 24, 2023
1 parent 5f818bc commit 0e35413
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 8 deletions.
21 changes: 21 additions & 0 deletions app/os_macos.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ package app
import (
"errors"
"image"
"io"
"mime"
"os"
"path/filepath"
"runtime"
"time"
"unicode"
Expand All @@ -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"
Expand Down Expand Up @@ -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, error) {
return os.Open(fileUrl)
},
})
}

//export gio_onDraw
func gio_onDraw(view C.CFTypeRef) {
w := mustView(view)
Expand Down
15 changes: 15 additions & 0 deletions app/os_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -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 <NSDraggingInfo>)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;
Expand Down Expand Up @@ -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);
Expand Down
18 changes: 11 additions & 7 deletions io/router/pointer.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,14 @@ func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEv
p.entered = append(p.entered[:0], hits...)
}

func (q *pointerQueue) notifyPotentialTargets(src *pointerHandler, events *handlerEvents, event event.Event) {
for k, tgt := range q.handlers {
if _, ok := firstMimeMatch(src, tgt); ok {
events.Add(k, event)
}
}
}

func (q *pointerQueue) deliverDragEvent(p *pointerInfo, events *handlerEvents) {
if p.dataSource != nil {
return
Expand All @@ -814,11 +822,7 @@ func (q *pointerQueue) deliverDragEvent(p *pointerInfo, events *handlerEvents) {
// One data source handler per pointer.
p.dataSource = k
// Notify all potential targets.
for k, tgt := range q.handlers {
if _, ok := firstMimeMatch(src, tgt); ok {
events.Add(k, transfer.InitiateEvent{})
}
}
q.notifyPotentialTargets(src, events, transfer.InitiateEvent{})
break
}
}
Expand Down Expand Up @@ -858,9 +862,9 @@ func (q *pointerQueue) deliverTransferDataEvent(p *pointerInfo, events *handlerE
transferIdx := len(q.transfers)
events.Add(p.dataTarget, transfer.DataEvent{
Type: src.offeredMime,
Open: func() io.ReadCloser {
Open: func() (io.ReadCloser, error) {
q.transfers[transferIdx] = nil
return src.data
return src.data, nil
},
})
q.transfers = append(q.transfers, src.data)
Expand Down
2 changes: 2 additions & 0 deletions io/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ func (q *Router) Queue(events ...event.Event) bool {
}
case clipboard.Event:
q.cqueue.Push(e, &q.handlers)
case transfer.DataEvent:
q.pointer.queue.notifyPotentialTargets(&pointerHandler{sourceMimes: []string{e.Type}}, &q.handlers, e)
}
}
return q.handlers.HadEvents()
Expand Down
2 changes: 1 addition & 1 deletion io/transfer/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ type DataEvent struct {
Type string
// Open returns the transfer data. It is only valid to call Open in the frame
// the DataEvent is received. The caller must close the return value after use.
Open func() io.ReadCloser
Open func() (io.ReadCloser, error)
}

func (DataEvent) ImplementsEvent() {}

0 comments on commit 0e35413

Please sign in to comment.