From 79f0af6cd097f55eacb763574e173f134c9c0a32 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 17 Feb 2021 13:50:52 +0100 Subject: Stage 3: remove non-delivery code from qquickdeliveryagent.cpp Change-Id: I94d2fb19b885a4821f3d2e12bde14fd834386848 --- src/quick/util/qquickdeliveryagent.cpp | 828 +-------------------------------- 1 file changed, 1 insertion(+), 827 deletions(-) diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp index acc220bba3..365304128d 100644 --- a/src/quick/util/qquickdeliveryagent.cpp +++ b/src/quick/util/qquickdeliveryagent.cpp @@ -37,838 +37,12 @@ ** ****************************************************************************/ -#include "qquickwindow.h" -#include "qquickwindow_p.h" - -#include "qquickitem.h" -#include "qquickitem_p.h" -#include "qquickevents_p_p.h" -#include "qquickgraphicsdevice_p.h" - -#if QT_CONFIG(quick_draganddrop) -#include -#endif -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#if QT_CONFIG(opengl) -#include -#include -#endif -#ifndef QT_NO_DEBUG_STREAM -#include -#endif - -#include +#include QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(lcTouch, "qt.quick.touch") -Q_LOGGING_CATEGORY(lcTouchCmprs, "qt.quick.touch.compression") -Q_LOGGING_CATEGORY(lcTouchTarget, "qt.quick.touch.target") -Q_LOGGING_CATEGORY(lcMouse, "qt.quick.mouse") -Q_LOGGING_CATEGORY(lcMouseTarget, "qt.quick.mouse.target") -Q_LOGGING_CATEGORY(lcPtr, "qt.quick.pointer") -Q_LOGGING_CATEGORY(lcPtrGrab, "qt.quick.pointer.grab") -Q_LOGGING_CATEGORY(lcTablet, "qt.quick.tablet") -Q_LOGGING_CATEGORY(lcWheelTarget, "qt.quick.wheel.target") -Q_LOGGING_CATEGORY(lcGestureTarget, "qt.quick.gesture.target") -Q_LOGGING_CATEGORY(lcHoverTrace, "qt.quick.hover.trace") -Q_LOGGING_CATEGORY(lcFocus, "qt.quick.focus") -Q_LOGGING_CATEGORY(lcDirty, "qt.quick.dirty") -Q_LOGGING_CATEGORY(lcTransient, "qt.quick.window.transient") - extern Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1); -bool QQuickWindowPrivate::defaultAlphaBuffer = false; - -#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE) -QQuickWindow::TextRenderType QQuickWindowPrivate::textRenderType = QQuickWindow::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE; -#else -QQuickWindow::TextRenderType QQuickWindowPrivate::textRenderType = QQuickWindow::QtTextRendering; -#endif - -void QQuickWindowPrivate::updateFocusItemTransform() -{ -#if QT_CONFIG(im) - Q_Q(QQuickWindow); - QQuickItem *focus = q->activeFocusItem(); - if (focus && QGuiApplication::focusObject() == focus) { - QQuickItemPrivate *focusPrivate = QQuickItemPrivate::get(focus); - QGuiApplication::inputMethod()->setInputItemTransform(focusPrivate->itemToWindowTransform()); - QGuiApplication::inputMethod()->setInputItemRectangle(QRectF(0, 0, focusPrivate->width, focusPrivate->height)); - focus->updateInputMethod(Qt::ImInputItemClipRectangle); - } -#endif -} - -class QQuickWindowIncubationController : public QObject, public QQmlIncubationController -{ - Q_OBJECT - -public: - QQuickWindowIncubationController(QSGRenderLoop *loop) - : m_renderLoop(loop), m_timer(0) - { - // Allow incubation for 1/3 of a frame. - m_incubation_time = qMax(1, int(1000 / QGuiApplication::primaryScreen()->refreshRate()) / 3); - - QAnimationDriver *animationDriver = m_renderLoop->animationDriver(); - if (animationDriver) { - connect(animationDriver, SIGNAL(stopped()), this, SLOT(animationStopped())); - connect(m_renderLoop, SIGNAL(timeToIncubate()), this, SLOT(incubate())); - } - } - -protected: - void timerEvent(QTimerEvent *) override - { - killTimer(m_timer); - m_timer = 0; - incubate(); - } - - void incubateAgain() { - if (m_timer == 0) { - // Wait for a while before processing the next batch. Using a - // timer to avoid starvation of system events. - m_timer = startTimer(m_incubation_time); - } - } - -public slots: - void incubate() { - if (m_renderLoop && incubatingObjectCount()) { - if (m_renderLoop->interleaveIncubation()) { - incubateFor(m_incubation_time); - } else { - incubateFor(m_incubation_time * 2); - if (incubatingObjectCount()) - incubateAgain(); - } - } - } - - void animationStopped() { incubate(); } - -protected: - void incubatingObjectCountChanged(int count) override - { - if (count && m_renderLoop && !m_renderLoop->interleaveIncubation()) - incubateAgain(); - } - -private: - QPointer m_renderLoop; - int m_incubation_time; - int m_timer; -}; - -#include "qquickwindow.moc" -#include "moc_qquickwindow_p.cpp" - - -#if QT_CONFIG(accessibility) -/*! - Returns an accessibility interface for this window, or 0 if such an - interface cannot be created. -*/ -QAccessibleInterface *QQuickWindow::accessibleRoot() const -{ - return QAccessible::queryAccessibleInterface(const_cast(this)); -} -#endif - - -/* -Focus behavior -============== - -Prior to being added to a valid window items can set and clear focus with no -effect. Only once items are added to a window (by way of having a parent set that -already belongs to a window) do the focus rules apply. Focus goes back to -having no effect if an item is removed from a window. - -When an item is moved into a new focus scope (either being added to a window -for the first time, or having its parent changed), if the focus scope already has -a scope focused item that takes precedence over the item being added. Otherwise, -the focus of the added tree is used. In the case of a tree of items being -added to a window for the first time, which may have a conflicted focus state (two -or more items in one scope having focus set), the same rule is applied item by item - -thus the first item that has focus will get it (assuming the scope doesn't already -have a scope focused item), and the other items will have their focus cleared. -*/ - -QQuickRootItem::QQuickRootItem() -{ -} - -/*! \reimp */ -void QQuickWindow::exposeEvent(QExposeEvent *) -{ - Q_D(QQuickWindow); - if (d->windowManager) - d->windowManager->exposureChanged(this); -} - -/*! \reimp */ -void QQuickWindow::resizeEvent(QResizeEvent *ev) -{ - Q_D(QQuickWindow); - if (d->contentItem) - d->contentItem->setSize(ev->size()); - if (d->windowManager) - d->windowManager->resize(this); -} - -/*! \reimp */ -void QQuickWindow::showEvent(QShowEvent *) -{ - Q_D(QQuickWindow); - if (d->windowManager) - d->windowManager->show(this); -} - -/*! \reimp */ -void QQuickWindow::hideEvent(QHideEvent *) -{ - Q_D(QQuickWindow); - if (d->windowManager) - d->windowManager->hide(this); -} - -/*! \reimp */ -void QQuickWindow::closeEvent(QCloseEvent *e) -{ - QQuickCloseEvent qev; - qev.setAccepted(e->isAccepted()); - emit closing(&qev); - e->setAccepted(qev.isAccepted()); -} - -/*! \reimp */ -void QQuickWindow::focusOutEvent(QFocusEvent *ev) -{ - Q_D(QQuickWindow); - if (d->contentItem) - d->contentItem->setFocus(false, ev->reason()); -} - -/*! \reimp */ -void QQuickWindow::focusInEvent(QFocusEvent *ev) -{ - Q_D(QQuickWindow); - if (d->contentItem) - d->contentItem->setFocus(true, ev->reason()); - d->updateFocusItemTransform(); -} - -#if QT_CONFIG(im) -static bool transformDirtyOnItemOrAncestor(const QQuickItem *item) -{ - while (item) { - if (QQuickItemPrivate::get(item)->dirtyAttributes & ( - QQuickItemPrivate::TransformOrigin | - QQuickItemPrivate::Transform | - QQuickItemPrivate::BasicTransform | - QQuickItemPrivate::Position | - QQuickItemPrivate::Size | - QQuickItemPrivate::ParentChanged | - QQuickItemPrivate::Clip)) { - return true; - } - item = item->parentItem(); - } - return false; -} -#endif - -/*! - * \internal - - A "polish loop" can occur inside QQuickWindowPrivate::polishItems(). It is when an item calls - polish() on an(other?) item from updatePolish(). If this anomaly happens repeatedly and without - interruption (of a well-behaved updatePolish() that doesn't call polish()), it is a strong - indication that we are heading towards an infinite polish loop. A polish loop is not a bug in - Qt Quick - it is a bug caused by ill-behaved items put in the scene. - - We can detect this sequence of polish loops easily, since the - QQuickWindowPrivate::itemsToPolish is basically a stack: polish() will push to it, and - polishItems() will pop from it. - Therefore if updatePolish() calls polish(), the immediate next item polishItems() processes is - the item that was polished by the previous call to updatePolish(). - We therefore just need to count the number of polish loops we detected in _sequence_. -*/ -struct PolishLoopDetector -{ - PolishLoopDetector(const QVector &itemsToPolish) - : itemsToPolish(itemsToPolish) - { - } - - /* - * returns true when it detected a likely infinite loop - * (suggests it should abort the polish loop) - **/ - bool check(QQuickItem *item, int itemsRemainingBeforeUpdatePolish) - { - if (itemsToPolish.count() > itemsRemainingBeforeUpdatePolish) { - // Detected potential polish loop. - ++numPolishLoopsInSequence; - if (numPolishLoopsInSequence >= 1000) { - // Start to warn about polish loop after 1000 consecutive polish loops - if (numPolishLoopsInSequence == 100000) { - // We have looped 100,000 times without actually reducing the list of items to - // polish, give up for now. - // This is not a fix, just a remedy so that the application can be somewhat - // responsive. - numPolishLoopsInSequence = 0; - return true; - } else if (numPolishLoopsInSequence < 1005) { - // Show the 5 next items involved in the polish loop. - // (most likely they will be the same 5 items...) - QQuickItem *guiltyItem = itemsToPolish.last(); - qmlWarning(item) << "possible QQuickItem::polish() loop"; - - auto typeAndObjectName = [](QQuickItem *item) { - QString typeName = QQmlMetaType::prettyTypeName(item); - QString objName = item->objectName(); - if (!objName.isNull()) - return QLatin1String("%1(%2)").arg(typeName, objName); - return typeName; - }; - - qmlWarning(guiltyItem) << typeAndObjectName(guiltyItem) - << " called polish() inside updatePolish() of " << typeAndObjectName(item); - - if (numPolishLoopsInSequence == 1004) - // Enough warnings. Reset counter in order to speed things up and re-detect - // more loops - numPolishLoopsInSequence = 0; - } - } - } else { - numPolishLoopsInSequence = 0; - } - return false; - } - const QVector &itemsToPolish; // Just a ref to the one in polishItems() - int numPolishLoopsInSequence = 0; -}; - -void QQuickWindowPrivate::polishItems() -{ - // An item can trigger polish on another item, or itself for that matter, - // during its updatePolish() call. Because of this, we cannot simply - // iterate through the set, we must continue pulling items out until it - // is empty. - // In the case where polish is called from updatePolish() either directly - // or indirectly, we use a PolishLoopDetector to determine if a warning should - // be printed to the user. - - PolishLoopDetector polishLoopDetector(itemsToPolish); - while (!itemsToPolish.isEmpty()) { - QQuickItem *item = itemsToPolish.takeLast(); - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - itemPrivate->polishScheduled = false; - const int itemsRemaining = itemsToPolish.count(); - itemPrivate->updatePolish(); - item->updatePolish(); - if (polishLoopDetector.check(item, itemsRemaining) == true) - break; - } - -#if QT_CONFIG(im) - if (QQuickItem *focusItem = q_func()->activeFocusItem()) { - // If the current focus item, or any of its anchestors, has changed location - // inside the window, we need inform IM about it. This to ensure that overlays - // such as selection handles will be updated. - const bool isActiveFocusItem = (focusItem == QGuiApplication::focusObject()); - const bool hasImEnabled = focusItem->inputMethodQuery(Qt::ImEnabled).toBool(); - if (isActiveFocusItem && hasImEnabled && transformDirtyOnItemOrAncestor(focusItem)) - updateFocusItemTransform(); - } -#endif -} - -/*! - * Schedules the window to render another frame. - * - * Calling QQuickWindow::update() differs from QQuickItem::update() in that - * it always triggers a repaint, regardless of changes in the underlying - * scene graph or not. - */ -void QQuickWindow::update() -{ - Q_D(QQuickWindow); - if (d->windowManager) - d->windowManager->update(this); - else if (d->renderControl) - QQuickRenderControlPrivate::get(d->renderControl)->update(); -} - -static void updatePixelRatioHelper(QQuickItem *item, float pixelRatio) -{ - if (item->flags() & QQuickItem::ItemHasContents) { - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - itemPrivate->itemChange(QQuickItem::ItemDevicePixelRatioHasChanged, pixelRatio); - } - - QList items = item->childItems(); - for (int i = 0; i < items.size(); ++i) - updatePixelRatioHelper(items.at(i), pixelRatio); -} - -void QQuickWindow::physicalDpiChanged() -{ - Q_D(QQuickWindow); - const qreal newPixelRatio = screen()->devicePixelRatio(); - if (qFuzzyCompare(newPixelRatio, d->devicePixelRatio)) - return; - d->devicePixelRatio = newPixelRatio; - if (d->contentItem) - updatePixelRatioHelper(d->contentItem, newPixelRatio); -} - -void QQuickWindow::handleScreenChanged(QScreen *screen) -{ - Q_D(QQuickWindow); - if (screen) { - physicalDpiChanged(); - // When physical DPI changes on the same screen, either the resolution or the device pixel - // ratio changed. We must check what it is. Device pixel ratio does not have its own - // ...Changed() signal. - d->physicalDpiChangedConnection = connect(screen, SIGNAL(physicalDotsPerInchChanged(qreal)), - this, SLOT(physicalDpiChanged())); - } else { - disconnect(d->physicalDpiChangedConnection); - } - - d->forcePolish(); -} - -void forcePolishHelper(QQuickItem *item) -{ - if (item->flags() & QQuickItem::ItemHasContents) { - item->polish(); - } - - QList items = item->childItems(); - for (int i=0; iscreen()) - return; - forcePolishHelper(contentItem); -} - -void forceUpdate(QQuickItem *item) -{ - if (item->flags() & QQuickItem::ItemHasContents) - item->update(); - QQuickItemPrivate::get(item)->dirty(QQuickItemPrivate::ChildrenUpdateMask); - - QList items = item->childItems(); - for (int i=0; iinvalidatePipelineCacheDependency(rpDesc); - if (owns) { - delete renderTarget; - delete rpDesc; - delete texture; - delete depthStencil; - } - } - - renderTarget = nullptr; - rpDesc = nullptr; - texture = nullptr; - depthStencil = nullptr; - owns = false; -} - -void QQuickWindowPrivate::ensureCustomRenderTarget() -{ - // resolve() can be expensive when importing an existing native texture, so - // it is important to only do it when the QQuickRenderTarget* was really changed - if (!redirect.renderTargetDirty || !rhi) - return; - - redirect.renderTargetDirty = false; - - redirect.rt.reset(rhi, renderer); - - // a default constructed QQuickRenderTarget means no redirection - if (customRenderTarget.isNull()) - return; - - QQuickRenderTargetPrivate::get(&customRenderTarget)->resolve(rhi, &redirect.rt); -} - -void QQuickWindowPrivate::setCustomCommandBuffer(QRhiCommandBuffer *cb) -{ - // ownership not transferred - redirect.commandBuffer = cb; -} - -void QQuickWindowPrivate::syncSceneGraph() -{ - Q_Q(QQuickWindow); - - ensureCustomRenderTarget(); - - // Calculate the dpr the same way renderSceneGraph() will. - qreal devicePixelRatio = q->effectiveDevicePixelRatio(); - if (redirect.rt.renderTarget && !QQuickRenderControl::renderWindowFor(q)) - devicePixelRatio = 1; - - QRhiCommandBuffer *cb = nullptr; - if (rhi) { - if (redirect.commandBuffer) - cb = redirect.commandBuffer; - else - cb = swapchain->currentFrameCommandBuffer(); - } - context->prepareSync(devicePixelRatio, cb, graphicsConfig); - - animationController->beforeNodeSync(); - - emit q->beforeSynchronizing(); - runAndClearJobs(&beforeSynchronizingJobs); - if (!renderer) { - forceUpdate(contentItem); - - QSGRootNode *rootNode = new QSGRootNode; - rootNode->appendChildNode(QQuickItemPrivate::get(contentItem)->itemNode()); - const bool useDepth = graphicsConfig.isDepthBufferEnabledFor2D(); - const QSGRendererInterface::RenderMode renderMode = useDepth ? QSGRendererInterface::RenderMode2D - : QSGRendererInterface::RenderMode2DNoDepthBuffer; - renderer = context->createRenderer(renderMode); - renderer->setRootNode(rootNode); - } - - updateDirtyNodes(); - - animationController->afterNodeSync(); - - // Copy the current state of clearing from window into renderer. - renderer->setClearColor(clearColor); - // Cannot skip clearing the color buffer in Qt 6 anymore. - const QSGAbstractRenderer::ClearMode mode = QSGAbstractRenderer::ClearColorBuffer - | QSGAbstractRenderer::ClearStencilBuffer - | QSGAbstractRenderer::ClearDepthBuffer; - renderer->setClearMode(mode); - - renderer->setVisualizationMode(visualizationMode); - - emit q->afterSynchronizing(); - runAndClearJobs(&afterSynchronizingJobs); -} - -void QQuickWindowPrivate::emitBeforeRenderPassRecording(void *ud) -{ - QQuickWindow *w = reinterpret_cast(ud); - emit w->beforeRenderPassRecording(); -} - -void QQuickWindowPrivate::emitAfterRenderPassRecording(void *ud) -{ - QQuickWindow *w = reinterpret_cast(ud); - emit w->afterRenderPassRecording(); -} - -void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfaceSize) -{ - Q_Q(QQuickWindow); - if (!renderer) - return; - - if (rhi) { - ensureCustomRenderTarget(); - QRhiRenderTarget *rt; - QRhiRenderPassDescriptor *rp; - QRhiCommandBuffer *cb; - if (redirect.rt.renderTarget) { - rt = redirect.rt.renderTarget; - rp = rt->renderPassDescriptor(); - if (!rp) { - qWarning("Custom render target is set but no renderpass descriptor has been provided."); - return; - } - cb = redirect.commandBuffer; - if (!cb) { - qWarning("Custom render target is set but no command buffer has been provided."); - return; - } - } else { - if (!swapchain) { - qWarning("QQuickWindow: No render target (neither swapchain nor custom target was provided)"); - return; - } - rt = swapchain->currentFrameRenderTarget(); - rp = rpDescForSwapchain; - cb = swapchain->currentFrameCommandBuffer(); - } - context->beginNextRhiFrame(renderer, rt, rp, cb, - emitBeforeRenderPassRecording, - emitAfterRenderPassRecording, - q); - } else { - context->beginNextFrame(renderer, - emitBeforeRenderPassRecording, - emitAfterRenderPassRecording, - q); - } - - animationController->advance(); - emit q->beforeRendering(); - runAndClearJobs(&beforeRenderingJobs); - - QSGAbstractRenderer::MatrixTransformFlags matrixFlags; - const bool flipY = rhi ? !rhi->isYUpInNDC() : false; - if (flipY) - matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY; - const qreal devicePixelRatio = q->effectiveDevicePixelRatio(); - if (redirect.rt.renderTarget) { - QRect rect(QPoint(0, 0), redirect.rt.renderTarget->pixelSize()); - renderer->setDeviceRect(rect); - renderer->setViewportRect(rect); - if (QQuickRenderControl::renderWindowFor(q)) { - renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size), matrixFlags); - renderer->setDevicePixelRatio(devicePixelRatio); - } else { - renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), rect.size()), matrixFlags); - renderer->setDevicePixelRatio(1); - } - } else { - QSize pixelSize; - QSizeF logicalSize; - if (surfaceSize.isEmpty()) { - pixelSize = size * devicePixelRatio; - logicalSize = size; - } else { - pixelSize = surfaceSize; - logicalSize = QSizeF(surfaceSize) / devicePixelRatio; - } - QRect rect(QPoint(0, 0), pixelSize); - renderer->setDeviceRect(rect); - renderer->setViewportRect(rect); - renderer->setProjectionMatrixToRect(QRectF(QPoint(0, 0), logicalSize), matrixFlags); - renderer->setDevicePixelRatio(devicePixelRatio); - } - - if (rhi) { - context->renderNextRhiFrame(renderer); - } else { - // This is the software backend (or some custom scenegraph context - // plugin) in practice, because the default implementation always - // hits the QRhi-based path in Qt 6. - context->renderNextFrame(renderer); - } - - emit q->afterRendering(); - runAndClearJobs(&afterRenderingJobs); - - if (rhi) - context->endNextRhiFrame(renderer); - else - context->endNextFrame(renderer); - - if (renderer && renderer->hasVisualizationModeWithContinuousUpdate()) { - // For the overdraw visualizer. This update is not urgent so avoid a - // direct update() call, this is only here to keep the overdraw - // visualization box rotating even when the scene is static. - QCoreApplication::postEvent(q, new QEvent(QEvent::Type(FullUpdateRequest))); - } -} - -QQuickWindowPrivate::QQuickWindowPrivate() - : contentItem(nullptr) - , activeFocusItem(nullptr) -#if QT_CONFIG(cursor) - , cursorItem(nullptr) - , cursorHandler(nullptr) -#endif -#if QT_CONFIG(quick_draganddrop) - , dragGrabber(nullptr) -#endif - , touchMouseId(-1) - , touchMouseDevice(nullptr) - , touchMousePressTimestamp(0) - , dirtyItemList(nullptr) - , devicePixelRatio(0) - , context(nullptr) - , renderer(nullptr) - , windowManager(nullptr) - , renderControl(nullptr) - , pointerEventRecursionGuard(0) - , clearColor(Qt::white) - , persistentGraphics(true) - , persistentSceneGraph(true) - , lastWheelEventAccepted(false) - , componentCompleted(true) - , allowChildEventFiltering(true) - , allowDoubleClick(true) - , lastFocusReason(Qt::OtherFocusReason) - , incubationController(nullptr) - , hasActiveSwapchain(false) - , hasRenderableSwapchain(false) - , swapchainJustBecameRenderable(false) -{ -#if QT_CONFIG(quick_draganddrop) - dragGrabber = new QQuickDragGrabber; -#endif -} - -QQuickWindowPrivate::~QQuickWindowPrivate() -{ - redirect.rt.reset(rhi, renderer); - if (QQmlInspectorService *service = QQmlDebugConnector::service()) - service->removeWindow(q_func()); -} - -void QQuickWindowPrivate::updateChildrenPalettes(const QPalette &parentPalette) -{ - Q_Q(QQuickWindow); - if (auto root = q->contentItem()) { - for (auto &&child: root->childItems()) { - QQuickItemPrivate::get(child)->inheritPalette(parentPalette); - } - } -} - -void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) -{ - q_ptr = c; - - - Q_Q(QQuickWindow); - - contentItem = new QQuickRootItem; - QQml_setParent_noEvent(contentItem, c); - QQmlEngine::setObjectOwnership(contentItem, QQmlEngine::CppOwnership); - QQuickItemPrivate *contentItemPrivate = QQuickItemPrivate::get(contentItem); - contentItemPrivate->window = q; - contentItemPrivate->windowRefCount = 1; - contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope; - contentItem->setSize(q->size()); - - visualizationMode = qgetenv("QSG_VISUALIZE"); - renderControl = control; - if (renderControl) - QQuickRenderControlPrivate::get(renderControl)->window = q; - - if (!renderControl) - windowManager = QSGRenderLoop::instance(); - - Q_ASSERT(windowManager || renderControl); - - if (QScreen *screen = q->screen()) - devicePixelRatio = screen->devicePixelRatio(); - - QSGContext *sg; - if (renderControl) { - QQuickRenderControlPrivate *renderControlPriv = QQuickRenderControlPrivate::get(renderControl); - sg = renderControlPriv->sg; - context = renderControlPriv->rc; - } else { - windowManager->addWindow(q); - sg = windowManager->sceneGraphContext(); - context = windowManager->createRenderContext(sg); - } - - q->setSurfaceType(windowManager ? windowManager->windowSurfaceType() : QSurface::OpenGLSurface); - q->setFormat(sg->defaultSurfaceFormat()); - // When using Vulkan, associating a scenegraph-managed QVulkanInstance with - // the window (but only when not using renderControl) is deferred to - // QSGRhiSupport::createRhi(). This allows applications to set up their own - // QVulkanInstance and set that on the window, if they wish to. - - animationController.reset(new QQuickAnimatorController(q)); - - QObject::connect(context, SIGNAL(initialized()), q, SIGNAL(sceneGraphInitialized()), Qt::DirectConnection); - QObject::connect(context, SIGNAL(invalidated()), q, SIGNAL(sceneGraphInvalidated()), Qt::DirectConnection); - QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection); - - QObject::connect(q, SIGNAL(focusObjectChanged(QObject*)), q, SIGNAL(activeFocusItemChanged())); - QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(handleScreenChanged(QScreen*))); - QObject::connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), - q, SLOT(handleApplicationStateChanged(Qt::ApplicationState))); - QObject::connect(q, SIGNAL(frameSwapped()), q, SLOT(runJobsAfterSwap()), Qt::DirectConnection); - - if (QQmlInspectorService *service = QQmlDebugConnector::service()) - service->addWindow(q); -} - -void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state) -{ - Q_D(QQuickWindow); - if (state != Qt::ApplicationActive && d->contentItem) - d->handleWindowDeactivate(); -} - -/*! - \property QQuickWindow::data - \internal -*/ - -QQmlListProperty QQuickWindowPrivate::data() -{ - return QQmlListProperty(q_func(), nullptr, - QQuickWindowPrivate::data_append, - QQuickWindowPrivate::data_count, - QQuickWindowPrivate::data_at, - QQuickWindowPrivate::data_clear, - QQuickWindowPrivate::data_replace, - QQuickWindowPrivate::data_removeLast); -} - void QQuickWindowPrivate::touchToMouseEvent(QEvent::Type type, const QEventPoint &p, const QTouchEvent *touchEvent, QMutableSinglePointEvent *mouseEvent) { Q_ASSERT(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)); -- cgit v1.2.3