X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fquick%2Fitems%2Fqquickwindow.cpp;h=4ea31a0d6faeba947562c92ba693b455ee4d42f5;hb=5e975a312412b63cb4993931923360bfe5a105b4;hp=ca94570a3ce5718ee60e4af52220228f7e1c29dd;hpb=3ddf7f1cf638091c8c7c7380bf0414dcc1145d2c;p=profile%2Fivi%2Fqtdeclarative.git diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index ca94570..4ea31a0 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtQml module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -80,47 +80,73 @@ void QQuickWindowPrivate::updateFocusItemTransform() 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(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(this)); @@ -196,14 +222,14 @@ void QQuickWindow::hideEvent(QHideEvent *) void QQuickWindow::focusOutEvent(QFocusEvent *) { Q_D(QQuickWindow); - d->rootItem->setFocus(false); + d->contentItem->setFocus(false); } /*! \reimp */ void QQuickWindow::focusInEvent(QFocusEvent *) { Q_D(QQuickWindow); - d->rootItem->setFocus(true); + d->contentItem->setFocus(true); d->updateFocusItemTransform(); } @@ -233,9 +259,8 @@ void QQuickWindowPrivate::polishItems() * This parameter enables that this window can be rendered without * being shown on screen. This feature is very limited in what it supports. * - * There needs to be another window actually showing that we can make current - * to get a surface to make current AND for this feature to be useful - * one needs to hook into beforeRender() and set the render tareget. + * For this feature to be useful one needs to hook into beforeRender() + * and set the render target. * */ void QQuickWindowPrivate::setRenderWithoutShowing(bool render) @@ -284,10 +309,10 @@ void QQuickWindowPrivate::syncSceneGraph() emit q->beforeSynchronizing(); if (!renderer) { - forceUpdate(rootItem); + forceUpdate(contentItem); QSGRootNode *rootNode = new QSGRootNode; - rootNode->appendChildNode(QQuickItemPrivate::get(rootItem)->itemNode()); + rootNode->appendChildNode(QQuickItemPrivate::get(contentItem)->itemNode()); renderer = context->createRenderer(); renderer->setRootNode(rootNode); } @@ -323,7 +348,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) } QQuickWindowPrivate::QQuickWindowPrivate() - : rootItem(0) + : contentItem(0) , activeFocusItem(0) , mouseGrabberItem(0) #ifndef QT_NO_CURSOR @@ -357,18 +382,18 @@ void QQuickWindowPrivate::init(QQuickWindow *c) Q_Q(QQuickWindow); - rootItem = new QQuickRootItem; - QQmlEngine::setObjectOwnership(rootItem, QQmlEngine::CppOwnership); - QQuickItemPrivate *rootItemPrivate = QQuickItemPrivate::get(rootItem); - rootItemPrivate->window = q; - rootItemPrivate->windowRefCount = 1; - rootItemPrivate->flags |= QQuickItem::ItemIsFocusScope; + contentItem = new QQuickRootItem; + QQmlEngine::setObjectOwnership(contentItem, QQmlEngine::CppOwnership); + QQuickItemPrivate *contentItemPrivate = QQuickItemPrivate::get(contentItem); + contentItemPrivate->window = q; + contentItemPrivate->windowRefCount = 1; + contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope; // In the absence of a focus in event on some platforms assume the window will - // be activated immediately and set focus on the rootItem + // be activated immediately and set focus on the contentItem // ### Remove when QTBUG-22415 is resolved. - //It is important that this call happens after the rootItem has a window.. - rootItem->setFocus(true); + //It is important that this call happens after the contentItem has a window.. + contentItem->setFocus(true); windowManager = QQuickWindowManager::instance(); context = windowManager->sceneGraphContext(); @@ -380,21 +405,26 @@ void QQuickWindowPrivate::init(QQuickWindow *c) QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection); } +/*! + \property QQuickWindow::data + \internal +*/ + QQmlListProperty QQuickWindowPrivate::data() { - initRootItem(); - return QQuickItemPrivate::get(rootItem)->data(); + initContentItem(); + return QQuickItemPrivate::get(contentItem)->data(); } -void QQuickWindowPrivate::initRootItem() +void QQuickWindowPrivate::initContentItem() { Q_Q(QQuickWindow); q->connect(q, SIGNAL(widthChanged(int)), - rootItem, SLOT(setWidth(int))); + contentItem, SLOT(setWidth(int))); q->connect(q, SIGNAL(heightChanged(int)), - rootItem, SLOT(setHeight(int))); - rootItem->setWidth(q->width()); - rootItem->setHeight(q->height()); + contentItem, SLOT(setHeight(int))); + contentItem->setWidth(q->width()); + contentItem->setHeight(q->height()); } static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true) @@ -497,7 +527,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e lastMousePosition = me->windowPos(); bool accepted = me->isAccepted(); - bool delivered = deliverHoverEvent(rootItem, me->windowPos(), last, me->modifiers(), accepted); + bool delivered = deliverHoverEvent(contentItem, me->windowPos(), last, me->modifiers(), accepted); if (!delivered) { //take care of any exits accepted = clearHover(); @@ -564,7 +594,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F Q_Q(QQuickWindow); Q_ASSERT(item); - Q_ASSERT(scope || item == rootItem); + Q_ASSERT(scope || item == contentItem); #ifdef FOCUS_DEBUG qWarning() << "QQuickWindowPrivate::setFocusInScope():"; @@ -584,7 +614,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F QVarLengthArray changed; // Does this change the active focus? - if (item == rootItem || (scopePrivate->activeFocus && item->isEnabled())) { + if (item == contentItem || (scopePrivate->activeFocus && item->isEnabled())) { oldActiveFocusItem = activeFocusItem; newActiveFocusItem = item; while (newActiveFocusItem->isFocusScope() @@ -613,7 +643,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F } } - if (item != rootItem && !(options & DontChangeSubFocusItem)) { + if (item != contentItem && !(options & DontChangeSubFocusItem)) { QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem; if (oldSubFocusItem) { QQuickItemPrivate::get(oldSubFocusItem)->focus = false; @@ -624,13 +654,13 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F } if (!(options & DontChangeFocusProperty)) { -// if (item != rootItem || QGuiApplication::focusWindow() == q) { // QTBUG-22415 +// if (item != contentItem || QGuiApplication::focusWindow() == q) { // QTBUG-22415 itemPrivate->focus = true; changed << item; // } } - if (newActiveFocusItem && rootItem->hasFocus()) { + if (newActiveFocusItem && contentItem->hasFocus()) { activeFocusItem = newActiveFocusItem; QQuickItemPrivate::get(newActiveFocusItem)->activeFocus = true; @@ -660,7 +690,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, Q_Q(QQuickWindow); Q_ASSERT(item); - Q_ASSERT(scope || item == rootItem); + Q_ASSERT(scope || item == contentItem); #ifdef FOCUS_DEBUG qWarning() << "QQuickWindowPrivate::clearFocusInScope():"; @@ -681,10 +711,10 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, QVarLengthArray changed; - Q_ASSERT(item == rootItem || item == scopePrivate->subFocusItem); + Q_ASSERT(item == contentItem || item == scopePrivate->subFocusItem); // Does this change the active focus? - if (item == rootItem || scopePrivate->activeFocus) { + if (item == contentItem || scopePrivate->activeFocus) { oldActiveFocusItem = activeFocusItem; newActiveFocusItem = scope; @@ -708,7 +738,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, } } - if (item != rootItem && !(options & DontChangeSubFocusItem)) { + if (item != contentItem && !(options & DontChangeSubFocusItem)) { QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem; if (oldSubFocusItem && !(options & DontChangeFocusProperty)) { QQuickItemPrivate::get(oldSubFocusItem)->focus = false; @@ -890,6 +920,10 @@ void QQuickWindowPrivate::cleanup(QSGNode *n) \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) { @@ -897,6 +931,9 @@ QQuickWindow::QQuickWindow(QWindow *parent) d->init(this); } +/*! + \internal +*/ QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent) : QWindow(dd, parent) { @@ -904,6 +941,9 @@ QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent) d->init(this); } +/*! + Destroys the window. +*/ QQuickWindow::~QQuickWindow() { Q_D(QQuickWindow); @@ -913,7 +953,7 @@ QQuickWindow::~QQuickWindow() QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); delete d->incubationController; d->incubationController = 0; - delete d->rootItem; d->rootItem = 0; + delete d->contentItem; d->contentItem = 0; } @@ -941,8 +981,8 @@ void QQuickWindow::releaseResources() /*! - 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(). @@ -971,8 +1011,8 @@ bool QQuickWindow::isPersistentOpenGLContext() const /*! - 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(). @@ -1004,7 +1044,8 @@ bool QQuickWindow::isPersistentSceneGraph() const /*! - 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 @@ -1014,7 +1055,7 @@ QQuickItem *QQuickWindow::contentItem() const { Q_D(const QQuickWindow); - return d->rootItem; + return d->contentItem; } /*! @@ -1052,14 +1093,6 @@ QQuickItem *QQuickWindow::mouseGrabberItem() const } -/*! - \qmlproperty color QtQuick.Window2::Window::color - - The background color for the window. - - Setting this property is more efficient than using a separate Rectangle. -*/ - bool QQuickWindowPrivate::clearHover() { Q_Q(QQuickWindow); @@ -1108,7 +1141,7 @@ bool QQuickWindow::event(QEvent *e) break; #endif case QEvent::WindowDeactivate: - rootItem()->windowDeactivateEvent(); + contentItem()->windowDeactivateEvent(); break; case QEvent::FocusAboutToChange: if (d->activeFocusItem) @@ -1167,7 +1200,7 @@ bool QQuickWindowPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouse QList 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; @@ -1200,7 +1233,7 @@ bool QQuickWindowPrivate::deliverMouseEvent(QMouseEvent *event) if (!mouseGrabberItem && event->type() == QEvent::MouseButtonPress && (event->buttons() & event->button()) == event->buttons()) { - if (deliverInitialMousePressEvent(rootItem, event)) + if (deliverInitialMousePressEvent(contentItem, event)) event->accept(); else event->ignore(); @@ -1258,7 +1291,7 @@ void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event) #endif if (!d->mouseGrabberItem && (event->buttons() & event->button()) == event->buttons()) { - if (d->deliverInitialMousePressEvent(d->rootItem, event)) + if (d->deliverInitialMousePressEvent(d->contentItem, event)) event->accept(); else event->ignore(); @@ -1303,7 +1336,7 @@ void QQuickWindow::mouseMoveEvent(QMouseEvent *event) d->lastMousePosition = event->windowPos(); bool accepted = event->isAccepted(); - bool delivered = d->deliverHoverEvent(d->rootItem, event->windowPos(), last, event->modifiers(), accepted); + bool delivered = d->deliverHoverEvent(d->contentItem, event->windowPos(), last, event->modifiers(), accepted); if (!delivered) { //take care of any exits accepted = d->clearHover(); @@ -1329,7 +1362,7 @@ bool QQuickWindowPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce QList 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; @@ -1395,7 +1428,7 @@ bool QQuickWindowPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event QList 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; @@ -1426,12 +1459,12 @@ void QQuickWindow::wheelEvent(QWheelEvent *event) 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; event->ignore(); - d->deliverWheelEvent(d->rootItem, event); + d->deliverWheelEvent(d->contentItem, event); d->lastWheelEventAccepted = event->isAccepted(); } #endif // QT_NO_WHEELEVENT @@ -1502,7 +1535,7 @@ bool QQuickWindowPrivate::deliverTouchEvent(QTouchEvent *event) // or some item accepted a point and should receive an update if (newPoints.count() > 0 || updatedPoints.count() > 0) { QSet acceptedNewPoints; - event->setAccepted(deliverTouchPoints(rootItem, event, newPoints, &acceptedNewPoints, &updatedPoints)); + event->setAccepted(deliverTouchPoints(contentItem, event, newPoints, &acceptedNewPoints, &updatedPoints)); } else event->ignore(); @@ -1542,7 +1575,7 @@ bool QQuickWindowPrivate::deliverTouchPoints(QQuickItem *item, QTouchEvent *even QList 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; @@ -1773,7 +1806,7 @@ void QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *e e->mouseButtons(), e->keyboardModifiers()); QQuickDropEventEx::copyActions(&enterEvent, *e); - event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent)); + event->setAccepted(deliverDragEvent(grabber, contentItem, &enterEvent)); } } @@ -1782,7 +1815,7 @@ bool QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte 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()); @@ -1833,7 +1866,7 @@ void QQuickWindowPrivate::updateCursor(const QPointF &scenePos) Q_Q(QQuickWindow); QQuickItem *oldCursorItem = cursorItem; - cursorItem = findCursorItem(rootItem, scenePos); + cursorItem = findCursorItem(contentItem, scenePos); if (cursorItem != oldCursorItem) { if (cursorItem) @@ -1852,13 +1885,18 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF return 0; } - QList children = itemPrivate->paintOrderChildItems(); - for (int ii = children.count() - 1; ii >= 0; --ii) { - QQuickItem *child = children.at(ii); - if (!child->isVisible() || !child->isEnabled()) - continue; - if (QQuickItem *cursorItem = findCursorItem(child, scenePos)) - return cursorItem; + const int numCursorsInHierarchy = itemPrivate->extra.isAllocated() ? itemPrivate->extra.value().numItemsWithCursor : 0; + const int numChildrenWithCursor = itemPrivate->hasCursor ? numCursorsInHierarchy-1 : numCursorsInHierarchy; + + if (numChildrenWithCursor > 0) { + QList children = itemPrivate->paintOrderChildItems(); + for (int ii = children.count() - 1; ii >= 0; --ii) { + QQuickItem *child = children.at(ii); + if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled) + continue; + if (QQuickItem *cursorItem = findCursorItem(child, scenePos)) + return cursorItem; + } } if (itemPrivate->hasCursor) { @@ -1954,8 +1992,21 @@ bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent return overThreshold; } +bool QQuickWindowPrivate::isRenderable() const +{ + if (geometry.width() <= 0 || geometry.height() <= 0) + return false; + // Change to be applied after the visibility property is integrated in qtbase: +// return visibility != QWindow::Hidden || (renderWithoutShowing && platformWindow); + // Temporary version which is implementation-agnostic but slightly less efficient: + const QQuickWindow *q = q_func(); + return q->isVisible() || (renderWithoutShowing && platformWindow); +} + /*! - 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) { @@ -2063,7 +2114,7 @@ void QQuickWindowPrivate::cleanupNodesOnShutdown() { Q_Q(QQuickWindow); cleanupNodes(); - cleanupNodesOnShutdown(rootItem); + cleanupNodesOnShutdown(contentItem); QSet::const_iterator it = parentlessItems.begin(); for (; it != parentlessItems.end(); ++it) cleanupNodesOnShutdown(*it); @@ -2373,9 +2424,17 @@ QOpenGLContext *QQuickWindow::openglContext() const 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. @@ -2385,7 +2444,7 @@ QOpenGLContext *QQuickWindow::openglContext() const /*! - \fn void QSGContext::sceneGraphInvalidated() + \fn void QQuickWindow::sceneGraphInvalidated() This signal is emitted when the scene graph has been invalidated. @@ -2411,7 +2470,7 @@ QOpenGLContext *QQuickWindow::openglContext() const void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo) { Q_D(QQuickWindow); - if (d->context && d->context && QThread::currentThread() != d->context->thread()) { + if (d->context && QThread::currentThread() != d->context->thread()) { qWarning("QQuickWindow::setRenderThread: Cannot set render target from outside the rendering thread"); return; } @@ -2428,11 +2487,22 @@ void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo) /*! \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); - if (d->context && d->context && QThread::currentThread() != d->context->thread()) { + if (d->context && QThread::currentThread() != d->context->thread()) { qWarning("QQuickWindow::setRenderThread: Cannot set render target from outside the rendering thread"); return; } @@ -2455,7 +2525,7 @@ uint QQuickWindow::renderTargetId() const } /*! - Returns the size of the currently set render target; otherwise returns an enpty size. + Returns the size of the currently set render target; otherwise returns an empty size. */ QSize QQuickWindow::renderTargetSize() const { @@ -2507,7 +2577,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const Q_D(const QQuickWindow); if (!d->incubationController) - d->incubationController = new QQuickWindowIncubationController(const_cast(d)); + d->incubationController = new QQuickWindowIncubationController(this); return d->incubationController; } @@ -2529,6 +2599,25 @@ QQmlIncubationController *QQuickWindow::incubationController() const */ /*! + \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. @@ -2539,8 +2628,9 @@ QQmlIncubationController *QQuickWindow::incubationController() const 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 @@ -2557,8 +2647,9 @@ QQmlIncubationController *QQuickWindow::incubationController() const 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 @@ -2568,8 +2659,8 @@ QQmlIncubationController *QQuickWindow::incubationController() const /*! - Sets weither the scene graph rendering of QML should clear the color buffer - before it starts rendering to \a enbled. + Sets whether the scene graph rendering of QML should clear the color buffer + 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. @@ -2588,7 +2679,7 @@ void QQuickWindow::setClearBeforeRendering(bool enabled) /*! - Returns weither clearing of the color buffer is done before rendering or not. + Returns whether clearing of the color buffer is done before rendering or not. */ bool QQuickWindow::clearBeforeRendering() const @@ -2615,7 +2706,7 @@ bool QQuickWindow::clearBeforeRendering() const 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. @@ -2637,7 +2728,7 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const /*! - 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. @@ -2663,11 +2754,20 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create return 0; } +/*! + \qmlproperty color QtQuick.Window2::Window::color + + The background color for the window. + + Setting this property is more efficient than using a separate Rectangle. +*/ /*! - 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() */ @@ -2680,20 +2780,34 @@ void QQuickWindow::setColor(const QColor &color) d->clearColor = color; emit colorChanged(color); + d->dirtyItem(contentItem()); } - - -/*! - Returns the color used to clear the opengl context. - */ - QColor QQuickWindow::color() const { return d_func()->clearColor; } +/*! + \qmlproperty string QtQuick.Window2::Window::title + + The window's title in the windowing system. + The window title might appear in the title area of the window decorations, + depending on the windowing system and the window flags. It might also + be used by the windowing system to identify the window in other contexts, + such as in the task switcher. + */ + +/*! + \qmlproperty string QtQuick.Window2::Window::modality + + The modality of the window. + + A modal window prevents other windows from receiving input events. + Possible values are Qt.NonModal (the default), Qt.WindowModal, + and Qt.ApplicationModal. + */ #include "moc_qquickwindow.cpp"