#include "WinSevenTaskbar.h"
-#define EPS (1.0E-5)
-#define FADE_DELAY 4
+#define FADE_DELAY 16
+#define OPACITY_DELTA 0.02
+
+/* It can happen that the QThread has just terminated and already emitted the 'terminated' signal, but did NOT change the 'isRunning' flag to FALSE yet. */
+/* For this reason the macro will first check the 'isRunning' flag. If (and only if) the flag still returns TRUE, then we will wait() for at most 50 ms. */
+/* If, after 50 ms, the wait() function returns with FALSE, then the thread probably is still running and we return TRUE. Otherwise we can return FALSE. */
+#define THREAD_RUNNING(THRD) (((THRD)->isRunning()) ? (!((THRD)->wait(50))) : false)
+
////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////
SplashScreen::SplashScreen(QWidget *parent)
- : QFrame(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)
+:
+ QFrame(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)
{
//Init the dialog, from the .ui file
setupUi(this);
void SplashScreen::showSplash(QThread *thread)
{
- double opacity = 0.0;
+ double opacity = OPACITY_DELTA;
+ const int opacitySteps = qRound(1.0 / OPACITY_DELTA);
SplashScreen *splashScreen = new SplashScreen();
//Show splash
splashScreen->m_canClose = false;
splashScreen->setWindowOpacity(opacity);
+ splashScreen->setFixedSize(splashScreen->size());
splashScreen->show();
//Wait for window to show
- QApplication::processEvents();
- Sleep(100);
- QApplication::processEvents();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ splashScreen->repaint();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
//Setup the event loop
QEventLoop *loop = new QEventLoop(splashScreen);
connect(timer, SIGNAL(timeout()), loop, SLOT(quit()));
//Start thread
- QApplication::processEvents();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
thread->start();
- QApplication::processEvents();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
//Init taskbar
WinSevenTaskbar::setTaskbarState(splashScreen, WinSevenTaskbar::WinSevenTaskbarIndeterminateState);
//Fade in
- for(int i = 0; i <= 100; i++)
+ for(int i = 1; i <= opacitySteps; i++)
{
- opacity = 0.01 * static_cast<double>(i);
+ opacity = OPACITY_DELTA * static_cast<double>(i);
splashScreen->setWindowOpacity(opacity);
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY);
Sleep(FADE_DELAY);
timer->start(30720);
//Loop while thread is still running
- while(thread->isRunning())
+ if(bool bIsRunning = THREAD_RUNNING(thread))
{
- loop->exec();
- if(thread->isRunning())
+ while(bIsRunning)
{
- QThread::yieldCurrentThread();
- if(thread->isRunning())
+ loop->exec();
+ if(bIsRunning = THREAD_RUNNING(thread))
{
qWarning("Potential deadlock in initialization thread!");
}
timer->stop();
//Fade out
- for(int i = 100; i >= 0; i--)
+ for(int i = opacitySteps; i >= 0; i--)
{
- opacity = 0.01 * static_cast<double>(i);
+ opacity = OPACITY_DELTA * static_cast<double>(i);
splashScreen->setWindowOpacity(opacity);
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY);
Sleep(FADE_DELAY);