I ended up implementing my own mouse tracking mechanism:
// MyControl.m:
- (void)mouseDown:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
if (currentCellIndex < [cells count]) {
MKListCell *cell = [cells objectAtIndex:currentCellIndex];
currentCell = cell;
[currentCell mouseDown:theEvent];
}
}
- (void)mouseUp:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
if (currentCellIndex < [cells count]) {
MKListCell *cell = [cells objectAtIndex:currentCellIndex];
[cell mouseUp:theEvent];
}
}
- (void)mouseEntered:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
if (currentCellIndex < [cells count]) {
MKListCell *cell = [cells objectAtIndex:currentCellIndex];
currentCell = cell;
[currentCell mouseEntered:theEvent];
}
}
- (void)mouseExited:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
if (currentCellIndex < [cells count]) {
MKListCell *cell = [cells objectAtIndex:currentCellIndex];
[cell mouseExited:theEvent];
currentCell = nil;
}
}
- (void)mouseMoved:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
MKListCell *cell;
if (currentCellIndex < [cells count]) {
cell = [cells objectAtIndex:currentCellIndex];
}
if (currentCell != cell) {
[currentCell mouseExited:theEvent];
[cell mouseEntered:theEvent];
currentCell = cell;
}
else {
[currentCell mouseMoved:theEvent];
}
}
- (void)mouseDragged:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
MKListCell *cell = nil;
if (currentCellIndex < [cells count]) {
cell = [cells objectAtIndex:currentCellIndex];
}
if (currentCell != cell) {
[currentCell mouseExited:theEvent];
[cell mouseEntered:theEvent];
currentCell = cell;
}
else {
[currentCell mouseMoved:theEvent];
}
}
- (int)indexOfCellAtPoint:(NSPoint)p {
int cellIndex = (self.bounds.size.height - p.y) / cellHeight;
return cellIndex;
}
And of course, in MyCell.h
:
- (void)mouseDown:(NSEvent *)event;
- (void)mouseUp:(NSEvent *)event;
- (void)mouseMoved:(NSEvent *)event;
- (void)mouseEntered:(NSEvent *)event;
- (void)mouseExited:(NSEvent *)event;
With an empty implementation for those methods (so the compiler doesn't complain and I can leave the implementation of the mouse handling methods to subclasses).