start to delay a bit objects creation.

use a component incubator to create objects whuile the event loop is running

load applets ui only when they get a view

it will have to be cleaned out a lot, by moving the loading logic into AppletInterface
This commit is contained in:
Marco Martin 2013-02-19 17:27:04 +01:00
parent f4f22df3a3
commit 26b5b98e0a
7 changed files with 115 additions and 14 deletions

View File

@ -34,7 +34,6 @@
//#include "private/declarative/dataenginebindings_p.h" //#include "private/declarative/dataenginebindings_p.h"
class QmlObjectPrivate class QmlObjectPrivate
{ {
public: public:
@ -66,6 +65,7 @@ public:
QString qmlPath; QString qmlPath;
QQmlEngine* engine; QQmlEngine* engine;
QQmlIncubator incubator;
QQmlComponent* component; QQmlComponent* component;
QObject *root; QObject *root;
bool delay : 1; bool delay : 1;
@ -127,6 +127,7 @@ QmlObject::QmlObject(QObject *parent)
d(new QmlObjectPrivate(this)) d(new QmlObjectPrivate(this))
{ {
d->engine = new QQmlEngine(this); d->engine = new QQmlEngine(this);
d->engine->setIncubationController(new QmlObjectIncubationController(0));
//d->engine->setNetworkAccessManagerFactory(new PackageAccessManagerFactory()); //d->engine->setNetworkAccessManagerFactory(new PackageAccessManagerFactory());
} }
@ -185,14 +186,14 @@ void QmlObject::completeInitialization()
return; return;
} }
QQmlIncubator incubator; d->component->create(d->incubator);
d->component->create(incubator);
while (!incubator.isReady() && incubator.status() != QQmlIncubator::Error) { while (!d->incubator.isReady() && d->incubator.status() != QQmlIncubator::Error) {
QCoreApplication::processEvents(QEventLoop::AllEvents, 50); QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
} }
d->root = incubator.object(); d->root = d->incubator.object();
//d->root = d->component->create();
if (!d->root) { if (!d->root) {
d->errorPrint(); d->errorPrint();

View File

@ -21,7 +21,12 @@
#define QMLOBJECT_H #define QMLOBJECT_H
#include <QObject> #include <QObject>
#include <QQmlIncubationController>
#include <QWindow>
#include <QAnimationDriver>
#include <QGuiApplication>
#include <QScreen>
class QQmlEngine; class QQmlEngine;
class QQmlComponent; class QQmlComponent;
@ -29,6 +34,53 @@ class QQmlComponent;
class QmlObjectPrivate; 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 <Plasma/QmlObject> * @class QmlObject plasma/declarativewidget.h <Plasma/QmlObject>
* *

View File

@ -68,6 +68,10 @@ AppletInterface::AppletInterface(DeclarativeAppletScript *script, QQuickItem *pa
this, SIGNAL(locationChanged())); this, SIGNAL(locationChanged()));
connect(m_appletScriptEngine, SIGNAL(contextChanged()), connect(m_appletScriptEngine, SIGNAL(contextChanged()),
this, 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() AppletInterface::~AppletInterface()
@ -89,6 +93,9 @@ void AppletInterface::setUiObject(QObject *object)
QQmlExpression expr(m_appletScriptEngine->engine()->rootContext(), object, "parent"); QQmlExpression expr(m_appletScriptEngine->engine()->rootContext(), object, "parent");
QQmlProperty prop(object, "anchors.fill"); QQmlProperty prop(object, "anchors.fill");
prop.write(expr.evaluate()); prop.write(expr.evaluate());
geometryChanged(QRectF(), QRectF(x(), y(), width(), height()));
emit busyChanged();
} }
QObject *AppletInterface::uiObject() const QObject *AppletInterface::uiObject() const
@ -138,7 +145,7 @@ void AppletInterface::setTitle(const QString &title)
bool AppletInterface::isBusy() const bool AppletInterface::isBusy() const
{ {
return m_busy; return !m_uiObject || m_busy;
} }
void AppletInterface::setBusy(bool 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" #include "moc_appletinterface.cpp"

View File

@ -228,6 +228,7 @@ Q_SIGNALS:
protected: protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
void itemChange(ItemChange change, const ItemChangeData &value);
DeclarativeAppletScript *m_appletScriptEngine; DeclarativeAppletScript *m_appletScriptEngine;
@ -244,6 +245,8 @@ private:
QWeakPointer<QObject> m_uiObject; QWeakPointer<QObject> m_uiObject;
QWeakPointer<QObject> m_compactUiObject; QWeakPointer<QObject> m_compactUiObject;
QTimer *m_creationTimer;
Plasma::BackgroundHints m_backgroundHints; Plasma::BackgroundHints m_backgroundHints;
bool m_busy : 1; bool m_busy : 1;
bool m_expanded : 1; bool m_expanded : 1;

View File

@ -98,7 +98,15 @@ bool DeclarativeAppletScript::init()
connect(applet(), SIGNAL(activate()), connect(applet(), SIGNAL(activate()),
this, SLOT(activate())); this, SLOT(activate()));
//FIXME: everything should be delayed
if (pc) {
delayedInit();
}
return true;
}
bool DeclarativeAppletScript::delayedInit()
{
m_qmlObject = new QmlObject(applet()); m_qmlObject = new QmlObject(applet());
m_qmlObject->setInitializationDelayed(true); m_qmlObject->setInitializationDelayed(true);
//FIXME: what replaced this? //FIXME: what replaced this?
@ -146,9 +154,10 @@ bool DeclarativeAppletScript::init()
m_interface->setUiObject(m_qmlObject->rootObject()); 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 //Create the ToolBox
Plasma::Containment *pc = qobject_cast<Plasma::Containment *>(applet());
if (pc) { if (pc) {
Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage("Plasma/Generic"); Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage("Plasma/Generic");
pkg.setPath("org.kde.toolbox"); 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 QString DeclarativeAppletScript::filePath(const QString &type, const QString &file) const

View File

@ -56,6 +56,7 @@ public Q_SLOTS:
void executeAction(const QString &name); void executeAction(const QString &name);
void activate(); void activate();
void configChanged(); void configChanged();
bool delayedInit();
protected: protected:
bool init(); bool init();

View File

@ -21,7 +21,8 @@ import QtQuick 2.0
import org.kde.plasma.core 0.1 as PlasmaCore import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.components 0.1 as PlasmaComponents import org.kde.plasma.components 0.1 as PlasmaComponents
Row {
Item {
id: root id: root
width: 640 width: 640
height: 48 height: 48
@ -31,13 +32,13 @@ Row {
Connections { Connections {
target: plasmoid target: plasmoid
onAppletAdded: { onAppletAdded: {
var container = appletContainerComponent.createObject(root) var container = appletContainerComponent.createObject(row)
container.visible = true
print("Applet added in test panel: " + applet) print("Applet added in test panel: " + applet)
applet.parent = container applet.parent = container
container.applet = applet container.applet = applet
applet.anchors.fill = applet.parent applet.anchors.fill = applet.parent
applet.visible = true applet.visible = true
container.visible = true
} }
} }
@ -45,6 +46,7 @@ Row {
id: appletContainerComponent id: appletContainerComponent
Item { Item {
id: container id: container
visible: false
anchors { anchors {
top: parent.top top: parent.top
@ -64,6 +66,14 @@ Row {
} }
} }
Row {
id: row
anchors {
top: parent.top
bottom: parent.bottom
}
}
Component.onCompleted: { Component.onCompleted: {
print("Test Panel loaded") print("Test Panel loaded")
print(plasmoid) print(plasmoid)