As a single developer on my open-source player Tano, I have always supported the primary platform that I worked on. A while ago, my old Dell finally gave out - fried USB controller after 8 years of usage - and I invested in a Macbook Pro. Why retina? I got discount as this was a previous model and people in our part are famous to save money ;)

The first thing that bothered me was that my application looked ugly! All icons and graphics were pixelated or worse. So I started adapting my Qt application to HiDPI and OS X overall. This report may be a little late but someone may still need to adapt a application to retina.

There were three main aspects to be adapted for retina: integrated icons (in a resource file), icon theme and painted elements.

Integrated icons

Since Qt 5.1 (this is the Qt version I stared working on on OS X) there supposed to be full HiDPI support. I use integrated icons as a pure QIcon or converted to QPixmap. Qt uses Apple’s @2x notation for detecting bigger icons, thus detecting the high-resolution image and replacing it automatically. So I added all double-sized icons to my resources and this fixed the rendering issues - almost. Converting to QPixmap from ui files did not work, so I added icons directly in the code passing the desired pixmap size at conversion.

1 ui->labelIcon->setPixmap(QIcon(":/logo/64x64/logo.png").pixmap(64));

Icon theme

I use icon themes for icons so Linux users can use their default system theme. What to do now with retina? Qt was smart enough to automatically use larger icons but I use Faenza icon theme, which uses different icons for smaller sizes. Being open-source, I generated all icons in 2x size and created tano-default@2x theme. On runtime I check if pixel ratio is large enough and change icon theme.

 1 void Tano::Style::setIconName()
 2 {
 3     QScopedPointer<Settings> settings(new Settings());
 4     if (!settings->icons().isEmpty()) {
 5         QString name = settings->icons();
 6 #if defined(Q_OS_MAC)
 7         if (qApp->devicePixelRatio() >= 2)
 8             name.append("@2x");
 9 #endif
10         QIcon::setThemeName(name);
11     }
12 }

I also experienced Qt bug with data detection so I needed to add the following code to detect deployed icons in Tano.app/Contents/Resources/icons

1 #if defined(Q_OS_MAC)
2     paths.prepend(QCoreApplication::applicationDirPath().replace("MacOS", "Resources") + "/icons");
3 #endif

Painting

This part was simple. You just need to be sure to multiply all sizes with devicePixelRatio() and it will render properly.

 

There are still many parts of Tano not retina-ready at the moment that are my fault (non existing high-resolution images) or Qt’s (default painted items, dialog icons).

Next step? Adding proper retina support to my new webpage.