Leopard broke my progress indicators

  • Hello everyone.

    I maintain an application which updates a determinate spinning
    NSProgressIndicator from a worker thread using the following category.

    #import <AppKit/NSProgressIndicator.h>

    @interface NSProgressIndicator (NSProgressIndicatorUpdateOnMainThread)

    - (void)setDoubleValueInMainThread:(NSNumber *)doubleValue;
    - (void)__setDoubleValueInMainThread:(NSNumber *)doubleValue;

    @end

    -------

    #import "NSProgressIndicatorUpdateOnMainThread.h"

    @implementation NSProgressIndicator (NSProgressIndicatorUpdateOnMainThread)

    - (void)setDoubleValueInMainThread:(NSNumber *)value {

    [self
    performSelectorOnMainThread:@selector(__setDoubleValueInMainThread:)
    withObject:value waitUntilDone:NO];

    }

    - (void)__setDoubleValueInMainThread:(NSNumber *)value {

    [self setDoubleValue:[value doubleValue]];
    [self displayIfNeeded];

    }

    All fairly standard stuff, and it works fine in Tiger, in Leopard
    however the indicator does not animate. I've trying recompiling in
    Leopard to no avail.

    The Debugger clearly shows that the __setDoubleValueInMainThread gets
    called, and it gets called in the main thread. According to the debugger
    the _minimum, _maximum and _value variables are the expected values
    while running. _animationIndex and _progressIndicator.isSpinning are
    always 0

    If I change the indicator to bar style it shows progress,
    and _animationIndex changes, _progressIndicator.isSpinning is 1.
    Using a indeterminate Spinning indicator works and animates properly.

    Bar indicators, however, use way to much CPU under Tiger (and congrats
    to Apple for fixing that in Leopard) so I want to get the Spinning
    indicator working again. So any body got an idea what I'm going wrong.

    Dave
  • What exactly do you mean by a determinate spinning progress bar?
    I don't think such a thing is standard UI...?

    On Dec 16, 2007, at 7:22 AM, David Burnett wrote:

    > Hello everyone.
    >
    > I maintain an application which updates a determinate spinning
    > NSProgressIndicator from a worker thread using the following category.
    >
    > #import <AppKit/NSProgressIndicator.h>
    >
    >
    > @interface NSProgressIndicator (NSProgressIndicatorUpdateOnMainThread)
    >
    > - (void)setDoubleValueInMainThread:(NSNumber *)doubleValue;
    > - (void)__setDoubleValueInMainThread:(NSNumber *)doubleValue;
    >
    > @end
    >
    > -------
    >
    > #import "NSProgressIndicatorUpdateOnMainThread.h"
    >
    > @implementation NSProgressIndicator
    > (NSProgressIndicatorUpdateOnMainThread)
    >
    > - (void)setDoubleValueInMainThread:(NSNumber *)value {
    >
    > [self performSelectorOnMainThread:@selector
    > (__setDoubleValueInMainThread:) withObject:value waitUntilDone:NO];
    >
    > }
    >
    > - (void)__setDoubleValueInMainThread:(NSNumber *)value {
    >
    > [self setDoubleValue:[value doubleValue]];
    > [self displayIfNeeded];
    >
    > }
    >
    >
    > All fairly standard stuff, and it works fine in Tiger, in Leopard
    > however the indicator does not animate. I've trying recompiling in
    > Leopard to no avail.
    >
    > The Debugger clearly shows that the __setDoubleValueInMainThread
    > gets called, and it gets called in the main thread. According to
    > the debugger the _minimum, _maximum and _value variables are the
    > expected values while running. _animationIndex and
    > _progressIndicator.isSpinning are always 0
    >
    >
    > If I change the indicator to bar style it shows progress,
    > and _animationIndex changes, _progressIndicator.isSpinning is 1.
    > Using a indeterminate Spinning indicator works and animates properly.
    >
    > Bar indicators, however, use way to much CPU under Tiger (and
    > congrats to Apple for fixing that in Leopard) so I want to get the
    > Spinning indicator working again. So any body got an idea what I'm
    > going wrong.
    >
    >
    >
    > Dave
  • John Stiles wrote:
    > What exactly do you mean by a determinate spinning progress bar?
    > I don't think such a thing is standard UI...?
    >

    Funny what happens when you don't read the NSProgressIndicator Class
    reference properly isn't it.

    It may have not been official option but setting the max, min and value
    would actually animate the spinning progress bar like you would expect.
    I never though to check if it was *supposed* to work and it quite
    clearly did. I guess I'll have to detect which version of OS X I'm
    running on and set the style based on that.

    Thanks for you help anyway.

    Dave

    >>
    >> I maintain an application which updates a  from a worker thread using the following category.
    >>
    >> #import <AppKit/NSProgressIndicator.h>
    >>
    >>
    >> @interface NSProgressIndicator (NSProgressIndicatorUpdateOnMainThread)
    >>
    >> - (void)setDoubleValueInMainThread:(NSNumber *)doubleValue;
    >> - (void)__setDoubleValueInMainThread:(NSNumber *)doubleValue;
    >>
    >> @end
    >>
    >> -------
    >>
    >> #import "NSProgressIndicatorUpdateOnMainThread.h"
    >>
    >> @implementation NSProgressIndicator
    >> (NSProgressIndicatorUpdateOnMainThread)
    >>
    >> - (void)setDoubleValueInMainThread:(NSNumber *)value {
    >>
    >> [self
    >> performSelectorOnMainThread:@selector(__setDoubleValueInMainThread:)
    >> withObject:value waitUntilDone:NO];
    >>
    >> }
    >>
    >> - (void)__setDoubleValueInMainThread:(NSNumber *)value {
    >>
    >> [self setDoubleValue:[value doubleValue]];
    >> [self displayIfNeeded];
    >>
    >> }
    >>
    >>
    >> All fairly standard stuff, and it works fine in Tiger, in Leopard
    >> however the indicator does not animate. I've trying recompiling in
    >> Leopard to no avail.
    >>
    >> The Debugger clearly shows that the __setDoubleValueInMainThread gets
    >> called, and it gets called in the main thread. According to the
    >> debugger the _minimum, _maximum and _value variables are the expected
    >> values while running. _animationIndex and
    >> _progressIndicator.isSpinning are always 0
    >>
    >>
    >> If I change the indicator to bar style it shows progress,
    >> and _animationIndex changes, _progressIndicator.isSpinning is 1.
    >> Using a indeterminate Spinning indicator works and animates properly.
    >>
    >> Bar indicators, however, use way to much CPU under Tiger (and congrats
    >> to Apple for fixing that in Leopard) so I want to get the Spinning
    >> indicator working again. So any body got an idea what I'm going wrong.
    >>
    >>
    >>
    >> Dave
    >
    >
  • Why don't you do something like what Mail.app does for its progress
    indicators (simple circles that fill in pie-chart style)?

    Trying to hijack the spinning progress indicator to do something it's
    not designed to do is bad UI, because it's inconsistent with all
    other apps on the platform. Users who see that icon won't expect it
    to be used for determinate progress indication, so one of two things
    will happen:
    - they will think your app looks bad
    - they will not realize that the indicator is determinate at all

    Either outcome is bad...

    On Dec 16, 2007, at 8:00 AM, David Burnett wrote:

    > John Stiles wrote:
    >> What exactly do you mean by a determinate spinning progress bar?
    >> I don't think such a thing is standard UI...?
    >
    > Funny what happens when you don't read the NSProgressIndicator
    > Class reference properly isn't it.
    >
    > It may have not been official option but setting the max, min and
    > value would actually animate the spinning progress bar like you
    > would expect.
    > I never though to check if it was *supposed* to work and it quite
    > clearly did. I guess I'll have to detect which version of OS X I'm
    > running on and set the style based on that.
    >
    >
    > Thanks for you help anyway.
    >
    > Dave
    >
    >>>
    >>> I maintain an application which updates a  from a worker thread
    >>> using the following category.
    >>>
    >>> #import <AppKit/NSProgressIndicator.h>
    >>>
    >>>
    >>> @interface NSProgressIndicator
    >>> (NSProgressIndicatorUpdateOnMainThread)
    >>>
    >>> - (void)setDoubleValueInMainThread:(NSNumber *)doubleValue;
    >>> - (void)__setDoubleValueInMainThread:(NSNumber *)doubleValue;
    >>>
    >>> @end
    >>>
    >>> -------
    >>>
    >>> #import "NSProgressIndicatorUpdateOnMainThread.h"
    >>>
    >>> @implementation NSProgressIndicator
    >>> (NSProgressIndicatorUpdateOnMainThread)
    >>>
    >>> - (void)setDoubleValueInMainThread:(NSNumber *)value {
    >>> [self performSelectorOnMainThread:@selector
    >>> (__setDoubleValueInMainThread:) withObject:value waitUntilDone:NO];
    >>>
    >>> }
    >>>
    >>> - (void)__setDoubleValueInMainThread:(NSNumber *)value {
    >>>
    >>> [self setDoubleValue:[value doubleValue]];
    >>> [self displayIfNeeded];
    >>> }
    >>>
    >>>
    >>> All fairly standard stuff, and it works fine in Tiger, in Leopard
    >>> however the indicator does not animate. I've trying recompiling
    >>> in Leopard to no avail.
    >>>
    >>> The Debugger clearly shows that the __setDoubleValueInMainThread
    >>> gets called, and it gets called in the main thread. According to
    >>> the debugger the _minimum, _maximum and _value variables are the
    >>> expected values while running. _animationIndex and
    >>> _progressIndicator.isSpinning are always 0
    >>>
    >>>
    >>> If I change the indicator to bar style it shows progress,
    >>> and _animationIndex changes, _progressIndicator.isSpinning is 1.
    >>> Using a indeterminate Spinning indicator works and animates
    >>> properly.
    >>>
    >>> Bar indicators, however, use way to much CPU under Tiger (and
    >>> congrats to Apple for fixing that in Leopard) so I want to get
    >>> the Spinning indicator working again. So any body got an idea
    >>> what I'm going wrong.
    >>>
    >>>
    >>>
    >>> Dave
    >
  • On Dec 16, 2007, at 8:22 AM, David Burnett wrote:

    > - (void)setDoubleValueInMainThread:(NSNumber *)value {
    >
    > [self
    > performSelectorOnMainThread:@selector(__setDoubleValueInMainThread:)
    > withObject:value waitUntilDone:NO];
    >
    > }

    This is not necessary since NSProgressIndicator, unlike a lot of
    AppKit classes, is fully thread-safe.

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • Nick Zitzmann wrote:
    >
    > On Dec 16, 2007, at 8:22 AM, David Burnett wrote:
    >
    >> - (void)setDoubleValueInMainThread:(NSNumber *)value {
    >>
    >> [self
    >> performSelectorOnMainThread:@selector(__setDoubleValueInMainThread:)
    >> withObject:value waitUntilDone:NO];
    >>
    >> }
    >
    >
    > This is not necessary since NSProgressIndicator, unlike a lot of AppKit
    > classes, is fully thread-safe.
    >

    It's like this so the re-drawing of the progress indicator is done on
    the main thread as it should be.

    Dave
  • On Dec 16, 2007 9:13 AM, John Stiles <jstiles...> wrote:
    > Why don't you do something like what Mail.app does for its progress
    > indicators (simple circles that fill in pie-chart style)?

    That's exactly what the standard NSProgressIndicator class draws
    (under Leopard) when it is set to spinning and determinate.

    --
    Clark S. Cox III
    <clarkcox3...>
  • John Stiles wrote:
    > Why don't you do something like what Mail.app does for its progress
    > indicators (simple circles that fill in pie-chart style)?
    >

    Because then I'd have to draw my own progress indicators and it would be
    a non standard control and in my opinion just as bad HIG wise as using
    the spinning indicators. I actually wanted to use Bar style progress
    indicators but they were using so much CPU they where causing
    significant performance issues.

    The application runs a multi threaded, CPU intensive, long running task.
    This was a simple change in style and as Interface Builder left the
    indeterminate check box unchecked when I changed the style I saw nothing
    wrong with using them.

    Insert a rant about Apple's lack of respect for the HIG and their custom
    controls clearly showing that they are aware that certain controls are
    not up to the job in hand.

    Dave
  • On Dec 16, 2007, at 11:04 AM, David Burnett wrote:

    > It's like this so the re-drawing of the progress indicator is done
    > on the main thread as it should be.

    But you don't need to set the double value on the main thread; that
    part of NSProgressIndicator is thread-safe or else its threaded
    drawing feature wouldn't work. According to the documentation[1] you
    should, however, call the display methods on the main thread.

    Nick Zitzmann
    <http://www.chronosnet.com/>

    [1] <http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/ar
    ticles/CocoaSafety.html
    >
  • Cool.  If only it worked that way.  I have tried this a dozen different ways
    and the only way I could get progress bars to work down in a thread is
    exactly as shown by the OP.

    > From: Nick Zitzmann <nick...>
    > Subject: Re: Leopard broke my progress indicators
    >
    > But you don't need to set the double value on the main thread; that
    > part of NSProgressIndicator is thread-safe or else its threaded
    > drawing feature wouldn't work. According to the documentation[1] you
    > should, however, call the display methods on the main thread.
    >
    > Nick Zitzmann
    > <http://www.chronosnet.com/>
    >
    > [1]
    > <http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/ar
    ti
    > cles/CocoaSafety.html
    <vargol...>
  • On Dec 16, 2007, at 12:53 PM, Nick Zitzmann wrote:

    > This is not necessary since NSProgressIndicator, unlike a lot of
    > AppKit classes, is fully thread-safe.

    Where is that documented? I don't see NSProgressIndicator mentioned
    as thread-safe here:

    <http://developer.apple.com/documentation/Cocoa/Conceptual/
    Multithreading/articles/CocoaSafety.html
    >

    or here:

    <http://developer.apple.com/documentation/Cocoa/Reference/
    ApplicationKit/Classes/NSProgressIndicator_Class/Reference/
    Reference.html
    >

    or in the header.

    --Michael
  • On Dec 16, 2007, at 11:07 AM, Nick Zitzmann wrote:

    > But you don't need to set the double value on the main thread; that
    > part of NSProgressIndicator is thread-safe or else its threaded
    > drawing feature wouldn't work.

    I don't think that's necessarily true. I think that the threaded
    animation feature is designed to keep the animation running, even if
    the main thread is otherwise busy. I don't think it has anything to do
    with thread safety of the NSProgressIndicator class itself. And, as
    Michael Tsai points out, it's not documented to be thread safe in
    which case you should assume that it isn't.

    j o a r
previous month december 2007 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