Inside SWT

Monday, March 02, 2009

Fighting the Cocoa default button!

On Mac Cocoa OS X 10.5, the throbbing default button animation is implemented as a separate thread that calls drawing methods directly from that thread. You would think that this wouldn't be a big deal but threads in a GUI toolkit are always a big deal.

It's an amazing GUI toolkit 101 blooper!

Who cares if the default button is painted from another thread? First off, SWT checks thread accesses to avoid operating system crashes. First attempts at a fix removed this check, causing operating system crashes.

How about hacking so that drawing requests from the throbbing thread are serviced, but don't run any SWT listeners? No good. The Mac user-interface is composited so parents of the button are asked to a paint all the way up to the shell and the button paints last on top of them.

Can't paint ... but must.

It seems that there are only two fixes:
  1. Lock and allow the throbbing thread to run as the Cocoa Gods intended
  2. Throb somehow safely in the UI-thread

Since introducing locking everywhere in SWT at Eclipse 3.5 M6 and hoping that it works at this point is insane, all we can do for now is attempt to throb safely. This fix involves remembering that you were asked to throb, telling the operating system that it has throbbed already and then later throbbing with impunity from the user-interface thread.



  • We do this in the Swing Aqua LaF by setting up a Swing Timer, and driving the paint from Java. Letting the Cocoa animation thread loose in your component heirarchy is a recipe for disaster.

    By Blogger Mike, at 12:16 PM  

  • Sounds familiar.

    Since SWT is native, the button is a real button, not a picture of a button (no insult intended) and this adds to the fun.

    We looked at doing the animation ourselves but there was no API that described the button paint phases. In fact, there is no theme drawing API of any kind for cocoa (am missing something?).

    In any case, I don't like what we have, but there was not much we could do, especially without the source for anything.

    By Blogger Steve, at 2:18 PM  

  • Interesting. Does it mean that in each Cocoa app, there's a dedicated thread, in addition to the UI thread, whose responsibility it is to draw animations, of which the pulsing button is an example?

    By Blogger jpp, at 4:54 PM  

  • For the default button there is a dedicated thread. I have no idea what other animations are using.

    By Blogger Steve, at 1:09 PM  

Post a Comment

<< Home