NSMenu animations block main thread
Asked Answered
S

1

8

I have:

  • NSStatusItem with a custom view (scrolling text in a secondary thread), with the secondary thread updating the internal state and notifying the main thread with setNeedsDisplay.
  • On mouseDown, an NSMenu pops up.
  • However, if any NSMenuItem in the NSMenu is selected, or if a second mouseDown is detected and the NSMenu fades, the scrolling text animation stutters.

It seems as though the NSMenu default view blocks the main thread while doing its animations. I've tested this by having the secondary thread output time_since_last_loop versus the drawRect: of the view (which is the main thread), and only the drawRect shows the stutter. drawRect of the custom view drops from ~30 fps to 5 for a few frames.

Any way to have NSMenu animations non-blocking, or concurrent with the drawRect of the custom view?

Stereograph answered 2/10, 2012 at 18:55 Comment(0)
R
0

I've used an NSTimer with NSEventTrackingRunLoopMode to solve similar issues.

In your main thread, create a timer:

    updateTimer = [[NSTimer scheduledTimerWithTimeInterval:kSecondsPerFrame target:self selector:@selector(update:) userInfo:nil repeats:YES] retain];

   // kpk important: this allows UI to draw while dragging the mouse.
   // Adding NSModalPanelRunLoopMode is too risky.
    [[NSRunLoop mainRunLoop] addTimer:updateTimer forMode:NSEventTrackingRunLoopMode];

Then in your update: routine, check for NSEventTrackingRunLoopMode:

   // only allow status updates and drawing (NO show data changes) if App is in
   // a Modal loop, such as NSEventTrackingRunLoopMode
   NSString *runLoopMode = [[NSRunLoop currentRunLoop] currentMode];
   if ( runLoopMode == NSEventTrackingRunLoopMode )
   {
       ... do periodic update tasks that are safe to do while
       ... in this mode
       ... I *think* NSMenu is just a window
       for ( NSWindow *win in [NSApp windows] )
       {
          [win displayIfNeeded];
       }

       return;
   }

   // do all other updates
   ...
Resplendence answered 6/1, 2017 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.