Merge pull request #11335 from vladest/menu_fix

Make sure root item is created before lambda gets called for desktop …
This commit is contained in:
anshuman64 2017-09-11 12:47:40 -07:00 committed by GitHub
commit 996277b34c
2 changed files with 31 additions and 26 deletions

View file

@ -640,7 +640,7 @@ void OffscreenQmlSurface::setBaseUrl(const QUrl& baseUrl) {
_qmlContext->setBaseUrl(baseUrl); _qmlContext->setBaseUrl(baseUrl);
} }
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, std::function<void(QQmlContext*, QObject*)> f) { void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
qCWarning(uiLogging) << "Called load on a non-surface thread"; qCWarning(uiLogging) << "Called load on a non-surface thread";
} }
@ -660,28 +660,28 @@ void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, std
auto qmlComponent = new QQmlComponent(_qmlContext->engine(), finalQmlSource, QQmlComponent::PreferSynchronous); auto qmlComponent = new QQmlComponent(_qmlContext->engine(), finalQmlSource, QQmlComponent::PreferSynchronous);
if (qmlComponent->isLoading()) { if (qmlComponent->isLoading()) {
connect(qmlComponent, &QQmlComponent::statusChanged, this, connect(qmlComponent, &QQmlComponent::statusChanged, this,
[this, qmlComponent, targetContext, f](QQmlComponent::Status) { [this, qmlComponent, targetContext, onQmlLoadedCallback](QQmlComponent::Status) {
finishQmlLoad(qmlComponent, targetContext, f); finishQmlLoad(qmlComponent, targetContext, onQmlLoadedCallback);
}); });
return; return;
} }
finishQmlLoad(qmlComponent, targetContext, f); finishQmlLoad(qmlComponent, targetContext, onQmlLoadedCallback);
} }
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> f) { void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
load(qmlSource, true, f); load(qmlSource, true, onQmlLoadedCallback);
} }
void OffscreenQmlSurface::load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> f) { void OffscreenQmlSurface::load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
load(qmlSource, false, f); load(qmlSource, false, onQmlLoadedCallback);
} }
void OffscreenQmlSurface::clearCache() { void OffscreenQmlSurface::clearCache() {
_qmlContext->engine()->clearComponentCache(); _qmlContext->engine()->clearComponentCache();
} }
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, std::function<void(QQmlContext*, QObject*)> f) { void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
disconnect(qmlComponent, &QQmlComponent::statusChanged, this, 0); disconnect(qmlComponent, &QQmlComponent::statusChanged, this, 0);
if (qmlComponent->isError()) { if (qmlComponent->isError()) {
for (const auto& error : qmlComponent->errors()) { for (const auto& error : qmlComponent->errors()) {
@ -691,7 +691,6 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
return; return;
} }
QObject* newObject = qmlComponent->beginCreate(qmlContext); QObject* newObject = qmlComponent->beginCreate(qmlContext);
if (qmlComponent->isError()) { if (qmlComponent->isError()) {
for (const auto& error : qmlComponent->errors()) { for (const auto& error : qmlComponent->errors()) {
@ -705,7 +704,20 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
} }
qmlContext->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership); qmlContext->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
f(qmlContext, newObject);
// All quick items should be focusable
QQuickItem* newItem = qobject_cast<QQuickItem*>(newObject);
if (newItem) {
// Make sure we make items focusable (critical for
// supporting keyboard shortcuts)
newItem->setFlag(QQuickItem::ItemIsFocusScope, true);
}
// Make sure we will call callback for this codepath
// Call this before qmlComponent->completeCreate() otherwise ghost window appears
if (newItem && _rootItem) {
onQmlLoadedCallback(qmlContext, newObject);
}
QObject* eventBridge = qmlContext->contextProperty("eventBridge").value<QObject*>(); QObject* eventBridge = qmlContext->contextProperty("eventBridge").value<QObject*>();
if (qmlContext != _qmlContext && eventBridge && eventBridge != this) { if (qmlContext != _qmlContext && eventBridge && eventBridge != this) {
@ -717,15 +729,6 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
qmlComponent->completeCreate(); qmlComponent->completeCreate();
qmlComponent->deleteLater(); qmlComponent->deleteLater();
// All quick items should be focusable
QQuickItem* newItem = qobject_cast<QQuickItem*>(newObject);
if (newItem) {
// Make sure we make items focusable (critical for
// supporting keyboard shortcuts)
newItem->setFlag(QQuickItem::ItemIsFocusScope, true);
}
// If we already have a root, just set a couple of flags and the ancestry // If we already have a root, just set a couple of flags and the ancestry
if (newItem && _rootItem) { if (newItem && _rootItem) {
// Allow child windows to be destroyed from JS // Allow child windows to be destroyed from JS
@ -748,6 +751,8 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
_rootItem = newItem; _rootItem = newItem;
_rootItem->setParentItem(_quickWindow->contentItem()); _rootItem->setParentItem(_quickWindow->contentItem());
_rootItem->setSize(_quickWindow->renderTargetSize()); _rootItem->setSize(_quickWindow->renderTargetSize());
// Call this callback after rootitem is set, otherwise VrMenu wont work
onQmlLoadedCallback(qmlContext, newObject);
} }
void OffscreenQmlSurface::updateQuick() { void OffscreenQmlSurface::updateQuick() {

View file

@ -50,11 +50,11 @@ public:
void resize(const QSize& size, bool forceResize = false); void resize(const QSize& size, bool forceResize = false);
QSize size() const; QSize size() const;
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {}); Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {}); Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
Q_INVOKABLE void load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {}); Q_INVOKABLE void load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
Q_INVOKABLE void load(const QString& qmlSourceFile, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {}) { Q_INVOKABLE void load(const QString& qmlSourceFile, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {}) {
return load(QUrl(qmlSourceFile), f); return load(QUrl(qmlSourceFile), onQmlLoadedCallback);
} }
void clearCache(); void clearCache();
void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; } void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; }
@ -120,7 +120,7 @@ protected:
private: private:
static QOpenGLContext* getSharedContext(); static QOpenGLContext* getSharedContext();
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, std::function<void(QQmlContext*, QObject*)> f); void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback);
QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject); QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject);
void setupFbo(); void setupFbo();
bool allowNewFrame(uint8_t fps); bool allowNewFrame(uint8_t fps);