Fullscreen mode in QtQuick

Submitted by mimec on 2014-10-08

In theory creating a fullscreen application in QtQuick is straightforward - you just have to call the showFullScreen() method of QQuickView instead of show():

QQuickView view;
…
view.showFullScreen();

The application will work fine until you press Alt+Tab to switch to another window or Windows+M to minimize all windows. It may turn out that when you try to switch back to your QtQuick application, the window won't appear, and the screen will seem frozen.

Apparently I wasn't the only one who observed such problem - I found a few unanswered questions in various Qt forums, so I decided to dig deeper into it. After some experimentation I observed that adding an animated item (such as a spinning BusyIndicator) solves the problem. But why does it make a difference? An animated item causes the window to be repainted every frame (typically 60 times per second). However, if your window only contains static elements, Qt will cleverly avoid repainting it until something changes. This optimization works fine in windowed mode, but it causes problem in fullscreen mode.

Perhaps there is another way to do that, but the most obvious solution that came to my mind was to force an update whenever the window is activated or deactivated:

QObject::connect( &view, &QWindow::activeChanged, &view, &QQuickWindow::update );

I tested this on both Windows XP and Windows 8 and it seems to fix the problem in all situations.

I'm not sure if this is a bug in Qt or simply a glitch caused by Windows itself; it may have something to do with the fact that OpenGL (which is used by QtQuick under the hood) works a bit differently in fullscreen mode, bypassing the windows composition mechanism and rendering directly to the screen, but maybe I'm wrong. It doesn't really matter as long as there is a workaround.

Another small thing that you must remember about when using QtQuick in fullscreen mode is that the contents of your window should resize to the actual screen resolution. You will almost certainly want to add the following line:

view.setResizeMode( QQuickView::SizeRootObjectToView );

This can be combined with the scalable UI mechanism that I described recently. Just design your UI for some predefined resolution (I use 1600x900 because it fits nicely in windowed mode when debugging) and then set the multiplier in the u.dp() method so that it scales everything up or down according to the actual screen resolution (the Screen QML Type will come in handy).

Comments

Hey, thanks for the hint on the update function. I had the same issue and your solution didn't worked for me because in Qt 5 QML files are loaded differently over the QQmlApplicationEngine. However i found a different solution that works just fine and in plain qml:

Window
{
    id: window
    visible: true
    visibility: Window.FullScreen
    onActiveChanged:
    {
        window.update()
    }
}

In Qt 5.10 this trick helped me:

Window
{
    id: window
    onActiveChanged: {
        window.visibility = activeFocusItem ? Window.FullScreen : Window.Minimized;
    }
}