NSButton mouseDown mouseUp behaves differently when enabled

If NSButton is not enabled, mouseDown: and mouseUp: behave as expected (therefore, when the mouse is pressed down, mouseDown: is called, and when it is issued, mouseUp is called :)

However, if NSButton IS is enabled than mouseUp: is not called at all, and mouseDown: is called AFTER the mouse was released

- (void)mouseDown:(NSEvent *)theEvent { [super mouseDown:theEvent]; } - (void)mouseUp:(NSEvent *)theEvent { [super mouseUp:theEvent]; } 

Why does this behave differently and how can I get the correct behavior (same as when the button is NOT turned on)

+8
cocoa nsview nscontrol macos nsbutton
source share
4 answers

To get rid of the previous one, if you want to create a custom button, the way in which it can distinguish clicking on releases from releases, try adding the isPressed property to it and the following code:

  (void)mouseDown:(NSEvent *)event { self.isPressed = true; [super mouseDown:event]; self.isPressed = false; [self.target performSelector:self.action withObject:self]; } 

A custom button must be configured to send actions to:

 [self.button sendActionOn: NSLeftMouseDownMask | NSLeftMouseUpMask]; 

Without this, the action method is not called until the button is released.

In the action method, you can request isPressed . eg:

 int state = (int)[sender isPressed]; 

The unfortunate but harmless β€œfeature” of this is that the action method is called twice when the button is released: once from within the NSButton with isPressed is still true. (This should be ignored.) The second time from the user button is the performSelector method, with isPressed false.

Any comments if this might work in future versions?

+2
source share

if someone is still looking for this ... I don't know why, but it works for me ...

 - (void)mouseDown:(NSEvent *)theEvent { NSLog(@"mouse down!"); [super mouseDown:theEvent]; NSLog(@"mouse up!"); } 
+13
source share

The behavior is correct. Your expectation that all mouse-related events go through responder methods is wrong.

When the button is turned on, the implementation of the superclass -mouseDown: will start an internal event tracking loop to track mouse movement and show the button pressed while the mouse is inside it, and show it as not pressed when the mouse exits. This internal event loop receives the NSLeftMouseUp event. He never went to the defendant method.

See Cocoa Event Handling Guide: Handling Mouse Events - Handling Drag and Drop Operations - Approaching Mouse Tracking .

+5
source share

Creating the rest, here Swift works in parallel with the Objective-C mouse tracking path in the Apple documentation for the NSButton subclass. Our code stores events, but does not pass them to the superclass and its event loop.

 override func mouseDown(theEvent: NSEvent) { var isInside: Bool = true Swift.print( "MyButton Mouse Down" ) self.highlighted = isInside while true { let event = self.window?.nextEventMatchingMask( Int(NSEventMask.LeftMouseUpMask.union(.LeftMouseDraggedMask).rawValue)) let mouseLoc = self.convertPoint((event?.locationInWindow)!, toView: nil) isInside = CGRectContainsPoint(self.bounds, mouseLoc) if event?.type == .LeftMouseDragged { self.highlighted = isInside } else if event?.type == .LeftMouseUp { self.highlighted = false if isInside { Swift.print( "MyButton Mouse Up" ) } break } } 
0
source share

All Articles