Fullscreen issue: windows XP taskbar suddenly appears
-
We were having an issue with some legacy code we are maintaining. The code uses Qt 4.8.6 and consists of a client application that runs fullscreen on a Windows XP Embedded device (Version 2002 Service Pack 2). After some refactoring, the application suddenly suffered from the following problem: it did start in fullscreen, but from the moment the constructor of certain widgets got called, the Windows taskbar came in front of the fullscreen application. After some debugging, i was able to solve the problem by re-introducing certain margin and spacing statements that were removed during the refactoring, they looked like this:
layout1->setContentsMargins(0,0,0,0); layout2->setMargin(0); layout3->setSpacing(0); .... layout2->setVerticalSpacing(2); layout2->setHorizontalSpacing(6); .... layout3->setSpacing(1);
where layout1 and layout2 are of type QGridLayout* and layout3 is of type QBoxLayout*.
I'm not sure exactly what subset of these statements was the minimal subset that fixed the problem (it would take me too much time to investigate that), but I was surprised to see that whether our application correctly runs in fullscreen (that is, without the Windows taskbar appearing in front of our application) depends on the contents margins and spacings... I would expect the fullscreen behavior to be independent of that???
Is this a bug in Qt 4.8.6 or a feature? Am I misunderstanding certain aspects of the fullscreen mode? Is the fullscreen behavior somehow dependent on the content margins and spacings of the layouts???
Thanks for sharing your comments!
-
We are still suffering from this problem, which is quite annoying because changes in GUI and layout-related things randomly trigger this problem once in a while.
For the record: i can confirm that it also occurs with Qt 4.8.7. Upgrading to 5.X is currently not possible for us.
Any suggestions or ideas that might lead to better understanding this issue are still welcome!
-
Just a thought I had during lunch, mabe it can help you with the issue:
Have you reimplemented
void changeEvent(QEvent *event)
yet ? From what you described , this should get triggered whenever the Taskbar appears.
Probably a change fromQt::WindowFullScreen
to either
Qt::WindowNoState
orQt::WindowMaximized
. You could detect that and reaply the correct windowstate. -
@J-Hilk
Thanks for the suggestion to reimplementvoid changeEvent(QEvent *event)
. I did that for myQMainWindow
, and logged all the QEvents that happened. This is what I get:MainWindow: a changEvent of type '33' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '105' occurred. MainWindow: WindowsStateChange event occurred: 4 MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred. MainWindow: a changEvent of type '99' occurred.
Which I interpret as:
33 => when setting the title
99 => QEvent::ActivationChange ("A widget's top-level window activation state has changed.")
105 => setting the window to full screen using a call to showFullscreen()
99 => QEvent::ActivationChange ("A widget's top-level window activation state has changed.")So after I set the window to full screen, there are quite some
ActivationChange
events. I still have to look it up what exactly these are, but could it be that thoseActivationChange
events cause the toolbar to come in front of the fullscreen application again? -
Hi, perhaps another approach is to fight back, by setting the windows z-order of your app so that it "wins" over the taskbar regardless of it rearing its head or not, I've done that in Qt5 (don't know about Qt4 but with some luck it works out the same):
add
LIBS += -luser32
in the .pro file#include "windows.h"
and add:
SetWindowPos((HWND) winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
perhaps somewhere after those widget constructors are called... -
@Bart_Vandewoestyne
hi,
if what @hskoglund suggested does not help, you can't do it that way, heres a bit more indepth analysisof the change event to see if the WindowState changes or if the taskbar is pulled forward forwhatever other reason.//Filter for the correct Change event if(event->type() == QEvent::WindowStateChange){ //cast to the right typ to ananlize the QWindowStateChangeEvent QWindowStateChangeEvent *ev = static_cast<QWindowStateChangeEvent *>(event); //Log or Print result qDebug() << ev->oldState(); }
Just to make sure, the
Qt::WindowStaysOnTopHint
is set and not overwritten later on? callingsetWindowFlags()
a second time for example will remove old flags. -
I think I was finally able to solve the problem.
As the solution suggested by @hskoglund is Windows-specific, I decided to first investigate a bit deeper the other options presented by @J-Hilk
It turned out that the
Qt::WindowStaysOnTopHint
flag was not set for our main window. I am now setting that flag in our main windows's constructor, and afterwards show it full screen. This seems to work.Thanks again for your suggestions!