Fullscreen Howto
From OESF
(Added extra sections) |
|||
Line 1: |
Line 1: | ||
| - | + | =Fullscreen in Qtopia= | |
| - | Thanks to Eon Games for giving permission to mirror their article | + | Thanks to Eon Games for giving permission to mirror their article. |
---- | ---- | ||
2002-02-28: The woes of fullscreen in Qtopia | 2002-02-28: The woes of fullscreen in Qtopia | ||
Line 65: |
Line 65: | ||
'''Please take a good look at the fullscreen handling in Qtopia. It shouldn't require many hours of experimentation and source code reading to figure out how it works. I think that a single call to showFullScreen() should be enough. If the application is hidden or covered another widget, it should automatically restore itself to fullscreen mode once it again is active.''' | '''Please take a good look at the fullscreen handling in Qtopia. It shouldn't require many hours of experimentation and source code reading to figure out how it works. I think that a single call to showFullScreen() should be enough. If the application is hidden or covered another widget, it should automatically restore itself to fullscreen mode once it again is active.''' | ||
| + | |||
| + | ==Further Reading== | ||
| + | See the source for the videowidget widget in Qtopia's Mediaplayer, in particular <tt>makeVisible()</tt>. | ||
| + | |||
| + | ==Parentless Widgets== | ||
| + | The above code works well for a widget that is normally embedded into an application. For floating widgets, i.e. a widget that has no parent it is important to remember that you remember to call <tt>showNormal()</tt> before closing or hiding it so that QPE can know that it should refresh the other widgets. | ||
Revision as of 20:53, 13 February 2011
Fullscreen in Qtopia
Thanks to Eon Games for giving permission to mirror their article.
2002-02-28: The woes of fullscreen in Qtopia
Welcome to my first Developer Diary installment. In this episode I recount the adventure of writing fullscreen mode Qtopia applications. Who would have thought it would be such a challenge...
When I got the source for Strategic Assault it quickly became apparent that I needed true fullscreen mode. Anyone that has used Qtopia knows about the ever-present taskbar at the bottom of the screen. I figured there had to be some way of disabling it. While hanging out in #zaurus on irc.openprojects.net, someone mentioned that the media player can play back video using true fullscreen mode.
That said, I quickly found the magic function, showFullScreen() . Excited to have found the solution I quickly added this method to the constructor of the display widget. I recompiled and started the game and... nothing. I looked at the player code again and found the second magic piece of code.
resize(qApp->desktop()->size());
However, after adding this code, I still had no success. After some experimentation, I finally got my first fullscreen experience. The solution was to use QTimer to call the showFullScreen() method with a short delay (thus effectively calling it after the widget had been shown). The success was short-lived. The taskbar sometimes came back (for example when viewing the builtin help).
This is when the fun really started. I tried putting the events in an overloaded show(). This didn't work and was a very bad idea since showFullScreen() happens to invoke show(). I also added a check in the main game loop (timerEvent()). It worked but when I called it all the time, it was too slow. After adding a check that only tried to set fullscreen if the current widget size differed from the screen size, the performance issue was solved. I also added functionality to restore fullscreen after the help widget was closed. This worked fine in the development environment until I placed the binary in the Qtopia binary directory and launched the application by clicking on the icon. Back to the drawing board.
When I tried to figure out what the difference might have been, I finally thought of the idea of using the resizeEvent() callback. This simple action did fix the problem with I had with launching the application from within Qtopia. I released another beta version claiming that the fullscreen / taskbar issue most likely was solved. However Qtopia once again bit me in the face.
This time the problem surfaced when another application was launched. After the application quit, the taskbar stayed. As a last resort, I looked into the various states (i.e isEnabled(), isActiveWindow() etc). I figured out that when another application was launched, Strategic Assault was no longer active. This led me to try using the focusInEvent() callback. This worked. It finally worked. All known cases handled. This is were I am now. A new beta will soon be released and who knows - maybe this time I nailed it.
The conclusion is that writing a fullscreen application in Qtopia is a very painful experience. What should be simple and straighforward is anything but that. If the focusInEvent() solution works, I have learned a valuable lesson for future applications. I hope that this article will be useful for all you other Qtopia developers out there. The code which might be it can be seen below.
void focusInEvent(QFocusEvent *) {
setFixedSize(qApp->desktop()->size()); // set size
showNormal(); // set normal mode
showFullScreen(); // set fullscreen
}
I should note that the showNormal() method call is there already fullscreen..to make sure that showFullScreen() is actually fully executed. It seems like Qtopia knows that the application is already fullscreen...
30 minutes later...
It's now some 30 minutes after I finished writing this article. I spent most of those 30 minutes trying to fix an issue which the above "fix" broke - when I hide and then show the game our friend TASKBAR came back.
Solution? Re-implement the resizeEvent() callback. However I now got a new issue I hadn't seen before. Namely, the titlebar sometimes appeared when the game was restored to its fullscreen glory. After some digging in the Qt source, I realize why. showNormal() resets the window flags with a reparent() call. Unfortunately, as I said above, the call to showNormal() is required for showFullScreen() to work. The solution? Call reparent() with the correct window flags directly after the call to showNormal().
I have now been unable to produce an case where the taskbar reappears (and doesn't go away when it should). I consider, cross your fingers, this code the final solution:
void resizeEvent(QResizeEvent *) {
if(size() != qApp->desktop()->size()) {
// Widget is not the correct size, so do the fullscreen magic
enableFullscreen();
}
}
void focusInEvent(QFocusEvent *) {
// Always do it here, no matter the size.
enableFullscreen();
}
void enableFullscreen() {
// Make sure size is correct
setFixedSize(qApp->desktop()->size());
// This call is needed because showFullScreen won't work
// correctly if the widget already considers itself to be fullscreen.
showNormal();
// This is needed because showNormal() forcefully changes the window
// style to WSTyle_TopLevel.
reparent(0, WStyle_Customize | WStyle_NoBorder, QPoint(0,0));
// Enable fullscreen.
showFullScreen();
}
I will end this revised article with a plea to Trolltech:
Please take a good look at the fullscreen handling in Qtopia. It shouldn't require many hours of experimentation and source code reading to figure out how it works. I think that a single call to showFullScreen() should be enough. If the application is hidden or covered another widget, it should automatically restore itself to fullscreen mode once it again is active.
Further Reading
See the source for the videowidget widget in Qtopia's Mediaplayer, in particular makeVisible().
Parentless Widgets
The above code works well for a widget that is normally embedded into an application. For floating widgets, i.e. a widget that has no parent it is important to remember that you remember to call showNormal() before closing or hiding it so that QPE can know that it should refresh the other widgets.

