trackingAreas can be snuck up on without triggering?

  • I have a view for which I am adding a tracking area so that I can update the cursor. The view entirely fills my window and is the only view in the window's content view.

    The tracking area is being registered thusly:

    - (void) awakeFromNib
    {
        NSTrackingArea* trackingArea = [[NSTrackingArea alloc ] initWithRect:[self bounds]
                  options:NSTrackingCursorUpdate|NSTrackingActiveInActiveApp
                  owner:self
                  userInfo:nil];
        [self addTrackingArea:trackingArea];
    }

    and I have defined in my view:

    - (void) cursorUpdate:(NSEvent *)event
    {
        NSLog(@"cursorUpdate: %@", [NSDate date]);
        [[NSCursor openHandCursor] set];
    }

    If I whip the mouse into the window's content area, my cursorUpdate method is called and I see the correct cursor. If I slowly sneak the mouse into my window's content area, I see the window resize cursor for a moment as I cross into the window content area (I'm running Lion), then... nothing. The cursor reverts to the arrow cursor, and my cursorUpdate: method is not called, even though I am well into my view's rectangle.

    If I inset my view from the boundaries of the window a bit (16-ish pixels), things behave as expected.

    What am I doing wrong?

    Sample project at <http://bugs.muratnkonar.com/trackingareas.zip>

    _murat
  • Hmmm. Running on 10.6 gives me a SIGABRT at launch.

    I can reboot under Lion and look at this in the morn if you still need another set of eyeballs.

    Cheers.

    On May 20, 2012, at 1:10 AM, <mlist0987...> wrote:

    > I have a view for which I am adding a tracking area so that I can update the cursor. The view entirely fills my window and is the only view in the window's content view.
    >
    > The tracking area is being registered thusly:
    >
    > - (void) awakeFromNib
    > {
    > NSTrackingArea* trackingArea = [[NSTrackingArea alloc ] initWithRect:[self bounds]
    > options:NSTrackingCursorUpdate|NSTrackingActiveInActiveApp
    > owner:self
    > userInfo:nil];
    > [self addTrackingArea:trackingArea];
    > }
    >
    > and I have defined in my view:
    >
    > - (void) cursorUpdate:(NSEvent *)event
    > {
    > NSLog(@"cursorUpdate: %@", [NSDate date]);
    > [[NSCursor openHandCursor] set];
    > }
    >
    > If I whip the mouse into the window's content area, my cursorUpdate method is called and I see the correct cursor. If I slowly sneak the mouse into my window's content area, I see the window resize cursor for a moment as I cross into the window content area (I'm running Lion), then... nothing. The cursor reverts to the arrow cursor, and my cursorUpdate: method is not called, even though I am well into my view's rectangle.
    >
    > If I inset my view from the boundaries of the window a bit (16-ish pixels), things behave as expected.
    >
    > What am I doing wrong?
    >
    > Sample project at <http://bugs.muratnkonar.com/trackingareas.zip>
    >
    > _murat
  • On May 19, 2012, at 22:10 , <mlist0987...> wrote:

    > If I whip the mouse into the window's content area, my cursorUpdate method is called and I see the correct cursor. If I slowly sneak the mouse into my window's content area, I see the window resize cursor for a moment as I cross into the window content area (I'm running Lion), then... nothing. The cursor reverts to the arrow cursor, and my cursorUpdate: method is not called, even though I am well into my view's rectangle.

    Does the window contain a NSScrollView? If so, there are certain places/timings where the scroll view takes control of the cursor. IIRC, the easiest workaround is to set scrollView.documentCursor to the same cursor you set for your view in 'cursorUpdate:' -- though I haven't tested the effects of this in Lion.

    Another [or a complementary] approach is to invoke 'cursorUpdate:' like this:

    - (void) mouseMoved: (NSEvent*) event {
    [self cursorUpdate: event];
    … other code for this method, if you have it …
    }

    It doesn't hurt to do the same in 'mouseDown:', 'mouseUp:', 'mouseDragged:', 'mouseEntered:' and 'mouseExited:', if you use any of those. This saves a lot of puzzling over other "missing" cursor updates, and it often simplifies your code by centralizing cursor setting.
  • No, the window is very vanilla. No scrollviews. Hierarchy is

    NSWindow
        NSView (window's content view)
            MyView

    Your alternate approach is essentially to give up on tracking areas, no? The tracking area approach has an attractive simplicity, especially once my view hierarchy and cursor tracking needs get more complicated, but if it's broken, I guess I'll have to roll my own solution. And file a bug report.

    I should have mentioned that this is on 10.7.4. Won't be able to test on 10.6.8 until Monday. Hi Alex!

    _murat

    On May 19, 2012, at 10:29 PM, Quincey Morris wrote:

    > On May 19, 2012, at 22:10 , <mlist0987...> wrote:
    >
    >> If I whip the mouse into the window's content area, my cursorUpdate method is called and I see the correct cursor. If I slowly sneak the mouse into my window's content area, I see the window resize cursor for a moment as I cross into the window content area (I'm running Lion), then... nothing. The cursor reverts to the arrow cursor, and my cursorUpdate: method is not called, even though I am well into my view's rectangle.
    >
    > Does the window contain a NSScrollView? If so, there are certain places/timings where the scroll view takes control of the cursor. IIRC, the easiest workaround is to set scrollView.documentCursor to the same cursor you set for your view in 'cursorUpdate:' -- though I haven't tested the effects of this in Lion.
    >
    > Another [or a complementary] approach is to invoke 'cursorUpdate:' like this:
    >
    > - (void) mouseMoved: (NSEvent*) event {
    > [self cursorUpdate: event];
    > … other code for this method, if you have it …
    > }
    >
    > It doesn't hurt to do the same in 'mouseDown:', 'mouseUp:', 'mouseDragged:', 'mouseEntered:' and 'mouseExited:', if you use any of those. This saves a lot of puzzling over other "missing" cursor updates, and it often simplifies your code by centralizing cursor setting.
    >
    >
  • On May 20, 2012, at 02:21 , <mlist0987...> wrote:

    > Your alternate approach is essentially to give up on tracking areas, no? The tracking area approach has an attractive simplicity, especially once my view hierarchy and cursor tracking needs get more complicated, but if it's broken, I guess I'll have to roll my own solution. And file a bug report.

    Not "give up:, really. Tracking areas are important because they provide much-improved 'mouseMoved:' behavior.

    The problem is that your code isn't the only code using tracking areas, and trying to predict which tracking area will "win" the cursor is difficult.

    Invoking 'cursorMoved:' from other events having a mouse location isn't an admission of defeat. It turns a fragile boundary-crossing solution into a robust state-detection solution.
  • On May 19, 2012, at 10:10 PM, "<mlist0987...>" <mlist0987...> wrote:

    > I have a view for which I am adding a tracking area so that I can update the cursor. The view entirely fills my window and is the only view in the window's content view.
    >
    > The tracking area is being registered thusly:
    >
    > - (void) awakeFromNib
    > {
    > NSTrackingArea* trackingArea = [[NSTrackingArea alloc ] initWithRect:[self bounds]
    > options:NSTrackingCursorUpdate|NSTrackingActiveInActiveApp
    > owner:self
    > userInfo:nil];
    > [self addTrackingArea:trackingArea];
    > }
    >
    > and I have defined in my view:
    >
    > - (void) cursorUpdate:(NSEvent *)event
    > {
    > NSLog(@"cursorUpdate: %@", [NSDate date]);
    > [[NSCursor openHandCursor] set];
    > }

    Have you implemented -updateTrackingAreas?

    --Kyle Sluder
  • On May 20, 2012, at 10:04 AM, Kyle Sluder wrote:

    > On May 19, 2012, at 10:10 PM, "<mlist0987...>" <mlist0987...> wrote:
    >
    >> I have a view for which I am adding a tracking area so that I can update the cursor. The view entirely fills my window and is the only view in the window's content view.
    >>
    >> The tracking area is being registered thusly:
    >>
    >> - (void) awakeFromNib
    >> {
    >> NSTrackingArea* trackingArea = [[NSTrackingArea alloc ] initWithRect:[self bounds]
    >> options:NSTrackingCursorUpdate|NSTrackingActiveInActiveApp
    >> owner:self
    >> userInfo:nil];
    >> [self addTrackingArea:trackingArea];
    >> }
    >>
    >> and I have defined in my view:
    >>
    >> - (void) cursorUpdate:(NSEvent *)event
    >> {
    >> NSLog(@"cursorUpdate: %@", [NSDate date]);
    >> [[NSCursor openHandCursor] set];
    >> }
    >
    > Have you implemented -updateTrackingAreas?

    Or you can try specifying NSTrackingInVisibleRect to take care of much tedium for you.

    Regards,
    Ken
  • On May 20, 2012, at 8:04 AM, Kyle Sluder wrote:

    > Have you implemented -updateTrackingAreas?

    Implementing it did not help. Not a surprise since my view doesn't change geometry.

    _murat
  • On May 20, 2012, at 9:02 AM, Ken Thomases wrote:

    > On May 20, 2012, at 10:04 AM, Kyle Sluder wrote:
    >
    >> Have you implemented -updateTrackingAreas?
    >
    > Or you can try specifying NSTrackingInVisibleRect to take care of much tedium for you.

    Nope, didn't help either.

    _murat
  • Sounds like your tracking area overlaps the 3 pixel wide grow zone tracking area. It's an interesting area - if you do a hitTest as the mouse is entering the window it won't hit your content in that zone, but it will if you start from > 3 pixels in and move out.

    But if you're only updating the cursor, why not try addCursorRect:cursor: ? Presumably that's smart enough to know about the grow zone.

    ----- Original Message -----
    From: <mlist0987...>
    To: "Cocoa Dev" <cocoa-dev...>
    Sent: Saturday, May 19, 2012 10:10:34 PM
    Subject: trackingAreas can be snuck up on without triggering?

    I have a view for which I am adding a tracking area so that I can update the cursor. The view entirely fills my window and is the only view in the window's content view.

    The tracking area is being registered thusly:

    - (void) awakeFromNib
    {
        NSTrackingArea* trackingArea = [[NSTrackingArea alloc ] initWithRect:[self bounds]
                  options:NSTrackingCursorUpdate|NSTrackingActiveInActiveApp
                  owner:self
                  userInfo:nil];
        [self addTrackingArea:trackingArea];
    }

    and I have defined in my view:

    - (void) cursorUpdate:(NSEvent *)event
    {
        NSLog(@"cursorUpdate: %@", [NSDate date]);
        [[NSCursor openHandCursor] set];
    }

    If I whip the mouse into the window's content area, my cursorUpdate method is called and I see the correct cursor. If I slowly sneak the mouse into my window's content area, I see the window resize cursor for a moment as I cross into the window content area (I'm running Lion), then... nothing. The cursor reverts to the arrow cursor, and my cursorUpdate: method is not called, even though I am well into my view's rectangle.

    If I inset my view from the boundaries of the window a bit (16-ish pixels), things behave as expected.

    What am I doing wrong?

    Sample project at <http://bugs.muratnkonar.com/trackingareas.zip>

    _murat
  • Belt *and* suspenders? ;)

    _murat

    On May 20, 2012, at 7:43 AM, Quincey Morris wrote:

    > On May 20, 2012, at 02:21 , <mlist0987...> wrote:
    >
    >> Your alternate approach is essentially to give up on tracking areas, no? The tracking area approach has an attractive simplicity, especially once my view hierarchy and cursor tracking needs get more complicated, but if it's broken, I guess I'll have to roll my own solution. And file a bug report.
    >
    > Not "give up:, really. Tracking areas are important because they provide much-improved 'mouseMoved:' behavior.
    >
    > The problem is that your code isn't the only code using tracking areas, and trying to predict which tracking area will "win" the cursor is difficult.
    >
    > Invoking 'cursorMoved:' from other events having a mouse location isn't an admission of defeat. It turns a fragile boundary-crossing solution into a robust state-detection solution.
    >
    >
  • On May 20, 2012, at 10:45 AM, Lee Ann Rucker wrote:

    > But if you're only updating the cursor, why not try addCursorRect:cursor: ? Presumably that's smart enough to know about the grow zone.

    The docs note that -addCursorRect:cursor: is "legacy api", supplanted in Leopard by... tracking rects! Not only that "The underlying implementation for the legacy methods is based on NSTrackingArea..."

    But IT WORKS! Thanks.

    _murat
  • Heh. I'd file a bug with Apple - this could be an edge case they didn't consider when they redid grow zones. At the very least they could make sample code showing what they're doing behind the scenes with the tracking rects.

    ----- Original Message -----
    From: <mlist0987...>
    To: "Lee Ann Rucker" <lrucker...>
    Cc: "Cocoa Dev" <cocoa-dev...>
    Sent: Sunday, May 20, 2012 11:11:51 AM
    Subject: Re: trackingAreas can be snuck up on without triggering?

    On May 20, 2012, at 10:45 AM, Lee Ann Rucker wrote:

    > But if you're only updating the cursor, why not try addCursorRect:cursor: ? Presumably that's smart enough to know about the grow zone.

    The docs note that -addCursorRect:cursor: is "legacy api", supplanted in Leopard by... tracking rects! Not only that "The underlying implementation for the legacy methods is based on NSTrackingArea..."

    But IT WORKS! Thanks.

    _murat
  • Bug ID# 11502520.

    _murat

    On May 20, 2012, at 11:42 PM, Lee Ann Rucker wrote:

    > Heh. I'd file a bug with Apple - this could be an edge case they didn't consider when they redid grow zones. At the very least they could make sample code showing what they're doing behind the scenes with the tracking rects.
    >
    > ----- Original Message -----
    > From: <mlist0987...>
    > To: "Lee Ann Rucker" <lrucker...>
    > Cc: "Cocoa Dev" <cocoa-dev...>
    > Sent: Sunday, May 20, 2012 11:11:51 AM
    > Subject: Re: trackingAreas can be snuck up on without triggering?
    >
    > On May 20, 2012, at 10:45 AM, Lee Ann Rucker wrote:
    >
    >> But if you're only updating the cursor, why not try addCursorRect:cursor: ? Presumably that's smart enough to know about the grow zone.
    >
    > The docs note that -addCursorRect:cursor: is "legacy api", supplanted in Leopard by... tracking rects! Not only that "The underlying implementation for the legacy methods is based on NSTrackingArea..."
    >
    > But IT WORKS! Thanks.
    >
    > _murat
    >
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today