Merge branch 'mart/prettyStartupSequence'

Conflicts:
	src/scriptengines/qml/plasmoid/containmentinterface.cpp
This commit is contained in:
Marco Martin 2013-08-12 14:42:58 +02:00
commit 0978d2f73a
18 changed files with 138 additions and 48 deletions

View File

@ -434,6 +434,10 @@ void Applet::flushPendingConstraintsEvents()
Plasma::Types::Constraints c = d->pendingConstraints;
d->pendingConstraints = Types::NoConstraint;
if (c & Plasma::Types::UiReadyConstraint) {
d->setUiReady();
}
if (c & Plasma::Types::StartupCompletedConstraint) {
//common actions
bool unlocked = immutability() == Types::Mutable;

View File

@ -364,7 +364,7 @@ class PLASMA_EXPORT Applet : public QObject
* @since 4.4
*/
void statusChanged(Plasma::Types::ItemStatus status);
//CONFIGURATION
/**
* Emitted when an applet has changed values in its configuration
@ -375,7 +375,6 @@ class PLASMA_EXPORT Applet : public QObject
* applets.
*/
void configNeedsSaving();
//ACTIONS
/**

View File

@ -395,6 +395,14 @@ void Containment::addApplet(Applet *applet)
d->applets << applet;
if (!applet->d->uiReady) {
d->loadingApplets << applet;
if (static_cast<Applet *>(this)->d->uiReady) {
static_cast<Applet *>(this)->d->uiReady = false;
emit uiReadyChanged(false);
}
}
connect(applet, SIGNAL(configNeedsSaving()), this, SIGNAL(configNeedsSaving()));
connect(applet, SIGNAL(appletDeleted(Plasma::Applet*)), this, SLOT(appletDeleted(Plasma::Applet*)));
connect(applet, SIGNAL(statusChanged(Plasma::Types::ItemStatus)), this, SLOT(checkStatus(Plasma::Types::ItemStatus)));
@ -510,6 +518,11 @@ QHash<QString, ContainmentActions*> &Containment::containmentActions()
return d->localActionPlugins;
}
bool Containment::isUiReady() const
{
return static_cast<const Applet *>(this)->d->uiReady;
}
void Containment::setActivity(const QString &activityId)
{
if (activityId.isEmpty() || d->activityId == activityId) {

View File

@ -205,6 +205,11 @@ class PLASMA_EXPORT Containment : public Applet
QHash<QString, ContainmentActions*> &containmentActions();
/**
* @returns true when the ui of this containment is fully loaded, as well the ui of every applet in it
*/
bool isUiReady() const;
Q_SIGNALS:
/**
* This signal is emitted when a new applet is created by the containment
@ -262,6 +267,12 @@ Q_SIGNALS:
*/
void formFactorChanged(Plasma::Types::FormFactor formFactor);
/**
* Emitted when the ui has been fully loaded and is fully working
* @param uiReady true when the ui of the containment is ready, as well the ui of each applet in it
*/
void uiReadyChanged(bool uiReady);
public Q_SLOTS:
/**
* Informs the Corona as to what position it is in. This is informational

View File

@ -53,8 +53,9 @@ enum Constraint {
ImmutableConstraint = 8, /**< the immutability (locked) nature of the applet changed */
StartupCompletedConstraint = 16, /**< application startup has completed */
ContextConstraint = 32, /**< the context (e.g. activity) has changed */
UiReadyConstraint = 64, /** The ui has been completely loaded (FIXME: merged with StartupCompletedConstraint?) */
AllConstraints = FormFactorConstraint | LocationConstraint | ScreenConstraint |
ImmutableConstraint
ImmutableConstraint | UiReadyConstraint
};
Q_ENUMS(Constraint)
Q_DECLARE_FLAGS(Constraints, Constraint)

View File

