Open onmyway133 opened 1 year ago
Create a custom NSView that handles mouseDragged to beginDraggingSession
NSView
mouseDragged
beginDraggingSession
struct DraggingSourceViewWrapper: NSViewRepresentable { let fileUrls: [URL] let onEnd: () -> Void func makeNSView(context: Context) -> DraggingSourceView { let view = DraggingSourceView(fileUrls: fileUrls) view.onEnd = onEnd return view } func updateNSView(_ view: DraggingSourceView, context: Context) { view.onEnd = onEnd } } final class DraggingSourceView: NSView { let fileUrls: [URL] var onEnd: (() -> Void)? init(fileUrls: [URL]) { self.fileUrls = fileUrls super.init(frame: .zero) } required init?(coder: NSCoder) { fatalError() } override func mouseDown(with event: NSEvent) { // NOTE: Needed for mouseDragged to work } override func mouseDragged(with event: NSEvent) { let draggingItems = fileUrls.map { url in let pasteboardItem = NSPasteboardItem() pasteboardItem.setString(url.absoluteString, forType: .string) pasteboardItem.setDataProvider(self, forTypes: [.fileURL]) let image = NSWorkspace.shared.icon(forFile: url.path) let draggingItem = NSDraggingItem(pasteboardWriter: pasteboardItem) draggingItem.setDraggingFrame(bounds, contents: image) return draggingItem } beginDraggingSession(with: draggingItems, event: event, source: self) } } extension DraggingSourceView: NSDraggingSource { func draggingSession( _ session: NSDraggingSession, sourceOperationMaskFor context: NSDraggingContext ) -> NSDragOperation { switch context { case .outsideApplication: return .move default: return .private } } func draggingSession(_ session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) { onEnd?() } } extension DraggingSourceView: NSPasteboardItemDataProvider { nonisolated func pasteboard( _ pasteboard: NSPasteboard?, item: NSPasteboardItem, provideDataForType type: NSPasteboard.PasteboardType ) { guard let string = item.string(forType: .string), let url = URL(string: string) else { return } if let url = BookmarkService.shared.resolve(url: url) { url.access { let data = url.absoluteString.data(using: .utf8) ?? Data() item.setData(data, forType: .fileURL) } } } }
Create a custom
NSView
that handlesmouseDragged
tobeginDraggingSession