Destroying The Spinning Wait Cursor

Mac OS X Spinning Wait Cursor

The Mac OS X spinning wait cursor. Every OS with a pointer-based UI has one.

Those who know me know that if there is one thing I can’t stand it’s an unresponsive user interface when working on a computer.  The most common unresponsive user interface I get is the spinning wait cursor.

In brief, a spinning wait cursor appears when an application has not responded to system events such as user clicks or messages from the OS.  System events are “pumped” into an application’s main thread, where it is the programmer’s job to handle them.  For instance, a button may have an OnClick(…) message handler, which is a piece of code that executes when the user clicks on the user interface element.  An important thing to note here, though, is that even though there are separate message handlers for each button or user interface element, they are all called from one thread — the main application thread which is tied to the OS’s message pump.  Since events are processed in the order they are received, if one event handler takes too long to process the entire application can become hosed and the user gets the spinning wait cursor.

Because there is only one event processing thread in today’s OSes, application programmers need to pay close attention to how much and what kind of code they put in their message handlers.  Anything above and beyond the extremely mundane should be done in a separate thread within the application (or done asynchronously).  Even if the application programmer is only using one line of code that calls an OS function, the programmer needs to consider what is happening during that call; is it something that relies on physical I/O like a disk that may take time to spin up?  If so, put it in a separate thread or make an asynchronous call!

But instead of just calling on application developers to code better, I’m also going to call on OS manufacturers to fix this problem.  I don’t claim to know all the answers in this realm, but I’d really like to see research done regarding having multiple event threads per application–perhaps as many as one thread per UI element.  That would make for a massively threaded program and there would certainly be overhead involved, but if a developer knows that their application is not very UI-complex, then why not let them choose to have the application run in this manner?  This would eliminate many sources of the spinning wait cursor.

  1. I think we’ve discussed this before. I think it’s safer for an app to, by default, use the main thread to handle events, and leave it up to the developer to put a separate thread if that’s what he wants it to do. If every interface element fires its own thread it could lead to a lot of unexpected consequences, when any combination of two actions can be executed at the same time.

    There’s a good reason why when you hit “Save” an app pauses and stops you from making changes until after the save is done.

    • There’s a difference between blocking the user and hosing up the UI. I agree that typically you want to prevent the user from changing the document when you pop-up a save dialog. That can be done easily enough however using a lock on the document.

      Lets say you are writing a multimedia application, and you add a “load asset” button to load a movie or multimedia file from disk or whatever. Depending on the size of the file, it may take several moments to load that asset into memory. If this was all done via the main UI thread you’d get a spinning wait cursor, but if you spawned another thread you could control the user interface. For instance, you could have the asset appear with a progress-bar on it as the background thread loads it into memory.

      The biggest culprit that I’ve noticed lately honestly is web browsers. With the current state of things, a plug-in (hello Flash) can generate the spinning wait cursor. I get this all the time with Safari, and it’s not always when Flash is running but simply the loading of Flash. The loading of a plug-in should NOT stop the event loop from processing UI commands.

You must log in to post a comment.

Trackbacks and Pingbacks: