Alien widgets on Mac

Up till now, every widget in Qt/Mac has been backed by its own NSView. This means that Qt keeps a parent-child hierarchy of views in Cocoa that more or less mirrors the hierarchy of widgets found in your application. Each view receives native events that gets forwarded to the corresponding widget. We then need to do some extra processing and redirection to implement Qt's own logic for doing implicit and explicit mouse grabs, popups, etc, before the events eventually gets converted into QEvents and sent down to the application in a platform independent way.

Apple states that you should be careful not to overuse NSViews (ref). Instead, you should try to keep the count below one hundred for optimization reasons. This means that if you create Qt applications that make heavy use of widgets, your application would easily hit this limit. The result can be bad, as the first movie below shows. The application recorded creates a silly count of 2000 widgets that each highlights a button as the mouse hovers over it. And as you can see, the example just doesn't scale up, resulting in a huge lag.

Since we know that some of our customers tend to use a lot of widgets to build fancy UI-s, this limit can sometimes be critical. Luckily, Qt has a solution to this problem called Alien widgets (ref). Alien has been in use by default for Qt on Windows and X11 since Qt-4.4, and basically removes the need for a widget to be backed by a native window handle. On Mac, this translates into Qt not having to use an NSView for each widget. Instead, we try to stick with just one view (the content view of the window), and divide that view into widgets ourselves, bypassing Cocoa as much as possible.

What we gain by doing this is three-fold; First, we remove the amount of code that needs to execute before an event reaches the application. For example, rather than Cocoa first finding the correct view for a mouse press, followed by Qt redirecting the event somewhere else (because of a grabs, popups etc), we now handle the press directly in Qt. Secondly, since more of the event handling is shifted from platform specific code, into platform independent code, we expect Qt/Mac to close the difference that may exist to other platforms over time. And finally, we now follow Apples recommendation of not using so many views. And they were right, that did actually slow down applications. The second movie below shows the same example using Alien, and the lag is totally gone.

Alien will be used by default on Mac (Cocoa) in Qt-4.8.

(Also, feel free to download and try Alien on Mac yourself)

Blog Topics: