Skip to content

Instantly share code, notes, and snippets.

@corysullivan
Created May 30, 2019 17:20
Show Gist options
  • Select an option

  • Save corysullivan/9b4777073f4c565633f29ec13cb8b30c to your computer and use it in GitHub Desktop.

Select an option

Save corysullivan/9b4777073f4c565633f29ec13cb8b30c to your computer and use it in GitHub Desktop.
//
// DraggingValidator.swift
// Stash
//
// Created by Cory Sullivan on 2019-03-09.
// Copyright © 2019 Cory Sullivan. All rights reserved.
//
import Cocoa
/**
This class determines if a file is being dragged at a global system level.
When dragging a window, the last file info is still in the pasteboard,
which makes it impossible to judge whether we are dragging a file or a window.
See: [Open Radar](http://www.openradar.me/radar?id=5027980136939520)
This class distinguishes the difference between dragging a file vs a window
by inspecting the pasteboard change count. When a window is dragged
the change count is not increased.
See: [Stack Overflow](https://stackoverflow.com/a/49641490/1615621)
Also: [Blog Post](https://isaacxen.github.io//2018/03/03/detecting-file-dragging-in-cocoa/)
*/
class DraggingValidator {
private var lastChangeCount: Int
private let pasteboard = NSPasteboard(name: .drag)
private let showWindow: (Bool) -> Void
private var isDragging = false {
didSet {
if isDragging != oldValue {
showWindow(isDragging)
}
}
}
init(showWindow: @escaping (Bool) -> Void) {
self.showWindow = showWindow
lastChangeCount = NSPasteboard(name: .drag).changeCount
registerForMouseEvents()
}
func registerForMouseEvents() {
NSEvent.addGlobalMonitorForEvents(matching: .leftMouseDragged) { _ in
if self.isDragging { return }
self.isDragging = self.isFile
}
NSEvent.addGlobalMonitorForEvents(matching: .leftMouseUp) { _ in
self.isDragging = false
}
}
var isFile: Bool {
guard pasteboard.propertyList(forType: .fileURL) != nil else { return false }
let changeCount = pasteboard.changeCount
if lastChangeCount != changeCount {
lastChangeCount = changeCount
return true
}
return false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment