     case doneDragging(atTime: NSDate)
 }
 
-private struct ObserveApplicationNotifications {
+class MouseStateKeeper {
+    public var state: MouseState
+    init() {
+        state = .pointing
+    }
+}
+
+private class ObserveApplicationNotifications {
     enum Error: Swift.Error {
         case failed
     }
 
     fileprivate let application: SIApplication
     fileprivate let windowManager: WindowManager
+    fileprivate let mouse: MouseStateKeeper
+
+    init(application app: SIApplication, windowManager wm: WindowManager) {
+        application = app
+        windowManager = wm
+        mouse = wm.mouseStateKeeper
+    }
 
     fileprivate func addObservers() -> Observable<Bool> {
         return _addObservers().retry(.exponentialDelayed(maxCount: 4, initial: 0.1, multiplier: 2))

        let application = self.application
        let windowManager = self.windowManager

        var mouseState: MouseState = .pointing
        let mouseEventsToWatch: NSEvent.EventTypeMask = [.leftMouseDown, .leftMouseUp, .leftMouseDragged]

        NSEvent.addGlobalMonitorForEvents(matching: mouseEventsToWatch) { anEvent in
            switch anEvent.type {
            case .leftMouseDown:
                mouseState = .clicking
            case .leftMouseDragged:
                switch mouseState {
                case .moving, .resizing:
                    () // ignore - we have what we need
                default:
                    mouseState = .dragging
                }

            case .leftMouseUp:
                switch mouseState {
                case .clicking:
                    mouseState = .pointing
                case .pointing:
                    mouseState = .pointing
                case .dragging:
                    // assume window move event will come shortly after
                    mouseState = .doneDragging(atTime: NSDate())
                case let .moving(draggedWindow):
                    self.swapDraggedWindowWithDropzone(draggedWindow)
                    mouseState = .pointing
                case let .resizing(resizedWindow):
                    mouseState = .pointing
                case .doneDragging:
                    mouseState = .doneDragging(atTime: NSDate()) // reset the clock I guess
                }

            default: ()

                    windowManager.markScreenForReflow(screen, withChange: .focusChanged(window: focusedWindow))
                }
            }

            application.observeNotification(kAXApplicationActivatedNotification as CFString!, with: application) { _ in
                NSObject.cancelPreviousPerformRequests(
                    withTarget: windowManager,
