mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-05 04:51:31 +02:00
Working on QML whitelist functionality
This commit is contained in:
parent
a5caae3739
commit
ffc51d5387
7 changed files with 113 additions and 62 deletions
18
interface/resources/qml/OverlayWindowTest.qml
Normal file
18
interface/resources/qml/OverlayWindowTest.qml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 100
|
||||||
|
height: 100
|
||||||
|
color: "white"
|
||||||
|
Rectangle {
|
||||||
|
width: 10
|
||||||
|
height: 10
|
||||||
|
color: "red"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: OverlayWindowTestString
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ Windows.Window {
|
||||||
// Don't destroy on close... otherwise the JS/C++ will have a dangling pointer
|
// Don't destroy on close... otherwise the JS/C++ will have a dangling pointer
|
||||||
destroyOnCloseButton: false
|
destroyOnCloseButton: false
|
||||||
property var source;
|
property var source;
|
||||||
property var component;
|
|
||||||
property var dynamicContent;
|
property var dynamicContent;
|
||||||
|
|
||||||
// Keyboard control properties in case needed by QML content.
|
// Keyboard control properties in case needed by QML content.
|
||||||
|
@ -35,28 +34,13 @@ Windows.Window {
|
||||||
dynamicContent.destroy();
|
dynamicContent.destroy();
|
||||||
dynamicContent = null;
|
dynamicContent = null;
|
||||||
}
|
}
|
||||||
component = Qt.createComponent(source);
|
console.log("QQQ Foo");
|
||||||
console.log("Created component " + component + " from source " + source);
|
QmlSurface.createContentFromQml(source, contentHolder, function(newObject) {
|
||||||
}
|
console.log("QQQ Bar " + dynamicContent);
|
||||||
|
dynamicContent = newObject;
|
||||||
onComponentChanged: {
|
dynamicContent.visible = true;
|
||||||
console.log("Component changed to " + component)
|
});
|
||||||
populate();
|
console.log("QQQ Baz");
|
||||||
}
|
|
||||||
|
|
||||||
function populate() {
|
|
||||||
console.log("Populate called: dynamicContent " + dynamicContent + " component " + component);
|
|
||||||
if (!dynamicContent && component) {
|
|
||||||
if (component.status == Component.Error) {
|
|
||||||
console.log("Error loading component:", component.errorString());
|
|
||||||
} else if (component.status == Component.Ready) {
|
|
||||||
console.log("Building dynamic content");
|
|
||||||
dynamicContent = component.createObject(contentHolder);
|
|
||||||
} else {
|
|
||||||
console.log("Component not yet ready, connecting to status change");
|
|
||||||
component.statusChanged.connect(populate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle message traffic from the script that launched us to the loaded QML
|
// Handle message traffic from the script that launched us to the loaded QML
|
||||||
|
|
|
@ -2240,6 +2240,12 @@ extern void setupPreferences();
|
||||||
void Application::initializeUi() {
|
void Application::initializeUi() {
|
||||||
// Make sure all QML surfaces share the main thread GL context
|
// Make sure all QML surfaces share the main thread GL context
|
||||||
OffscreenQmlSurface::setSharedContext(_offscreenContext->getContext());
|
OffscreenQmlSurface::setSharedContext(_offscreenContext->getContext());
|
||||||
|
OffscreenQmlSurface::addWhitelistContextHandler(QUrl{ "qrc:///qml/OverlayWindowTest.qml" },
|
||||||
|
[](QQmlContext* context) {
|
||||||
|
qDebug() << "Whitelist OverlayWindow worked";
|
||||||
|
context->setContextProperty("OverlayWindowTestString", "TestWorked");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
AddressBarDialog::registerType();
|
AddressBarDialog::registerType();
|
||||||
ErrorDialog::registerType();
|
ErrorDialog::registerType();
|
||||||
|
|
|
@ -62,7 +62,7 @@ QVariantMap QmlWindowClass::parseArguments(QScriptContext* context) {
|
||||||
|
|
||||||
QUrl url { properties[SOURCE_PROPERTY].toString() };
|
QUrl url { properties[SOURCE_PROPERTY].toString() };
|
||||||
if (url.scheme() != "http" && url.scheme() != "https" && url.scheme() != "file" && url.scheme() != "about" &&
|
if (url.scheme() != "http" && url.scheme() != "https" && url.scheme() != "file" && url.scheme() != "about" &&
|
||||||
url.scheme() != "atp") {
|
url.scheme() != "atp" && url.scheme() != "qrc") {
|
||||||
properties[SOURCE_PROPERTY] = QUrl::fromLocalFile(url.toString()).toString();
|
properties[SOURCE_PROPERTY] = QUrl::fromLocalFile(url.toString()).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,11 +64,19 @@ public:
|
||||||
for (const auto& url : urls) {
|
for (const auto& url : urls) {
|
||||||
_callbacks[url].push_back(callback);
|
_callbacks[url].push_back(callback);
|
||||||
}
|
}
|
||||||
|
for (const auto& url : _callbacks.keys()) {
|
||||||
|
qDebug() << "URL found for " << url << " with " << _callbacks[url].size() << " items";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QmlContextCallback> getCallbacksForUrl(const QUrl& url) const {
|
QList<QmlContextCallback> getCallbacksForUrl(const QUrl& url) const {
|
||||||
|
qDebug() << "Looking for callbacks for " << url;
|
||||||
|
|
||||||
return resultWithReadLock<QList<QmlContextCallback>>([&] {
|
return resultWithReadLock<QList<QmlContextCallback>>([&] {
|
||||||
|
for (const auto& url : _callbacks.keys()) {
|
||||||
|
qDebug() << "URL found for " << url << " with " << _callbacks[url].size() << " items";
|
||||||
|
}
|
||||||
QList<QmlContextCallback> result;
|
QList<QmlContextCallback> result;
|
||||||
auto itr = _callbacks.find(url);
|
auto itr = _callbacks.find(url);
|
||||||
if (_callbacks.end() != itr) {
|
if (_callbacks.end() != itr) {
|
||||||
|
@ -98,7 +106,7 @@ void OffscreenQmlSurface::addWhitelistContextHandler(const std::initializer_list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QmlContextObjectCallback OffscreenQmlSurface::DEFAULT_CONTEXT_CALLBACK = [](QQmlContext*, QObject*) {};
|
QmlContextObjectCallback OffscreenQmlSurface::DEFAULT_CONTEXT_CALLBACK = [](QQmlContext*, QQuickItem*) {};
|
||||||
|
|
||||||
struct TextureSet {
|
struct TextureSet {
|
||||||
// The number of surfaces with this size
|
// The number of surfaces with this size
|
||||||
|
@ -590,6 +598,7 @@ void OffscreenQmlSurface::create() {
|
||||||
_qmlContext->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
|
_qmlContext->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
|
||||||
_qmlContext->setContextProperty("eventBridge", this);
|
_qmlContext->setContextProperty("eventBridge", this);
|
||||||
_qmlContext->setContextProperty("webEntity", this);
|
_qmlContext->setContextProperty("webEntity", this);
|
||||||
|
_qmlContext->setContextProperty("QmlSurface", this);
|
||||||
|
|
||||||
// FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper
|
// FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper
|
||||||
// Find a way to flag older scripts using this mechanism and wanr that this is deprecated
|
// Find a way to flag older scripts using this mechanism and wanr that this is deprecated
|
||||||
|
@ -688,20 +697,14 @@ void OffscreenQmlSurface::setBaseUrl(const QUrl& baseUrl) {
|
||||||
_qmlContext->setBaseUrl(baseUrl);
|
_qmlContext->setBaseUrl(baseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
QQmlContext* OffscreenQmlSurface::contextForUrl(const QUrl& qmlSource, bool forceNewContext) {
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
qCWarning(uiLogging) << "Called load on a non-surface thread";
|
|
||||||
}
|
|
||||||
// Synchronous loading may take a while; restart the deadlock timer
|
|
||||||
QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection);
|
|
||||||
|
|
||||||
// Get any whitelist functionality
|
// Get any whitelist functionality
|
||||||
QList<QmlContextCallback> callbacks = getQmlWhitelist()->getCallbacksForUrl(qmlSource);
|
QList<QmlContextCallback> callbacks = getQmlWhitelist()->getCallbacksForUrl(qmlSource);
|
||||||
// If we have whitelisted content, we must load a new context
|
// If we have whitelisted content, we must load a new context
|
||||||
createNewContext |= !callbacks.empty();
|
forceNewContext |= !callbacks.empty();
|
||||||
|
|
||||||
QQmlContext* targetContext = _qmlContext;
|
QQmlContext* targetContext = _qmlContext;
|
||||||
if (_rootItem && createNewContext) {
|
if (_rootItem && forceNewContext) {
|
||||||
targetContext = new QQmlContext(targetContext);
|
targetContext = new QQmlContext(targetContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,6 +712,15 @@ void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, con
|
||||||
callback(targetContext);
|
callback(targetContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return targetContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
qCWarning(uiLogging) << "Called load on a non-surface thread";
|
||||||
|
}
|
||||||
|
// Synchronous loading may take a while; restart the deadlock timer
|
||||||
|
QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection);
|
||||||
|
|
||||||
// FIXME eliminate loading of relative file paths for QML
|
// FIXME eliminate loading of relative file paths for QML
|
||||||
QUrl finalQmlSource = qmlSource;
|
QUrl finalQmlSource = qmlSource;
|
||||||
|
@ -716,17 +728,36 @@ void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, con
|
||||||
finalQmlSource = _qmlContext->resolvedUrl(qmlSource);
|
finalQmlSource = _qmlContext->resolvedUrl(qmlSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto targetContext = contextForUrl(finalQmlSource);
|
||||||
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, [=](QQmlComponent::Status) {
|
connect(qmlComponent, &QQmlComponent::statusChanged, this, [=](QQmlComponent::Status) {
|
||||||
finishQmlLoad(qmlComponent, targetContext, onQmlLoadedCallback);
|
finishQmlLoad(qmlComponent, targetContext, nullptr, onQmlLoadedCallback);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
finishQmlLoad(qmlComponent, targetContext, onQmlLoadedCallback);
|
finishQmlLoad(qmlComponent, targetContext, nullptr, onQmlLoadedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::createContentFromQml(const QUrl& qmlSource, QQuickItem* parent, const QJSValue& callback) {
|
||||||
|
auto targetContext = contextForUrl(qmlSource);
|
||||||
|
|
||||||
|
auto onQmlLoadedCallback = [=](QQmlContext*, QObject* newItem) {
|
||||||
|
QJSValue(callback).call(QJSValueList() << _qmlContext->engine()->newQObject(newItem));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto qmlComponent = new QQmlComponent(_qmlContext->engine(), qmlSource, QQmlComponent::PreferSynchronous);
|
||||||
|
if (qmlComponent->isLoading()) {
|
||||||
|
connect(qmlComponent, &QQmlComponent::statusChanged, this, [=](QQmlComponent::Status) {
|
||||||
|
finishQmlLoad(qmlComponent, targetContext, parent, onQmlLoadedCallback);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finishQmlLoad(qmlComponent, targetContext, parent, onQmlLoadedCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
||||||
load(qmlSource, true, onQmlLoadedCallback);
|
load(qmlSource, true, onQmlLoadedCallback);
|
||||||
}
|
}
|
||||||
|
@ -743,7 +774,8 @@ void OffscreenQmlSurface::clearCache() {
|
||||||
_qmlContext->engine()->clearComponentCache();
|
_qmlContext->engine()->clearComponentCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, const QmlContextObjectCallback& callback) {
|
|
||||||
|
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, QQuickItem* parent, const QmlContextObjectCallback& callback) {
|
||||||
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()) {
|
||||||
|
@ -765,6 +797,22 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!newObject) {
|
||||||
|
if (!_rootItem) {
|
||||||
|
qFatal("Could not load object as root item");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qCWarning(uiLogging) << "Unable to load QML item";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject* eventBridge = qmlContext->contextProperty("eventBridge").value<QObject*>();
|
||||||
|
if (qmlContext != _qmlContext && eventBridge && eventBridge != this) {
|
||||||
|
// FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper
|
||||||
|
// Find a way to flag older scripts using this mechanism and wanr that this is deprecated
|
||||||
|
qmlContext->setContextProperty("eventBridgeWrapper", new EventBridgeWrapper(eventBridge, qmlContext));
|
||||||
|
}
|
||||||
|
|
||||||
qmlContext->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
qmlContext->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
|
|
||||||
// All quick items should be focusable
|
// All quick items should be focusable
|
||||||
|
@ -775,35 +823,26 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
|
||||||
newItem->setFlag(QQuickItem::ItemIsFocusScope, true);
|
newItem->setFlag(QQuickItem::ItemIsFocusScope, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Make sure we will call callback for this codepath
|
// Make sure we will call callback for this codepath
|
||||||
// Call this before qmlComponent->completeCreate() otherwise ghost window appears
|
// Call this before qmlComponent->completeCreate() otherwise ghost window appears
|
||||||
if (newItem && _rootItem) {
|
// If we already have a root, just set a couple of flags and the ancestry
|
||||||
callback(qmlContext, newObject);
|
if (_rootItem) {
|
||||||
}
|
callback(qmlContext, newItem);
|
||||||
|
|
||||||
QObject* eventBridge = qmlContext->contextProperty("eventBridge").value<QObject*>();
|
if (!parent) {
|
||||||
if (qmlContext != _qmlContext && eventBridge && eventBridge != this) {
|
parent = _rootItem;
|
||||||
// FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper
|
}
|
||||||
// Find a way to flag older scripts using this mechanism and wanr that this is deprecated
|
// Allow child windows to be destroyed from JS
|
||||||
qmlContext->setContextProperty("eventBridgeWrapper", new EventBridgeWrapper(eventBridge, qmlContext));
|
QQmlEngine::setObjectOwnership(newObject, QQmlEngine::JavaScriptOwnership);
|
||||||
|
newObject->setParent(parent);
|
||||||
|
newItem->setParentItem(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
qmlComponent->completeCreate();
|
qmlComponent->completeCreate();
|
||||||
qmlComponent->deleteLater();
|
qmlComponent->deleteLater();
|
||||||
|
|
||||||
// If we already have a root, just set a couple of flags and the ancestry
|
if (_rootItem) {
|
||||||
if (newItem && _rootItem) {
|
|
||||||
// Allow child windows to be destroyed from JS
|
|
||||||
QQmlEngine::setObjectOwnership(newObject, QQmlEngine::JavaScriptOwnership);
|
|
||||||
newObject->setParent(_rootItem);
|
|
||||||
if (newItem) {
|
|
||||||
newItem->setParentItem(_rootItem);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!newItem) {
|
|
||||||
qFatal("Could not load object as root item");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,7 +854,7 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
|
||||||
_rootItem->setSize(_quickWindow->renderTargetSize());
|
_rootItem->setSize(_quickWindow->renderTargetSize());
|
||||||
|
|
||||||
// Call this callback after rootitem is set, otherwise VrMenu wont work
|
// Call this callback after rootitem is set, otherwise VrMenu wont work
|
||||||
callback(qmlContext, newObject);
|
callback(qmlContext, newItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::updateQuick() {
|
void OffscreenQmlSurface::updateQuick() {
|
||||||
|
|
|
@ -30,13 +30,14 @@ class QQmlContext;
|
||||||
class QQmlComponent;
|
class QQmlComponent;
|
||||||
class QQuickWindow;
|
class QQuickWindow;
|
||||||
class QQuickItem;
|
class QQuickItem;
|
||||||
|
class QJSValue;
|
||||||
|
|
||||||
// GPU resources are typically buffered for one copy being used by the renderer,
|
// GPU resources are typically buffered for one copy being used by the renderer,
|
||||||
// one copy in flight, and one copy being used by the receiver
|
// one copy in flight, and one copy being used by the receiver
|
||||||
#define GPU_RESOURCE_BUFFER_SIZE 3
|
#define GPU_RESOURCE_BUFFER_SIZE 3
|
||||||
|
|
||||||
using QmlContextCallback = std::function<void(QQmlContext*)>;
|
using QmlContextCallback = std::function<void(QQmlContext*)>;
|
||||||
using QmlContextObjectCallback = std::function<void(QQmlContext*, QObject*)>;
|
using QmlContextObjectCallback = std::function<void(QQmlContext*, QQuickItem*)>;
|
||||||
|
|
||||||
class OffscreenQmlSurface : public QObject {
|
class OffscreenQmlSurface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -57,6 +58,8 @@ 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 createContentFromQml(const QUrl& qmlSource, QQuickItem* parent, const QJSValue& callback);
|
||||||
|
|
||||||
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||||
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||||
Q_INVOKABLE void load(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
Q_INVOKABLE void load(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||||
|
@ -123,9 +126,10 @@ protected:
|
||||||
void setFocusText(bool newFocusText);
|
void setFocusText(bool newFocusText);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QQmlContext* contextForUrl(const QUrl& url, bool forceNewContext = false);
|
||||||
static QOpenGLContext* getSharedContext();
|
static QOpenGLContext* getSharedContext();
|
||||||
|
|
||||||
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, const QmlContextObjectCallback& callbacks);
|
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, QQuickItem* parent, const QmlContextObjectCallback& callbacks);
|
||||||
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);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
print("Launching web window");
|
print("Launching web window");
|
||||||
qmlWindow = new OverlayWindow({
|
qmlWindow = new OverlayWindow({
|
||||||
title: 'Test Qml',
|
title: 'Test Qml',
|
||||||
source: "https://s3.amazonaws.com/DreamingContent/qml/content.qml",
|
source: "qrc:///qml/OverlayWindowTest.qml",
|
||||||
height: 240,
|
height: 240,
|
||||||
width: 320,
|
width: 320,
|
||||||
toolWindow: false,
|
toolWindow: false,
|
||||||
|
|
Loading…
Reference in a new issue