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 Feb 25, 2023
1 parent 5f818bc commit 450e1f3
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 0 deletions.
8 changes: 8 additions & 0 deletions app/os_macos.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

"gioui.org/internal/f32"
"gioui.org/io/clipboard"
"gioui.org/io/externalDragDrop"
"gioui.org/io/key"
"gioui.org/io/pointer"
"gioui.org/io/system"
Expand Down Expand Up @@ -557,6 +558,13 @@ 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, pbrd *C.char) {
fileUrl := C.GoString(pbrd)
w := mustView(view)
w.w.Event(externalDragDrop.Event{Text: fileUrl})
}

//export gio_onDraw
func gio_onDraw(view C.CFTypeRef) {
w := mustView(view)
Expand Down
22 changes: 22 additions & 0 deletions app/os_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,27 @@ - (void)mouseMoved:(NSEvent *)event {
- (void)mouseDragged:(NSEvent *)event {
handleMouse(self, event, MOUSE_MOVE, 0, 0);
}
-(NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender
{
return NSDragOperationCopy; // NSDragOperationGeneric
}
- (void)draggingEnded:(id <NSDraggingInfo>)sender
{
NSPasteboard* pbrd = [sender draggingPasteboard];

for (NSPasteboardItem *item in [pbrd pasteboardItems]) {
for (NSString *type in [item types]) {
if ([type isEqualToString:@"public.file-url"]) {
NSData* data = [item dataForType:type];
NSString *clipboard_url = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSURL *url = [[NSURL alloc] initWithString:clipboard_url];
NSString *real_path = url.path;
char* content = (char*)[real_path UTF8String];
gio_onExternalDrop((__bridge CFTypeRef)self, content);
}
}
}
}
- (void)scrollWheel:(NSEvent *)event {
CGFloat dx = -event.scrollingDeltaX;
CGFloat dy = -event.scrollingDeltaY;
Expand Down Expand Up @@ -366,6 +387,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
5 changes: 5 additions & 0 deletions internal/ops/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const (
TypeSnippet
TypeSelection
TypeActionInput
TypeExternalDragDrop
)

type StackID struct {
Expand Down Expand Up @@ -160,6 +161,7 @@ const (
TypeSnippetLen = 1 + 4 + 4
TypeSelectionLen = 1 + 2*4 + 2*4 + 4 + 4
TypeActionInputLen = 1 + 1
TypeExternalDragDropLen = 1
)

func (op *ClipOp) Decode(data []byte) {
Expand Down Expand Up @@ -417,6 +419,7 @@ var opProps = [0x100]opProp{
TypeSnippet: {Size: TypeSnippetLen, NumRefs: 2},
TypeSelection: {Size: TypeSelectionLen, NumRefs: 1},
TypeActionInput: {Size: TypeActionInputLen, NumRefs: 0},
TypeExternalDragDrop: {Size: TypeExternalDragDropLen, NumRefs: 1},
}

func (t OpType) props() (size, numRefs int) {
Expand Down Expand Up @@ -498,6 +501,8 @@ func (t OpType) String() string {
return "Stroke"
case TypeSemanticLabel:
return "SemanticDescription"
case TypeExternalDragDrop:
return "ExternalDragDrop"
default:
panic("unknown OpType")
}
Expand Down
27 changes: 27 additions & 0 deletions io/externalDragDrop/externalDragDrop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: Unlicense OR MIT

package externalDragDrop

import (
"gioui.org/internal/ops"
"gioui.org/io/event"
"gioui.org/op"
)

// Event is generated when the clipboard content is requested.
type Event struct {
Text string
}

// ReadOp requests the text of the clipboard, delivered to
// the current handler through an Event.
type ReadOp struct {
Tag event.Tag
}

func (h ReadOp) Add(o *op.Ops) {
data := ops.Write1(&o.Internal, ops.TypeExternalDragDropLen, h.Tag)
data[0] = byte(ops.TypeExternalDragDrop)
}

func (Event) ImplementsEvent() {}
3 changes: 3 additions & 0 deletions io/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"gioui.org/internal/ops"
"gioui.org/io/clipboard"
"gioui.org/io/event"
"gioui.org/io/externalDragDrop"
"gioui.org/io/key"
"gioui.org/io/pointer"
"gioui.org/io/profile"
Expand Down Expand Up @@ -182,6 +183,8 @@ func (q *Router) Queue(events ...event.Event) bool {
}
case clipboard.Event:
q.cqueue.Push(e, &q.handlers)
case externalDragDrop.Event:
q.handlers.Add(nil, e)
}
}
return q.handlers.HadEvents()
Expand Down

0 comments on commit 450e1f3

Please sign in to comment.