diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/animation/qabstractanimation.cpp | 122 | ||||
-rw-r--r-- | src/corelib/animation/qabstractanimation.h | 18 | ||||
-rw-r--r-- | src/corelib/animation/qabstractanimation_p.h | 8 | ||||
-rw-r--r-- | src/corelib/corelib.pro | 6 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 3 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 1 | ||||
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 30 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 18 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication_p.h | 2 |
10 files changed, 169 insertions, 40 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 602cf8a6fd..7d74de8e44 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -201,16 +201,17 @@ void QUnifiedTimer::ensureTimerUpdate() { QUnifiedTimer *inst = QUnifiedTimer::instance(false); if (inst && inst->isPauseTimerActive) - inst->updateAnimationsTime(); + inst->updateAnimationsTime(-1); } -void QUnifiedTimer::updateAnimationsTime() +void QUnifiedTimer::updateAnimationsTime(qint64 timeStep) { //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations if(insideTick) return; - qint64 totalElapsed = time.elapsed(); + qint64 totalElapsed = timeStep >= 0 ? timeStep : time.elapsed(); + // ignore consistentTiming in case the pause timer is active int delta = (consistentTiming && !isPauseTimerActive) ? timingInterval : totalElapsed - lastTick; @@ -260,7 +261,8 @@ void QUnifiedTimer::restartAnimationTimer() } else if (!driver->isRunning() || isPauseTimerActive) { driver->start(); isPauseTimerActive = false; - } + } else if (runningLeafAnimations == 0) + driver->stop(); } void QUnifiedTimer::setTimingInterval(int interval) @@ -302,7 +304,7 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) if (event->timerId() == animationTimer.timerId()) { // update current time on all top level animations - updateAnimationsTime(); + updateAnimationsTime(-1); restartAnimationTimer(); } } @@ -389,19 +391,49 @@ int QUnifiedTimer::closestPauseAnimationTimeToFinish() return closestTimeToFinish; } + void QUnifiedTimer::installAnimationDriver(QAnimationDriver *d) { - if (driver->isRunning()) { - qWarning("QUnifiedTimer: Cannot change animation driver while animations are running"); + if (driver != &defaultDriver) { + qWarning("QUnifiedTimer: animation driver already installed..."); return; } - if (driver && driver != &defaultDriver) - delete driver; + if (driver->isRunning()) { + driver->stop(); + d->start(); + } driver = d; + +} + + +void QUnifiedTimer::uninstallAnimationDriver(QAnimationDriver *d) +{ + if (driver != d) { + qWarning("QUnifiedTimer: trying to uninstall a driver that is not installed..."); + return; + } + + driver = &defaultDriver; + + if (d->isRunning()) { + d->stop(); + driver->start(); + } +} + +/*! + Returns true if \a d is the currently installed animation driver + and is not the default animation driver (which can never be uninstalled). +*/ +bool QUnifiedTimer::canUninstallAnimationDriver(QAnimationDriver *d) +{ + return d == driver && driver != &defaultDriver; } + /*! \class QAnimationDriver @@ -424,35 +456,69 @@ QAnimationDriver::QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent) { } +QAnimationDriver::~QAnimationDriver() +{ + QUnifiedTimer *timer = QUnifiedTimer::instance(true); + if (timer->canUninstallAnimationDriver(this)) + uninstall(); +} + + /*! - Advances the animation based on the current time. This function should - be continuously called by the driver while the animation is running. + Advances the animation based to the specified \a timeStep. This function should + be continuously called by the driver subclasses while the animation is running. - \internal + If \a timeStep is positive, it will be used as the current time in the + calculations; otherwise, the current clock time will be used. */ -void QAnimationDriver::advance() + +void QAnimationDriver::advanceAnimation(qint64 timeStep) { QUnifiedTimer *instance = QUnifiedTimer::instance(); // update current time on all top level animations - instance->updateAnimationsTime(); + instance->updateAnimationsTime(timeStep); instance->restartAnimationTimer(); } + +/*! + Advances the animation. This function should be continously called + by the driver while the animation is running. + */ + +void QAnimationDriver::advance() +{ + advanceAnimation(-1); +} + + + /*! Installs this animation driver. The animation driver is thread local and will only apply for the thread its installed in. - - \internal */ + void QAnimationDriver::install() { QUnifiedTimer *timer = QUnifiedTimer::instance(true); timer->installAnimationDriver(this); } + + +/*! + Uninstalls this animation driver. + */ + +void QAnimationDriver::uninstall() +{ + QUnifiedTimer *timer = QUnifiedTimer::instance(true); + timer->uninstallAnimationDriver(this); +} + bool QAnimationDriver::isRunning() const { return d_func()->running; @@ -463,7 +529,7 @@ void QAnimationDriver::start() { Q_D(QAnimationDriver); if (!d->running) { - started(); + emit started(); d->running = true; } } @@ -473,16 +539,28 @@ void QAnimationDriver::stop() { Q_D(QAnimationDriver); if (d->running) { - stopped(); + emit stopped(); d->running = false; } } + +/*! + \fn qint64 QAnimationDriver::elapsed() const + + Returns the number of milliseconds since the animations was started. + */ + +qint64 QAnimationDriver::elapsed() const +{ + return QUnifiedTimer::instance()->time.elapsed(); +} + /*! \fn QAnimationDriver::started() - This function is called by the animation framework to notify the driver - that it should start running. + This signal is emitted by the animation framework to notify the driver + that continous animation has started. \internal */ @@ -490,8 +568,8 @@ void QAnimationDriver::stop() /*! \fn QAnimationDriver::stopped() - This function is called by the animation framework to notify the driver - that it should stop running. + This signal is emitted by the animation framework to notify the driver + that continous animation has stopped. \internal */ diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index 0900870ce2..91282066a6 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -141,23 +141,31 @@ class Q_CORE_EXPORT QAnimationDriver : public QObject public: QAnimationDriver(QObject *parent = 0); + ~QAnimationDriver(); + + virtual void advance(); - void advance(); void install(); + void uninstall(); bool isRunning() const; + qint64 elapsed() const; + +Q_SIGNALS: + void started(); + void stopped(); + protected: - virtual void started() {}; - virtual void stopped() {}; + void advanceAnimation(qint64 timeStep = -1); + virtual void start(); + virtual void stop(); QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = 0); private: friend class QUnifiedTimer; - void start(); - void stop(); }; diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index ba92960f6b..de26987721 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -180,15 +180,21 @@ public: static void updateAnimationTimer(); void installAnimationDriver(QAnimationDriver *driver); + void uninstallAnimationDriver(QAnimationDriver *driver); + bool canUninstallAnimationDriver(QAnimationDriver *driver); void restartAnimationTimer(); - void updateAnimationsTime(); + void updateAnimationsTime(qint64 timeStep); + + //useful for profiling/debugging + int runningAnimationCount() { return animations.count(); } protected: void timerEvent(QTimerEvent *); private: friend class QDefaultAnimationDriver; + friend class QAnimationDriver; QAnimationDriver *driver; QDefaultAnimationDriver defaultDriver; diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 4efb1b9a22..a31d1e5b7f 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -1,7 +1,11 @@ -MODULE = core TARGET = QtCore QPRO_PWD = $$PWD QT = + +CONFIG += module +MODULE = core # not corelib, as per project file +MODULE_PRI = ../modules/qt_core.pri + DEFINES += QT_BUILD_CORE_LIB QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 9434eb29f7..49f5f989fb 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2755,7 +2755,8 @@ QT_LICENSED_MODULE(DBus) #if !(defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) \ && !(defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) \ - && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) + && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) \ + && !(defined(Q_WS_QPA)) # define QT_NO_RAWFONT #endif diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 82c6ebad05..1dbc40f3ed 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -583,6 +583,7 @@ QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEng } } #else + Q_UNUSED(entry); Q_UNUSED(own); #endif return name; diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 3af9b46df8..f53742b815 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -171,17 +171,27 @@ private: Q_GLOBAL_STATIC(QMutex, processManagerGlobalMutex) -static QProcessManager *processManager() { +static QProcessManager *processManagerInstance = 0; + +static QProcessManager *processManager() +{ // The constructor of QProcessManager should be called only once // so we cannot use Q_GLOBAL_STATIC directly for QProcessManager QMutex *mutex = processManagerGlobalMutex(); QMutexLocker locker(mutex); - static QProcessManager processManager; - return &processManager; + + if (!processManagerInstance) + QProcessPrivate::initializeProcessManager(); + + Q_ASSERT(processManagerInstance); + return processManagerInstance; } QProcessManager::QProcessManager() { + // can only be called from main thread + Q_ASSERT(!qApp || qApp->thread() == QThread::currentThread()); + #if defined (QPROCESS_DEBUG) qDebug() << "QProcessManager::QProcessManager()"; #endif @@ -197,6 +207,8 @@ QProcessManager::QProcessManager() action.sa_handler = qt_sa_sigchld_handler; action.sa_flags = SA_NOCLDSTOP; ::sigaction(SIGCHLD, &action, &qt_sa_old_sigchld_handler); + + processManagerInstance = this; } QProcessManager::~QProcessManager() @@ -221,6 +233,8 @@ QProcessManager::~QProcessManager() if (currentAction.sa_handler == qt_sa_sigchld_handler) { ::sigaction(SIGCHLD, &qt_sa_old_sigchld_handler, 0); } + + processManagerInstance = 0; } void QProcessManager::run() @@ -1287,7 +1301,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a void QProcessPrivate::initializeProcessManager() { - (void) processManager(); + if (qApp && qApp->thread() != QThread::currentThread()) { + // The process manager must be initialized in the main thread + // Note: The call below will re-enter this function, but in the right thread, + // so the else statement below will be executed. + QMetaObject::invokeMethod(qApp, "_q_initializeProcessManager", Qt::BlockingQueuedConnection); + } else { + static QProcessManager processManager; + Q_UNUSED(processManager); + } } QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index f430d1c0a4..36609a3a1c 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -392,6 +392,16 @@ void QCoreApplicationPrivate::createEventDispatcher() #endif } +void QCoreApplicationPrivate::_q_initializeProcessManager() +{ +#ifndef QT_NO_PROCESS +# ifdef Q_OS_UNIX + QProcessPrivate::initializeProcessManager(); +# endif +#endif +} + + QThread *QCoreApplicationPrivate::theMainThread = 0; QThread *QCoreApplicationPrivate::mainThread() { @@ -639,12 +649,6 @@ void QCoreApplication::init() } #endif -#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS)) - // Make sure the process manager thread object is created in the main - // thread. - QProcessPrivate::initializeProcessManager(); -#endif - #ifdef QT_EVAL extern void qt_core_eval_init(uint); qt_core_eval_init(d->application_type); @@ -2710,3 +2714,5 @@ int QCoreApplication::loopLevel() */ QT_END_NAMESPACE + +#include "moc_qcoreapplication.cpp" diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index b83e240566..929e4a9836 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -196,6 +196,7 @@ protected: QCoreApplication(QCoreApplicationPrivate &p); private: + Q_PRIVATE_SLOT(d_func(), void _q_initializeProcessManager()) static bool sendSpontaneousEvent(QObject *receiver, QEvent *event); bool notifyInternal(QObject *receiver, QEvent *event); diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index add2a3553e..fdceab4724 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -85,6 +85,8 @@ public: bool sendThroughObjectEventFilters(QObject *, QEvent *); bool notify_helper(QObject *, QEvent *); + void _q_initializeProcessManager(); + virtual QString appName() const; virtual void createEventDispatcher(); static void removePostedEvent(QEvent *); |