@ -67,7 +67,8 @@ AppletPrivate::AppletPrivate(KService::Ptr service, const KPluginInfo *info, int
transient(false),
needsConfig(false),
started(false),
globalShortcutEnabled(false)
globalShortcutEnabled(false),
uiReady(false)
{
if (appletId == 0) {
appletId = ++s_maxAppletId;
@ -270,6 +271,29 @@ void AppletPrivate::propagateConfigChanged()
q->configChanged();
}
void AppletPrivate::setUiReady()
{
//am i the containment?
Containment *c = qobject_cast<Containment *>(q);
if (c) {
//if we are the containment and there is still some uncomplete applet, we're still incomplete
if (!c->d->loadingApplets.isEmpty()) {
return;
}
} else {
c = q->containment();
if (c) {
q->containment()->d->loadingApplets.remove(q);
if (q->containment()->d->loadingApplets.isEmpty() && !static_cast<Applet *>(q->containment())->d->uiReady) {
static_cast<Applet *>(q->containment())->d->uiReady = true;
emit q->containment()->uiReadyChanged(true);
}
}
}
uiReady = true;
}
void AppletPrivate::setIsContainment(bool nowIsContainment, bool forceUpdate)
{
if (isContainment == nowIsContainment && !forceUpdate) {

View File

@ -69,6 +69,7 @@ public:
void updateShortcuts();
void globalShortcutChanged();
void propagateConfigChanged();
void setUiReady();
static KActionCollection* defaultActions(QObject *parent);
@ -114,6 +115,7 @@ public:
bool needsConfig : 1;
bool started : 1;
bool globalShortcutEnabled : 1;
bool uiReady : 1;
};
} // Plasma namespace

View File

@ -22,6 +22,7 @@
#define CONTAINMENT_P_H
#include <kactioncollection.h>
#include <QSet>
#include "plasma.h"
#include "applet.h"
@ -97,6 +98,8 @@ public:
Types::FormFactor formFactor;
Types::Location location;
QList<Applet *> applets;
//Applets still considered not ready
QSet <Applet *> loadingApplets;
QString wallpaper;
QHash<QString, ContainmentActions*> localActionPlugins;
int screen;

View File

@ -157,6 +157,11 @@ Q_SIGNALS:
*/
void saveState(KConfigGroup &group) const;
/**
* @param uiReady true if the UI for this applet is ready
*/
void uiReadyChanged(bool uiReady);
public Q_SLOTS:
/**

View File

@ -81,10 +81,6 @@ AppletInterface::AppletInterface(DeclarativeAppletScript *script, QQuickItem *pa
m_qmlObject = new QmlObject(this);
m_qmlObject->setInitializationDelayed(true);
m_creationTimer = new QTimer(this);
m_creationTimer->setSingleShot(true);
connect(m_creationTimer, &QTimer::timeout, this, &AppletInterface::init);
m_collapseTimer = new QTimer(this);
m_collapseTimer->setSingleShot(true);
connect(m_collapseTimer, &QTimer::timeout, this, &AppletInterface::compactRepresentationCheck);
@ -185,7 +181,8 @@ void AppletInterface::init()
}
geometryChanged(QRectF(), QRectF(x(), y(), width(), height()));
emit busyChanged();
m_appletScriptEngine->setUiReady(true);
applet()->updateConstraints(Plasma::Types::UiReadyConstraint);
}
Plasma::Types::FormFactor AppletInterface::formFactor() const
@ -732,15 +729,8 @@ void AppletInterface::itemChange(ItemChange change, const ItemChangeData &value)
{
if (change == QQuickItem::ItemSceneChange) {
//we have a window: create the
if (value.window && !m_qmlObject->rootObject() && !m_creationTimer->isActive()) {
if (value.window && !m_qmlObject->rootObject()) {
init();
/*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);

View File

@ -207,12 +207,12 @@ private:
QmlObject *m_qmlObject;
QWeakPointer<QObject> m_compactUiObject;
QTimer *m_creationTimer;
QTimer *m_collapseTimer;
Plasma::Types::BackgroundHints m_backgroundHints;
bool m_busy : 1;
bool m_expanded : 1;
friend class ContainmentInterface;
};
#endif

View File

@ -67,6 +67,21 @@ ContainmentInterface::ContainmentInterface(DeclarativeAppletScript *parent)
void ContainmentInterface::init()
{
AppletInterface::init();
foreach (QObject *appletObj, m_appletInterfaces) {
AppletInterface *applet = qobject_cast<AppletInterface *>(appletObj);
if (applet) {
if (!applet->qmlObject()) {
applet->init();
}
m_appletInterfaces << applet;
emit appletAdded(applet);
}
}
if (!m_appletInterfaces.isEmpty()) {
emit appletsChanged();
}
}
QList <QObject *> ContainmentInterface::applets()
@ -131,17 +146,22 @@ QVariantList ContainmentInterface::availableScreenRegion(int id) const
void ContainmentInterface::appletAddedForward(Plasma::Applet *applet)
{
if (!applet) {
return;
}
QObject *appletGraphicObject = applet->property("graphicObject").value<QObject *>();
QObject *contGraphicObject = containment()->property("graphicObject").value<QObject *>();
qDebug() << "Applet added:" << applet << applet->title() << appletGraphicObject;
qDebug() << "Applet added on containment:" << containment()->title() << contGraphicObject
<< "Applet: " << applet << applet->title() << appletGraphicObject;
if (applet && contGraphicObject && appletGraphicObject) {
if (contGraphicObject && appletGraphicObject) {
appletGraphicObject->setProperty("visible", false);
appletGraphicObject->setProperty("parent", QVariant::fromValue(contGraphicObject));
//if an appletGraphicObject is not set, we have to display some error message
} else if (applet && contGraphicObject) {
} else if (contGraphicObject) {
QObject *errorUi = qmlObject()->createObjectFromSource(QUrl::fromLocalFile(containment()->corona()->package().filePath("appleterror")));
if (errorUi) {

View File

@ -56,8 +56,7 @@ K_EXPORT_PLASMA_APPLETSCRIPTENGINE(declarativeappletscript, DeclarativeAppletScr
DeclarativeAppletScript::DeclarativeAppletScript(QObject *parent, const QVariantList &args)
: Plasma::AppletScript(parent),
m_interface(0),
m_uiReady(false)
m_interface(0)
{
qmlRegisterType<AppletInterface>();
qmlRegisterType<ConfigPropertyMap>();
@ -115,21 +114,6 @@ void DeclarativeAppletScript::constraintsEvent(Plasma::Types::Constraints constr
}
}
void DeclarativeAppletScript::setUiReady(bool ready)
{
if (m_uiReady == ready) {
return;
}
m_uiReady = ready;
emit uiReadyChanged(ready);
}
bool DeclarativeAppletScript::isUiReady() const
{
return m_uiReady;
}
void DeclarativeAppletScript::activate()
{
#if 0

View File

@ -24,6 +24,7 @@
#include <kdemacros.h>
#include <QQmlEngine>
#include <QSet>
#include <Plasma/AppletScript>
@ -45,9 +46,6 @@ public:
void constraintsEvent(Plasma::Types::Constraints constraints);
void setUiReady(bool ready);
bool isUiReady() const;
public Q_SLOTS:
void executeAction(const QString &name);
void activate();
@ -63,8 +61,8 @@ Q_SIGNALS:
private:
AppletInterface *m_interface;
bool m_uiReady;
friend class AppletInterface;
friend class ContainmentInterface;
};

View File

@ -50,7 +50,6 @@ DesktopCorona::DesktopCorona(QObject *parent)
connect(m_appConfigSyncTimer, &QTimer::timeout,
this, &DesktopCorona::syncAppConfig);
connect(m_desktopWidget, SIGNAL(resized(int)),
this, SLOT(screenResized(int)));
connect(m_desktopWidget, SIGNAL(screenCountChanged(int)),
@ -252,6 +251,25 @@ void DesktopCorona::checkViews()
}
}
void DesktopCorona::checkLoadingDesktopsComplete()
{
Plasma::Containment *c = qobject_cast<Plasma::Containment *>(sender());
if (c) {
disconnect(c, &Plasma::Containment::uiReadyChanged,
this, &DesktopCorona::checkLoadingDesktopsComplete);
m_loadingDesktops.remove(c);
}
if (m_loadingDesktops.isEmpty()) {
foreach (Plasma::Containment *cont, m_waitingPanels) {
m_panelViews[cont] = new PanelView(this);
m_panelViews[cont]->setContainment(cont);
}
m_waitingPanels.clear();
}
}
void DesktopCorona::updateScreenOwner(int wasScreen, int isScreen, Plasma::Containment *containment)
{
qDebug() << "Was screen" << wasScreen << "Is screen" << isScreen <<"Containment" << containment << containment->title();
@ -260,9 +278,7 @@ void DesktopCorona::updateScreenOwner(int wasScreen, int isScreen, Plasma::Conta
containment->formFactor() == Plasma::Types::Vertical) {
if (isScreen >= 0) {
m_panelViews[containment] = new PanelView(this);
m_panelViews[containment]->setContainment(containment);
m_panelViews[containment]->show();
m_waitingPanels << containment;
} else {
if (m_panelViews.contains(containment)) {
m_panelViews[containment]->setContainment(0);
@ -270,10 +286,18 @@ void DesktopCorona::updateScreenOwner(int wasScreen, int isScreen, Plasma::Conta
m_panelViews.remove(containment);
}
}
//Desktop view
} else {
if (containment->isUiReady()) {
checkLoadingDesktopsComplete();
} else {
m_loadingDesktops.insert(containment);
connect(containment, &Plasma::Containment::uiReadyChanged,
this, &DesktopCorona::checkLoadingDesktopsComplete);
}
if (isScreen < 0 || m_views.count() < isScreen + 1) {
qWarning() << "Invalid screen";
return;

View File

@ -99,11 +99,14 @@ private Q_SLOTS:
void handleContainmentAdded(Plasma::Containment *c);
void showWidgetExplorer();
void syncAppConfig();
void checkLoadingDesktopsComplete();
private:
QDesktopWidget *m_desktopWidget;
QList <View *> m_views;
WidgetExplorerView *m_widgetExplorerView;
QList<Plasma::Containment *> m_waitingPanels;
QSet<Plasma::Containment *> m_loadingDesktops;
QHash<Plasma::Containment *, PanelView *> m_panelViews;
KConfigGroup m_desktopDefaultsConfig;
QTimer *m_appConfigSyncTimer;

View File

@ -47,6 +47,7 @@ PanelView::PanelView(DesktopCorona *corona, QWindow *parent)
setColor(QColor(Qt::transparent));
setFlags(Qt::FramelessWindowHint);
KWindowSystem::setType(winId(), NET::Dock);
setVisible(false);
//TODO: how to take the shape from the framesvg?
KWindowEffects::enableBlurBehind(winId(), true);
@ -326,6 +327,10 @@ void PanelView::restore()
return;
}
setVisible(containment()->isUiReady());
connect(containment(), &Plasma::Containment::uiReadyChanged,
this, &PanelView::setVisible);
static const int MINSIZE = 10;
m_offset = config().readEntry<int>("offset", 0);

View File

@ -73,6 +73,10 @@ KConfigGroup View::config() const
void View::setContainment(Plasma::Containment *cont)
{
if (m_containment.data() == cont) {
return;
}
Plasma::Types::Location oldLoc = (Plasma::Types::Location)location();
Plasma::Types::FormFactor oldForm = formFactor();