summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp122
-rw-r--r--src/corelib/animation/qabstractanimation.h18
-rw-r--r--src/corelib/animation/qabstractanimation_p.h8
-rw-r--r--src/corelib/corelib.pro6
-rw-r--r--src/corelib/global/qglobal.h3
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp1
-rw-r--r--src/corelib/io/qprocess_unix.cpp30
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp18
-rw-r--r--src/corelib/kernel/qcoreapplication.h1
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h2
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 *);