Re: The mouse is where, again?
Re: The mouse is where, again?
- Subject: Re: The mouse is where, again?
- From: Quincey Morris <email@hidden>
- Date: Sun, 27 Jan 2008 23:46:42 -0800
On Jan 27, 2008, at 17:41, Jayson Adams wrote:
The answer to whether or not the mouse is within the tracking rect
bounds is NSPointInRect([NSEvent mouseLocation], trackingRect) (you
have to convert the mouse location to your view coordinate system,
of course).
I'm wondering where this information came from.
-- Are you sure it's not NSMouseInRect([NSEvent mouseLocation],
trackingRect,flipped), or [view mouse: [NSEvent mouseLocation] inRect:
trackingRect] (with everything converted to the correct coordinate
system)?
-- Are you sure that the tracking area code doesn't allow for nested
subviews and/or tracking areas? Does it handle overlapping sibling
views and/or tracking areas in a predictable way? A single rectangle
test won't work in those situations. (I suppose every tracking area
might be handled independently, with mouseEntered and mouseExited
messages for all of the views under the mouse simultaneously, but the
documentation doesn't say this, I don't think. It certainly can't work
this way for the cursorUpdate part of the tracking function, because
it has to pick a single tracking area to take charge of the cursor at
any given moment. But if true, then yes of course a single rectangle
test would work.)
-- IAC, even if you know the algorithm, the correctness of the answer
still depends on the correctness of using [NSEvent mouseLocation] at
all.
(Remember that I was asking about NSTrackingArea, not NSTrackingRect,
if it makes any difference.)
But I also argue that the only thing that *ever* really matters is
where the mouse is, as you say, *now*. ... If I'm dragging out a
selection rect, for example, it's a bug if the corner of the
selection rect is not always under the mouse.
This is intuitive, plausible, but ... wrong. For example, it's
clearly a bug if the corner of the selection rect *is* under the
mouse, if the mouse button has been released but you don't know it
yet because the mouseUp event is still in the event queue. (It only
took me 3 days to figure that out.)
Sorry, it's correct. And why would the mouse up event ever just be
sitting in the event queue?
We're talking about a standard event loop here where you do
something on each drag event. The only difference is using the
current mouse location instead of the mouse location as claimed by
the drag event:
while ([nextEvent type] != NSLeftMouseUp) {
mouseLocation = [[self window]
mouseLocationOutsideOfEventStream];
if (NSEqualPoints(mouselocation, lastMouseLocation)) {
continue;
}
lastMouseLocation = mouseLocation;
/* mouse drag processing */
nextEvent = [[self window]
nextEventMatchingMask:NSLeftMouseDraggedMask | NSLeftMouseUpMask];
}
Let me lay the example out a bit more specifically, and see if I can
change your mind.
Suppose (for simplicity) the mouse happens to be moving smoothly along
the 45-degree diagonal. So it starts at (0,0) and moves through
(50,50) and (100,100) and (200,200) and so on.
Suppose that the mouse-down is at (0,0), and the mouse-up is at
(200,200).
Now imagine the state of the application in the middle of the dragging
sequence, at a moment when it's still processing a mouse-moved event
whose location is (100,100).
It's entirely possible (see below for more about this) that while this
event is being processed in the body of your while loop, there's
*already* another event in the queue -- in particular, the mouse-up at
(200,200).
It's *also* entirely possible that at the same moment, while the same
mouse-moved (100,100) event is being processed, the mouse itself is
*already* (in real-time) at (300,300).
In these circumstances, would it be correct or incorrect to extend to
(300,300) a selection rect being dragged out? I'm saying it would be
incorrect, because the user never dragged that far (having released
the mouse button about 141.4 diagonal pixels ago), as the application
will see the next time through the while loop when it processes the
next event in the queue. If there happened to be an object of some
kind at (300,300), selecting it would surprise the user.
This kind of defect used to show up frequently in many poorly written
Windows applications (some years ago, at least, when I had a reason to
care what Windows applications did) which lazily used the current
mouse location in place of the event queue mouse location. You had to
be really careful when clicking on things to let the application catch
up with the event queue (far more clogged in Windows than on the Mac)
or you'd find you had clicked the wrong thing by mistake.
And why would the mouse up event ever just be sitting in the event
queue?
Well, it would be sitting in the event queue if it was put there
before the application had finished processing earlier events. If it's
put in the queue at all, it's going to sit there for at least some
time before it's retrieved. And, it may *linger* in the event queue if
the application is a bit slow in processing an earlier event, or if
another process uses up the available CPU time for a while. Both of
those scenarios happen quite a lot on my iMac G5.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden