I have a custom NSView
subclass with (for example) the following methods:
override func mouseDown(with event: NSEvent) { Swift.print("mouseDown") }
override func mouseDragged(with event: NSEvent) { Swift.print("mouseDragged") }
override func mouseUp(with event: NSEvent) { Swift.print("mouseUp") }
As long as the mouse (button) is pressed, dragged and released all inside the view, this works fine. However, when the mouse is depressed inside the view, moved outside the view, and only then released, I never receive the mouseUp
event.
P.S.: Calling the super
implementations does not help.
The MouseClick event is raised. The MouseUp event is raised. If the user moves the pointer out of the toggle control while the mouse button is down (such as moving the mouse off the Button control while it is pressed), the toggle control will paint in the raised state and only the MouseUp event occurs.
contextmenu. Triggers when the right mouse button is pressed. There are other ways to open a context menu, e.g. using a special keyboard key, it triggers in that case also, so it's not exactly the mouse event.
The mouseup event is fired at an Element when a button on a pointing device (such as a mouse or trackpad) is released while the pointer is located inside it. mouseup events are the counterpoint to mousedown events.
To cause a MouseDown event for a form section to occur, press the mouse button in a blank area of the form section. The following apply to MouseDown events: If a mouse button is pressed while the pointer is over a form or control, that object receives all mouse events up to and including the last MouseUp event.
The Handling Mouse Dragging Operations section of Apple's mouse events documentation provided a solution: Apparently, we do receive the mouseUp
event when tracking events with a mouse-tracking loop.
Here's a variant of the sample code from the documentation, adapted for Swift 3:
override func mouseDown(with event: NSEvent) {
var keepOn = true
mouseDownImpl(with: event)
// We need to use a mouse-tracking loop as otherwise mouseUp events are not delivered when the mouse button is
// released outside the view.
while true {
guard let nextEvent = self.window?.nextEvent(matching: [.leftMouseUp, .leftMouseDragged]) else { continue }
let mouseLocation = self.convert(nextEvent.locationInWindow, from: nil)
let isInside = self.bounds.contains(mouseLocation)
switch nextEvent.type {
case .leftMouseDragged:
if isInside {
mouseDraggedImpl(with: nextEvent)
}
case .leftMouseUp:
mouseUpImpl(with: nextEvent)
return
default: break
}
}
}
func mouseDownImpl(with event: NSEvent) { Swift.print("mouseDown") }
func mouseDraggedImpl(with event: NSEvent) { Swift.print("mouseDragged") }
func mouseUpImpl(with event: NSEvent) { Swift.print("mouseUp") }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With