Skip navigation.
 
mlErratic behaviour in mouseDown: method of NSTableView
FROM : Greg Hurrell
DATE : Tue Apr 26 20:49:20 2005

I have a table view that uses custom subclasses of NSTableView, 
NSTableColumn and various NSCell subclasses. I have noticed that the 
performance of the table view is quite sluggish and that it seems to 
miss mouse clicks at times. This is not a problem that is unique to 
my custom table view but something that you can see in any Cocoa 
application that uses table views; try clicking rapidly on a checkbox 
or similar control inside such a table view and you'll see that some 
of the clicks get missed (for example, I'm writing this in Mail.app; 
try checking and unchecking in the "Rules" section of the preferences 
and you'll see what I mean). I don't see the problem in Carbon apps 
(for example, checking and unchecking songs in iTunes).

So I came up with a minimal test case which does basically nothing 
more than add NSLog statements in this method of the NSTableView 
subclass:

- (void)mouseDown:(NSEvent *)theEvent

And this method of the NSCell subclasses:

- (BOOL)trackMouse:(NSEvent *)theEvent
            inRect:(NSRect)cellFrame
            ofView:(NSView *)controlView
      untilMouseUp:(BOOL)untilMouseUp

What I notice is that the table view always receives the mouse down 
event no matter how fast you click, but that if you click rapidly it 
will only call the mouse tracking method in the cell some of the 
times (you don't have to click very fast to get this to happen).

I had a very quick attempt at replacing the mouseDown: method (ie. 
not calling the super implementation but doing everything on my own) 
but I don't think it's a path worth going down as I'll have to do an 
awful lot to replicate the Cocoa behaviour. What I do know from my 
own investigations and from reading the archives is that NSTableView 
is setting up a modal even loop inside mouseDown: and eats up all the 
events up to and including the finally mouse-up event, and along the 
way it is handling things like selection behaviour, determining which 
cells need to be set up for each row, copying cells before passing 
them the trackMouse:inRect:ofView:untilMouseUp: message, releasing 
the cells. It's also modifying its behaviour depending on the class 
of the cell in question (for example, it sets untilMouseUp to NO in 
the case of NSButtonCells and YES in the case of NSStepperCells). I 
suspect it is doing an awful lot more under the hood in addition to 
all this too.

Basically, it's probably too much of a reverse engineering task to 
bother with, and even if I could exactly match Cocoa's behaviour I 
might not eliminate the problem of the missed clicks. Given that the 
problem exists even in Apple's flagship Cocoa apps (like Mail.app) 
it's likely that there are no easy fixes, because if there were Apple 
would have fixed it already.

Any thoughts?

Cheers,
Greg

Related mailsAuthorDate
No related mails found.