diff --git a/src/scriptengines/qml/declarative/qmlobject.cpp b/src/scriptengines/qml/declarative/qmlobject.cpp index 3c1436fea..238989fbd 100644 --- a/src/scriptengines/qml/declarative/qmlobject.cpp +++ b/src/scriptengines/qml/declarative/qmlobject.cpp @@ -34,7 +34,6 @@ //#include "private/declarative/dataenginebindings_p.h" - class QmlObjectPrivate { public: @@ -66,6 +65,7 @@ public: QString qmlPath; QQmlEngine* engine; + QQmlIncubator incubator; QQmlComponent* component; QObject *root; bool delay : 1; @@ -127,6 +127,7 @@ QmlObject::QmlObject(QObject *parent) d(new QmlObjectPrivate(this)) { d->engine = new QQmlEngine(this); + d->engine->setIncubationController(new QmlObjectIncubationController(0)); //d->engine->setNetworkAccessManagerFactory(new PackageAccessManagerFactory()); } @@ -185,14 +186,14 @@ void QmlObject::completeInitialization() return; } - QQmlIncubator incubator; - d->component->create(incubator); + d->component->create(d->incubator); - while (!incubator.isReady() && incubator.status() != QQmlIncubator::Error) { + while (!d->incubator.isReady() && d->incubator.status() != QQmlIncubator::Error) { QCoreApplication::processEvents(QEventLoop::AllEvents, 50); } - d->root = incubator.object(); + d->root = d->incubator.object(); + //d->root = d->component->create(); if (!d->root) { d->errorPrint(); diff --git a/src/scriptengines/qml/declarative/qmlobject.h b/src/scriptengines/qml/declarative/qmlobject.h index 064a19294..67454126f 100644 --- a/src/scriptengines/qml/declarative/qmlobject.h +++ b/src/scriptengines/qml/declarative/qmlobject.h @@ -21,7 +21,12 @@ #define QMLOBJECT_H #include +#include +#include +#include +#include +#include class QQmlEngine; class QQmlComponent; @@ -29,6 +34,53 @@ class QQmlComponent; class QmlObjectPrivate; +class QmlObjectIncubationController : public QObject, public QQmlIncubationController +{ + Q_OBJECT + +public: + QmlObjectIncubationController(QObject *parent) + : QQmlIncubationController(), + QObject(parent) + { + // Allow incubation for 1/3 of a frame. + m_incubation_time = qMax(1, int(1000 / QGuiApplication::primaryScreen()->refreshRate()) / 3); + } + +protected: + virtual bool event(QEvent *e) + { + if (e->type() == QEvent::User) { + incubate(); + return true; + } + return QObject::event(e); + } + +public slots: + void incubate() + { + if (incubatingObjectCount()) { + 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) { + QCoreApplication::postEvent(this, new QEvent(QEvent::User)); + } + } +private: + int m_incubation_time; +}; + /** * @class QmlObject plasma/declarativewidget.h * diff --git a/src/scriptengines/qml/plasmoid/appletinterface.cpp b/src/scriptengines/qml/plasmoid/appletinterface.cpp index 7ef9e5f4c..721a7fe9e 100644 --- a/src/scriptengines/qml/plasmoid/appletinterface.cpp +++ b/src/scriptengines/qml/plasmoid/appletinterface.cpp @@ -68,6 +68,10 @@ AppletInterface::AppletInterface(DeclarativeAppletScript *script, QQuickItem *pa this, SIGNAL(locationChanged())); connect(m_appletScriptEngine, SIGNAL(contextChanged()), this, SIGNAL(contextChanged())); + + m_creationTimer = new QTimer(this); + m_creationTimer->setSingleShot(true); + connect(m_creationTimer, &QTimer::timeout, m_appletScriptEngine, &DeclarativeAppletScript::delayedInit); } AppletInterface::~AppletInterface() @@ -89,6 +93,9 @@ void AppletInterface::setUiObject(QObject *object) QQmlExpression expr(m_appletScriptEngine->engine()->rootContext(), object, "parent"); QQmlProperty prop(object, "anchors.fill"); prop.write(expr.evaluate()); + + geometryChanged(QRectF(), QRectF(x(), y(), width(), height())); + emit busyChanged(); } QObject *AppletInterface::uiObject() const @@ -138,7 +145,7 @@ void AppletInterface::setTitle(const QString &title) bool AppletInterface::isBusy() const { - return m_busy; + return !m_uiObject || m_busy; } void AppletInterface::setBusy(bool busy) @@ -505,4 +512,22 @@ void AppletInterface::geometryChanged(const QRectF &newGeometry, const QRectF &o } } +void AppletInterface::itemChange(ItemChange change, const ItemChangeData &value) +{ + if (change == QQuickItem::ItemSceneChange) { + //we have a window: create the + if (value.window && !m_uiObject && !m_creationTimer->isActive()) { + m_appletScriptEngine->delayedInit(); + + /*Experiment on even more delayed, doesn't seem to be good + QTime time = QTime::currentTime(); + qsrand((uint)time.msec()); + const int interval = qrand() % ((1000 + 1) - 50) + 50; + //QTimer::singleShot(interval, m_appletScriptEngine, SLOT(delayedInit())); + m_creationTimer->start(interval);*/ + } + } + QQuickItem::itemChange(change, value); +} + #include "moc_appletinterface.cpp" diff --git a/src/scriptengines/qml/plasmoid/appletinterface.h b/src/scriptengines/qml/plasmoid/appletinterface.h index c78c4aa11..ccaefb9d8 100644 --- a/src/scriptengines/qml/plasmoid/appletinterface.h +++ b/src/scriptengines/qml/plasmoid/appletinterface.h @@ -228,6 +228,7 @@ Q_SIGNALS: protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + void itemChange(ItemChange change, const ItemChangeData &value); DeclarativeAppletScript *m_appletScriptEngine; @@ -244,6 +245,8 @@ private: QWeakPointer m_uiObject; QWeakPointer m_compactUiObject; + QTimer *m_creationTimer; + Plasma::BackgroundHints m_backgroundHints; bool m_busy : 1; bool m_expanded : 1; diff --git a/src/scriptengines/qml/plasmoid/declarativeappletscript.cpp b/src/scriptengines/qml/plasmoid/declarativeappletscript.cpp index f45578e3a..c9d00ab58 100644 --- a/src/scriptengines/qml/plasmoid/declarativeappletscript.cpp +++ b/src/scriptengines/qml/plasmoid/declarativeappletscript.cpp @@ -98,7 +98,15 @@ bool DeclarativeAppletScript::init() connect(applet(), SIGNAL(activate()), this, SLOT(activate())); + //FIXME: everything should be delayed + if (pc) { + delayedInit(); + } + return true; +} +bool DeclarativeAppletScript::delayedInit() +{ m_qmlObject = new QmlObject(applet()); m_qmlObject->setInitializationDelayed(true); //FIXME: what replaced this? @@ -146,9 +154,10 @@ bool DeclarativeAppletScript::init() m_interface->setUiObject(m_qmlObject->rootObject()); - qDebug() << "Graphic object created:" << a << a->property("graphicObject"); + qDebug() << "Graphic object created:" << applet() << applet()->property("graphicObject"); //Create the ToolBox + Plasma::Containment *pc = qobject_cast(applet()); if (pc) { Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage("Plasma/Generic"); pkg.setPath("org.kde.toolbox"); @@ -175,7 +184,7 @@ bool DeclarativeAppletScript::init() } } - return !a->failedToLaunch(); + return !applet()->failedToLaunch(); } QString DeclarativeAppletScript::filePath(const QString &type, const QString &file) const diff --git a/src/scriptengines/qml/plasmoid/declarativeappletscript.h b/src/scriptengines/qml/plasmoid/declarativeappletscript.h index 5a2c0ed99..b4fa1adb5 100644 --- a/src/scriptengines/qml/plasmoid/declarativeappletscript.h +++ b/src/scriptengines/qml/plasmoid/declarativeappletscript.h @@ -56,6 +56,7 @@ public Q_SLOTS: void executeAction(const QString &name); void activate(); void configChanged(); + bool delayedInit(); protected: bool init(); diff --git a/src/shell/containments/testpanel/contents/ui/main.qml b/src/shell/containments/testpanel/contents/ui/main.qml index be36ebe34..6166387b1 100644 --- a/src/shell/containments/testpanel/contents/ui/main.qml +++ b/src/shell/containments/testpanel/contents/ui/main.qml @@ -21,7 +21,8 @@ import QtQuick 2.0 import org.kde.plasma.core 0.1 as PlasmaCore import org.kde.plasma.components 0.1 as PlasmaComponents -Row { + +Item { id: root width: 640 height: 48 @@ -31,13 +32,13 @@ Row { Connections { target: plasmoid onAppletAdded: { - var container = appletContainerComponent.createObject(root) - container.visible = true + var container = appletContainerComponent.createObject(row) print("Applet added in test panel: " + applet) applet.parent = container container.applet = applet - applet.anchors.fill= applet.parent + applet.anchors.fill = applet.parent applet.visible = true + container.visible = true } } @@ -45,12 +46,13 @@ Row { id: appletContainerComponent Item { id: container + visible: false anchors { top: parent.top bottom: parent.bottom } - width: height + width: height property Item applet @@ -64,8 +66,16 @@ Row { } } + Row { + id: row + anchors { + top: parent.top + bottom: parent.bottom + } + } + Component.onCompleted: { print("Test Panel loaded") print(plasmoid) } -} \ No newline at end of file +}