FROM : Quincey Morris
DATE : Mon Jan 28 08:46:42 2008
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.
DATE : Mon Jan 28 08:46:42 2008
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.
| Related mails | Author | Date |
|---|---|---|
| quinceymorris | Jan 25, 23:51 | |
| Jayson Adams | Jan 26, 00:38 | |
| quinceymorris | Jan 26, 01:19 | |
| Jayson Adams | Jan 26, 02:43 | |
| Quincey Morris | Jan 28, 01:54 | |
| Jayson Adams | Jan 28, 02:41 | |
| Quincey Morris | Jan 28, 08:46 | |
| Jayson Adams | Jan 28, 18:51 | |
| Clark Cox | Jan 28, 19:24 | |
| Jayson Adams | Jan 28, 19:51 | |
| Hamish Allan | Jan 28, 20:21 | |
| Jayson Adams | Jan 28, 20:26 | |
| Hamish Allan | Jan 28, 20:44 | |
| Jayson Adams | Jan 28, 21:02 | |
| Hamish Allan | Jan 28, 23:59 | |
| Sam Stigler | Jan 29, 01:31 | |
| Wesley Smith | Jan 29, 01:41 | |
| Jayson Adams | Jan 29, 02:26 | |
| Hamish Allan | Jan 29, 14:03 | |
| Clark Cox | Jan 29, 17:23 | |
| John Stiles | Jan 29, 18:36 | |
| Quincey Morris | Jan 29, 19:32 | |
| Scott Anguish | Jan 30, 03:41 | |
| Scott Anguish | Jan 30, 03:43 | |
| Hamish Allan | Jan 30, 06:20 | |
| Quincey Morris | Jan 30, 08:34 |






Cocoa mail archive

