I have a subclassed NSView
which is part of a .xib-file of a subclassed NSDocument
, which gets alive by the default behaviour of NSDocumentController
's openDocument:
method. In this subclassed NSView
I have implemented the methods awakeFromNib
, in which the view's NSWindow
setAcceptsMouseMovedEvents:YES
method is called, and acceptsFirstMouse:
, which returns YES
. But my mouseMoved:
method implementation of my subclassed NSView
doesn't get called when I move the mouse over it. What might be the problem?

- 2,439
- 1
- 23
- 29
-
Depending on your use case, you may be able to use MouseDragged. That works without an NSTrackingArea, but it only fires if the mouse is down. – William Jockusch Jul 05 '16 at 08:07
6 Answers
Be sure to request the mouseMoved event is sent:
NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect |
NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved);
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:options
owner:self
userInfo:nil];
-
One note. I'm not sure it should be an int but rather an NSInteger type or the typedef preferably NSTrackingAreaOptions which is infinitely more readable and guaranteed to be the right type. – uchuugaka Jul 22 '14 at 10:47
-
7This is correct, but doesn't give any context as to where this should be called. See https://stackoverflow.com/a/41878227/5552584 for that information. – Aᴄʜᴇʀᴏɴғᴀɪʟ Apr 11 '18 at 06:38
As noted by others, an NSTrackingArea
is a good solution, and an appropriate place to install the tracking area is NSView.updateTrackingAreas()
. It isn't necessary to set the containing NSWindow's setAcceptsMouseMovedEvents
property.
In Swift 3:
class CustomView : NSView {
var trackingArea : NSTrackingArea?
override func updateTrackingAreas() {
if trackingArea != nil {
self.removeTrackingArea(trackingArea!)
}
let options : NSTrackingAreaOptions =
[.mouseEnteredAndExited, .mouseMoved, .activeInKeyWindow]
trackingArea = NSTrackingArea(rect: self.bounds, options: options,
owner: self, userInfo: nil)
self.addTrackingArea(trackingArea!)
}
override func mouseMoved(with event: NSEvent) {
Swift.print("Mouse moved: \(event)")
}
}

- 4,953
- 45
- 48

- 2,067
- 2
- 16
- 15
-
.mouseEnteredAndExited, .mouseMoved, .activeInKeyWindow => .mouseEnteredAndExited, .mouseMoved, .activeInKeyWindow – andrewchan2022 Jun 12 '18 at 14:03
-
1This sample code saved by day. TIL about updateTrackingAreas. Thanks! – Gwendal Roué Dec 03 '19 at 16:47
I haven't used mouseMoved:
in a real project (I've just played around with it a little). As far as I can tell, mouseMoved:
is only called when your view is the first responder and then not only while the mouse is over your view, but always when the mouse moves. You might be better off using an NSTrackingArea. Check the Cocoa Event Handling Guide for more information.

- 447
- 3
- 10
-
4
-
1See below. You need a tracking area installed in order to begin receiving these events. – uchuugaka Jul 22 '14 at 10:44
Deshitified version of @jbouwman s answer:
override func updateTrackingAreas() {
self.addTrackingArea(NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .mouseMoved, .activeInKeyWindow], owner: self, userInfo: nil))
}
-
-
This will cause the tracking area to be added multiple times, which results in getting multiple mouse events. @jbouwman's code avoids that. – fbitterlich Oct 29 '21 at 22:11
Just incase anyone else runs into this. I ran into an issue where I was subclassing a subclass and was trying to add a tracking area to both classes (for two different reasons).
If you are doing something like this, you will need to make sure that your mouseMoved:
, etc call into the super, or only one of your subclasses will receive the message.
- (void) mouseMoved: (NSEvent*) theEvent
{
// Call the super event
[super mouseMoved: theEvent];
}

- 17,317
- 32
- 140
- 246
oc version:
- (void)updateTrackingAreas {
[self initTrackingArea];
}
-(void) initTrackingArea {
NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect |
NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved);
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:options
owner:self
userInfo:nil];
[self addTrackingArea:area];
}

- 4,953
- 45
- 48