qApp->inputMethod()->setInputItemTransform(QQuickItemPrivate::get(focus)->itemToWindowTransform());
}
+
class QQuickWindowIncubationController : public QObject, public QQmlIncubationController
{
+ Q_OBJECT
+
public:
- QQuickWindowIncubationController(QQuickWindowPrivate *window)
- : m_window(window), m_eventSent(false) {}
+ QQuickWindowIncubationController(const QQuickWindow *window)
+ : m_window(QQuickWindowPrivate::get(const_cast<QQuickWindow *>(window)))
+ {
+ // Allow incubation for 1/3 of a frame.
+ m_incubation_time = qMax(1, int(1000 / QGuiApplication::primaryScreen()->refreshRate()) / 3);
+
+ m_animation_driver = m_window->windowManager->animationDriver();
+ if (m_animation_driver) {
+ connect(m_animation_driver, SIGNAL(stopped()), this, SLOT(animationStopped()));
+ connect(window, SIGNAL(frameSwapped()), this, SLOT(incubate()));
+ }
+ }
protected:
virtual bool event(QEvent *e)
{
if (e->type() == QEvent::User) {
- Q_ASSERT(m_eventSent);
- volatile bool *amtp = m_window->windowManager->allowMainThreadProcessing();
- while (incubatingObjectCount()) {
- if (amtp)
- incubateWhile(amtp, 2);
- else
- incubateFor(5);
- QCoreApplication::processEvents();
- }
-
- m_eventSent = false;
+ incubate();
+ return true;
}
return QObject::event(e);
}
+public slots:
+ void incubate() {
+ if (incubatingObjectCount()) {
+ if (m_animation_driver && m_animation_driver->isRunning()) {
+ incubateFor(m_incubation_time);
+ } else {
+ incubateFor(m_incubation_time * 2);
+ if (incubatingObjectCount())
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ }
+ }
+ }
+
+ void animationStopped() { incubate(); }
+
+protected:
virtual void incubatingObjectCountChanged(int count)
{
- if (count && !m_eventSent) {
- m_eventSent = true;
+ if (count && (!m_animation_driver || !m_animation_driver->isRunning()))
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
- }
- // If no animations are running, the renderer may be waiting
- m_window->windowManager->wakeup();
}
private:
QQuickWindowPrivate *m_window;
- bool m_eventSent;
+ int m_incubation_time;
+ QAnimationDriver *m_animation_driver;
};
+#include "qquickwindow.moc"
+
+
#ifndef QT_NO_ACCESSIBILITY
+/*!
+ Returns an accessibility interface for this window, or 0 if such an
+ interface cannot be created.
+
+ \warning The caller is responsible for deleting the returned interface.
+*/
QAccessibleInterface *QQuickWindow::accessibleRoot() const
{
return QAccessible::queryAccessibleInterface(const_cast<QQuickWindow*>(this));
QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection);
}
+/*!
+ \property QQuickWindow::data
+ \internal
+*/
+
QQmlListProperty<QObject> QQuickWindowPrivate::data()
{
initRootItem();
may result in the entire scene graph and its OpenGL context being deleted. The
sceneGraphInvalidated() signal will be emitted when this happens.
+ \sa {OpenGL Under QML Example}
+
+*/
+
+/*!
+ Constructs a window for displaying a QML scene with parent window \a parent.
*/
QQuickWindow::QQuickWindow(QWindow *parent)
: QWindow(*(new QQuickWindowPrivate), parent)
d->init(this);
}
+/*!
+ \internal
+*/
QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent)
: QWindow(dd, parent)
{
d->init(this);
}
+/*!
+ Destroys the window.
+*/
QQuickWindow::~QQuickWindow()
{
Q_D(QQuickWindow);
/*!
- Controls whether the OpenGL context can be released as a part of a call to
- releaseResources().
+ Sets whether the OpenGL context can be released as a part of a call to
+ releaseResources() to \a persistent.
The OpenGL context might still be released when the user makes an explicit
call to hide().
/*!
- Controls whether the scene graph nodes and resources can be released as a
- part of a call to releaseResources().
+ Sets whether the scene graph nodes and resources can be released as a
+ part of a call to releaseResources() to \a persistent.
The scene graph nodes and resources might still be released when the user
makes an explicit call to hide().
/*!
- Returns the invisible root item of the scene.
+ \property QQuickWindow::contentItem
+ \brief The invisible root item of the scene.
A QQuickWindow always has a single invisible root item containing all of its content.
To add items to this window, reparent the items to the contentItem or to an existing
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
for (int ii = children.count() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
- if (!child->isVisible() || !child->isEnabled())
+ if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
continue;
if (deliverInitialMousePressEvent(child, event))
return true;
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
for (int ii = children.count() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
- if (!child->isVisible() || !child->isEnabled())
+ if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
continue;
if (deliverHoverEvent(child, scenePos, lastScenePos, modifiers, accepted))
return true;
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
for (int ii = children.count() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
- if (!child->isVisible() || !child->isEnabled())
+ if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
continue;
if (deliverWheelEvent(child, event))
return true;
qWarning() << "QQuickWindow::wheelEvent()" << event->pixelDelta() << event->angleDelta();
#endif
- //if the actual wheel event was accepted, accept the compatability wheel event and return early
+ //if the actual wheel event was accepted, accept the compatibility wheel event and return early
if (d->lastWheelEventAccepted && event->angleDelta().isNull())
return;
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
for (int ii = children.count() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
- if (!child->isEnabled() || !child->isVisible())
+ if (!child->isEnabled() || !child->isVisible() || QQuickItemPrivate::get(child)->culled)
continue;
if (deliverTouchPoints(child, event, newPoints, acceptedNewPoints, updatedPoints))
return true;
Q_Q(QQuickWindow);
bool accepted = false;
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- if (!item->isVisible() || !item->isEnabled())
+ if (!item->isVisible() || !item->isEnabled() || QQuickItemPrivate::get(item)->culled)
return false;
QPointF p = item->mapFromScene(event->pos());
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
for (int ii = children.count() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
- if (!child->isVisible() || !child->isEnabled())
+ if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
continue;
if (QQuickItem *cursorItem = findCursorItem(child, scenePos))
return cursorItem;
}
/*!
- Propagates an event to a QQuickItem on the window
+ Propagates an event \a e to a QQuickItem \a item on the window.
+
+ The return value is currently not used.
*/
bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
{
return 0;
}
+/*!
+ \fn void QQuickWindow::frameSwapped()
+
+ This signal is emitted when the frame buffers have been swapped.
+
+ This signal will be emitted from the scene graph rendering thread.
+*/
+
/*!
- \fn void QSGContext::sceneGraphInitialized()
+ \fn void QQuickWindow::sceneGraphInitialized()
This signal is emitted when the scene graph has been initialized.
/*!
- \fn void QSGContext::sceneGraphInvalidated()
+ \fn void QQuickWindow::sceneGraphInvalidated()
This signal is emitted when the scene graph has been invalidated.
/*!
\overload
- */
+
+ Sets the render target for this window to be an FBO with
+ \a fboId and \a size.
+
+ The specified FBO must be created in the context of the window
+ or one that shares with it.
+
+ \warning
+ This function can only be called from the thread doing
+ the rendering.
+*/
+
void QQuickWindow::setRenderTarget(uint fboId, const QSize &size)
{
Q_D(QQuickWindow);
Q_D(const QQuickWindow);
if (!d->incubationController)
- d->incubationController = new QQuickWindowIncubationController(const_cast<QQuickWindowPrivate *>(d));
+ d->incubationController = new QQuickWindowIncubationController(this);
return d->incubationController;
}
*/
/*!
+ \fn void QQuickWindow::beforeSynchronizing()
+
+ This signal is emitted before the scene graph is synchronized with the QML state.
+
+ This signal can be used to do any preparation required before calls to
+ QQuickItem::updatePaintNode().
+
+ The GL context used for rendering the scene graph will be bound at this point.
+
+ \warning This signal is emitted from the scene graph rendering thread. If your
+ slot function needs to finish before execution continues, you must make sure that
+ the connection is direct (see Qt::ConnectionType).
+
+ \warning Make very sure that a signal handler for beforeSynchronizing leaves the GL
+ context in the same state as it was when the signal handler was entered. Failing to
+ do so can result in the scene not rendering properly.
+*/
+
+/*!
\fn void QQuickWindow::beforeRendering()
This signal is emitted before the scene starts rendering.
The GL context used for rendering the scene graph will be bound
at this point.
- \warning Since this signal is emitted from the scene graph rendering thread, the
- receiver should be on the scene graph thread or the connection should be Qt::DirectConnection.
+ \warning This signal is emitted from the scene graph rendering thread. If your
+ slot function needs to finish before execution continues, you must make sure that
+ the connection is direct (see Qt::ConnectionType).
\warning Make very sure that a signal handler for beforeRendering leaves the GL
context in the same state as it was when the signal handler was entered. Failing to
The GL context used for rendering the scene graph will be bound at this point.
- \warning Since this signal is emitted from the scene graph rendering thread, the
- receiver should be on the scene graph thread or the connection should be Qt::DirectConnection.
+ \warning This signal is emitted from the scene graph rendering thread. If your
+ slot function needs to finish before execution continues, you must make sure that
+ the connection is direct (see Qt::ConnectionType).
\warning Make very sure that a signal handler for afterRendering() leaves the GL
context in the same state as it was when the signal handler was entered. Failing to
/*!
Sets weither the scene graph rendering of QML should clear the color buffer
- before it starts rendering to \a enbled.
+ before it starts rendering to \a enabled.
By disabling clearing of the color buffer, it is possible to do GL painting
under the scene graph.
initialized.
\warning The returned texture is not memory managed by the scene graph and
- must be explicitely deleted by the caller on the rendering thread.
+ must be explicitly deleted by the caller on the rendering thread.
This is acheived by deleting the texture from a QSGNode destructor
or by using deleteLater() in the case where the texture already has affinity
to the rendering thread.
/*!
- Creates a new QSGTexture object from an existing GL texture \a id.
+ Creates a new QSGTexture object from an existing GL texture \a id and \a size.
The caller of the function is responsible for deleting the returned texture.
return 0;
}
-
/*!
- Sets the color used to clear the opengl context to \a color.
+ \property QQuickWindow::color
+ \brief The color used to clear the OpenGL context.
Setting the clear color has no effect when clearing is disabled.
+ By default, the clear color is white.
\sa setClearBeforeRendering()
*/
emit colorChanged(color);
}
-
-
-/*!
- Returns the color used to clear the opengl context.
- */
-
QColor QQuickWindow::color() const
{
return d_func()->clearColor;