From 64a01ff5b5d1eaadb1e60013673ac25459b79e14 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 12 Dec 2017 08:27:36 +0100 Subject: Fix custom scenegraph item animations when used with QQuickWidget When used within a QQuickWidget, our custom scenegraph item animations wouldn't update. Gunnar suggested that the cause of this is the fact that we're not calling QQuickWindow::update() anywhere (as would be done for us if we implemented these controls with Animators in QML). To go into more detail, QQuickWidget uses a QQuickRenderControl internally, and the render control's renderRequested() and sceneChanged() signals are both connected to QQuickWidget::triggerUpdate(), so if calling QQuickWindow::update() is enough to kick it into action. QQuickWindow::frameSwapped is not emitted as part of QQuickWidget's render cycle, so that is probably the core of the problem. So instead, of using frameSwapped to drive the animation, we drive it directly from our beforeRendering handler. We also want to ensure that the very first animation triggers a start as well, so we make QQuickAnimatedNode::start() call QQuickWindow::update(). It was also suggested that we use direct connections when connecting to QQuickWindow::beforeRendering and QQuickWindow::frameSwapped, as QQuickWindow has affinity to the GUI thread. So, to make sure that things get called on the right thread at the right time, we change that as well. Task-number: QTBUG-62874 Change-Id: Id233be1b80858ec19eef9312f143adffadababff Reviewed-by: J-P Nurmi --- src/quickcontrols2/qquickanimatednode.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/quickcontrols2') diff --git a/src/quickcontrols2/qquickanimatednode.cpp b/src/quickcontrols2/qquickanimatednode.cpp index 83539fc6..3a18c757 100644 --- a/src/quickcontrols2/qquickanimatednode.cpp +++ b/src/quickcontrols2/qquickanimatednode.cpp @@ -112,8 +112,14 @@ void QQuickAnimatedNode::start(int duration) m_timer.restart(); if (duration > 0) m_duration = duration; - connect(m_window, &QQuickWindow::beforeRendering, this, &QQuickAnimatedNode::advance); - connect(m_window, &QQuickWindow::frameSwapped, this, &QQuickAnimatedNode::update); + + connect(m_window, &QQuickWindow::beforeRendering, this, &QQuickAnimatedNode::advance, Qt::DirectConnection); + connect(m_window, &QQuickWindow::frameSwapped, this, &QQuickAnimatedNode::update, Qt::DirectConnection); + + // If we're inside a QQuickWidget, this call is necessary to ensure the widget + // gets updated for the first time. + m_window->update(); + emit started(); } @@ -152,6 +158,9 @@ void QQuickAnimatedNode::advance() } } updateCurrentTime(time); + + // If we're inside a QQuickWidget, this call is necessary to ensure the widget gets updated. + m_window->update(); } void QQuickAnimatedNode::update() -- cgit v1.2.3