Files
ElyOffice/tests/scripts/drop.swift
T
ZacharyZhang-NY b7fca0146d Ely Office: six offline-first desktop apps in Rust and GPUI
ElyDoc, ElyTable, ElyShow (LibreOfficeKit), ElyPDF (MuPDF), ElyTree (Git),
ElyMark (Milkdown and CodeMirror in CEF). ElyMail and ElyAgent follow.
2026-10-08 21:20:08 -04:00

60 lines
2.0 KiB
Swift

// Drags a file from its window onto x, y.
import AppKit
let args = CommandLine.arguments
let file = URL(fileURLWithPath: args[1])
let target = CGPoint(x: Double(args[2])!, y: Double(args[3])!)
let start = CGPoint(x: 60, y: 60)
final class Source: NSView, NSDraggingSource {
func draggingSession(_: NSDraggingSession, sourceOperationMaskFor _: NSDraggingContext) -> NSDragOperation {
.copy
}
func draggingSession(_: NSDraggingSession, endedAt _: NSPoint, operation: NSDragOperation) {
print(operation.isEmpty ? "refused" : "dropped")
exit(0)
}
override func acceptsFirstMouse(for _: NSEvent?) -> Bool {
true
}
override func mouseDown(with event: NSEvent) {
let item = NSDraggingItem(pasteboardWriter: file as NSURL)
item.setDraggingFrame(bounds, contents: NSImage(size: bounds.size))
beginDraggingSession(with: [item], event: event, source: self)
}
}
func post(_ type: CGEventType, _ at: CGPoint) {
CGEvent(mouseEventSource: nil, mouseType: type, mouseCursorPosition: at, mouseButton: .left)?
.post(tap: .cghidEventTap)
usleep(40000)
}
let app = NSApplication.shared
app.setActivationPolicy(.accessory)
let height = NSScreen.screens[0].frame.height
let frame = NSRect(x: start.x - 20, y: height - start.y - 20, width: 40, height: 40)
let window = NSWindow(contentRect: frame, styleMask: .borderless, backing: .buffered, defer: false)
window.contentView = Source(frame: NSRect(x: 0, y: 0, width: 40, height: 40))
window.level = .floating
window.orderFrontRegardless()
DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
post(.mouseMoved, start)
post(.leftMouseDown, start)
for step in 1...30 {
let t = Double(step) / 30
post(.leftMouseDragged, CGPoint(x: start.x + (target.x - start.x) * t, y: start.y + (target.y - start.y) * t))
}
usleep(300000)
post(.leftMouseDragged, target)
post(.leftMouseUp, target)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
print("timeout")
exit(1)
}
app.run()