We've had several issues with applets having constraintsEvent() called before 
init() has been called at Plasma startup.

As far as I can ascertain, this is because control is being passed to an event 
loop in Corona::LoadLayout between the call to Containment::restore(), which 
creates the applets, and init() being called on the applets.  This causes a 
timeout on a timer attached to Applet that calls flushPendingContraints(), 
which in turn calls constraintsEvent().

There are two solutions I can see to this: either we tell applet developers 
that they can't count on init() being called before constraintsEvent(), or we 
can do something like the attached patch.

This patch doesn't start the timer if one of the constraints is 
Plasma::StartupCompletedConstraint (set by Containment::restore()).  Instead, 
the onus is on the code that calls Containment::addApplet() to also call 
flushingPendingConstraints().

Alex


PS: wondering why an event loop is called?  One reason I've seen in a 
backtrace is that Plasma::Icon::setUrl makes use of KIO::NetAccess methods, 
which create their own event loop.


-- 
Proud KDE hacker: http://www.kde.org
Get KDE 4.1 - out now!
Arch Linux: perfect for geeks like me - http://www.archlinux.org
OpenSUSE: just works - http://www.opensuse.org


Index: corona.cpp
===================================================================
--- corona.cpp	(revision 845258)
+++ corona.cpp	(working copy)
@@ -289,6 +289,8 @@ void Corona::loadLayout(const QString& c
 
         foreach(Applet* applet, containment->applets()) {
             applet->init();
+            // We have to flush the applet constraints manually
+            applet->flushPendingConstraintsEvents();
         }
 
         containment->updateConstraints(Plasma::StartupCompletedConstraint);
Index: applet.cpp
===================================================================
--- applet.cpp	(revision 845258)
+++ applet.cpp	(working copy)
@@ -1645,7 +1645,9 @@ QString AppletPrivate::instanceName()
 
 void AppletPrivate::scheduleConstraintsUpdate(Plasma::Constraints c)
 {
-    if (!constraintsTimerId) {
+    // Don't start up a timer if we're just starting up
+    // flushPendingConstraints will be called by Corona
+    if (!constraintsTimerId && !(c & Plasma::StartupCompletedConstraint)) {
         constraintsTimerId = q->startTimer(0);
     }
     pendingConstraints |= c;
Index: containment.h
===================================================================
--- containment.h	(revision 845258)
+++ containment.h	(working copy)
@@ -176,7 +176,12 @@ class PLASMA_EXPORT Containment : public
                           const QRectF &geometry = QRectF(-1, -1, -1, -1));
 
         /**
-         * add existing applet to this containment at pos
+         * Add an existing applet to this Containment
+         *
+         * If dontInit is true, the pending constraints are not flushed either.
+         * So it is your responsibility to call both init() and
+         * flushPendingConstraints() on the applet.
+         *
          * @param applet the applet that should be added
          * @param pos the containment-relative position
          * @param dontInit if true, init() will not be called on the applet

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel

Reply via email to