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
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() {}