move applet handle handling (*cough*) to applet instead of contaiment

much cleaner and eliminates the possibility of odd crashes

BUG:253421
This commit is contained in:
Aaron Seigo 2011-05-28 00:22:17 +02:00
parent 223795818f
commit dd122bc011
8 changed files with 96 additions and 109 deletions

View File

@ -1265,6 +1265,18 @@ void Applet::flushPendingConstraintsEvents()
} }
} }
if (!unlocked && d->handle) {
AppletHandle *h = d->handle.data();
disconnect(this);
QGraphicsScene *s = scene();
if (s && h->scene() == s) {
s->removeItem(h);
}
h->deleteLater();
}
emit immutabilityChanged(immutability()); emit immutabilityChanged(immutability());
} }
@ -1754,6 +1766,40 @@ bool Applet::eventFilter(QObject *o, QEvent *e)
bool Applet::sceneEventFilter(QGraphicsItem *watched, QEvent *event) bool Applet::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{ {
if (watched == this) {
switch (event->type()) {
case QEvent::GraphicsSceneHoverEnter:
//kDebug() << "got hoverenterEvent" << immutability() << " " << immutability();
if (immutability() == Mutable) {
QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(event);
if (d->handle) {
d->handle.data()->setHoverPos(he->pos());
} else {
//kDebug() << "generated applet handle";
AppletHandle *handle = new AppletHandle(containment(), this, he->pos());
connect(handle, SIGNAL(disappearDone(AppletHandle*)),
this, SLOT(handleDisappeared(AppletHandle*)));
connect(this, SIGNAL(geometryChanged()),
handle, SLOT(appletResized()));
d->handle = handle;
}
}
break;
case QEvent::GraphicsSceneHoverMove:
if (d->handle && !d->handle.data()->shown() && immutability() == Mutable) {
QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(event);
d->handle.data()->setHoverPos(he->pos());
}
break;
default:
break;
}
return false;
}
switch (event->type()) { switch (event->type()) {
case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMouseMove:
case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneMousePress:
@ -2359,6 +2405,16 @@ QVariant Applet::itemChange(GraphicsItemChange change, const QVariant &value)
} }
} }
break; break;
case ItemParentHasChanged:
{
Containment *c = containment();
if (c && c->containmentType() == Containment::DesktopContainment) {
installSceneEventFilter(this);
} else {
removeSceneEventFilter(this);
}
}
break;
case ItemPositionHasChanged: case ItemPositionHasChanged:
emit geometryChanged(); emit geometryChanged();
// fall through! // fall through!
@ -2868,6 +2924,24 @@ void AppletPrivate::resetConfigurationObject()
} }
} }
void AppletPrivate::handleDisappeared(AppletHandle *h)
{
if (h == handle.data()) {
h->detachApplet();
QGraphicsScene *scene = q->scene();
if (scene && h->scene() == scene) {
scene->removeItem(h);
}
h->deleteLater();
}
}
void ContainmentPrivate::checkRemoveAction()
{
q->enableAction("remove", q->immutability() == Mutable);
}
uint AppletPrivate::s_maxAppletId = 0; uint AppletPrivate::s_maxAppletId = 0;
int AppletPrivate::s_maxZValue = 0; int AppletPrivate::s_maxZValue = 0;
int AppletPrivate::s_minZValue = 0; int AppletPrivate::s_minZValue = 0;

View File

@ -1124,6 +1124,7 @@ class PLASMA_EXPORT Applet : public QGraphicsWidget
Q_PRIVATE_SLOT(d, void publishCheckboxStateChanged(int state)) Q_PRIVATE_SLOT(d, void publishCheckboxStateChanged(int state))
Q_PRIVATE_SLOT(d, void globalShortcutChanged()) Q_PRIVATE_SLOT(d, void globalShortcutChanged())
Q_PRIVATE_SLOT(d, void propagateConfigChanged()) Q_PRIVATE_SLOT(d, void propagateConfigChanged())
Q_PRIVATE_SLOT(d, void handleDisappeared(AppletHandle *handle))
/** /**
* Reimplemented from QGraphicsItem * Reimplemented from QGraphicsItem

View File

@ -67,7 +67,6 @@
#include "remote/accessmanager.h" #include "remote/accessmanager.h"
#include "private/applet_p.h" #include "private/applet_p.h"
#include "private/applethandle_p.h"
#include "private/containmentactionspluginsconfig_p.h" #include "private/containmentactionspluginsconfig_p.h"
#include "private/extenderitemmimedata_p.h" #include "private/extenderitemmimedata_p.h"
#include "private/extenderapplet_p.h" #include "private/extenderapplet_p.h"
@ -888,9 +887,6 @@ void Containment::addApplet(Applet *applet, const QPointF &pos, bool delayInit)
applet->removeSceneEventFilter(currentContainment); applet->removeSceneEventFilter(currentContainment);
KConfigGroup oldConfig = applet->config(); KConfigGroup oldConfig = applet->config();
currentContainment->d->applets.removeAll(applet); currentContainment->d->applets.removeAll(applet);
if (currentContainment->d->handles.contains(applet)) {
currentContainment->d->handles.remove(applet);
}
applet->setParentItem(this); applet->setParentItem(this);
applet->setParent(this); applet->setParent(this);
@ -918,12 +914,7 @@ void Containment::addApplet(Applet *applet, const QPointF &pos, bool delayInit)
applet->setPos(pos); applet->setPos(pos);
} }
if (delayInit || currentContainment) { if (!delayInit && !currentContainment) {
if (d->type == DesktopContainment) {
applet->installSceneEventFilter(this);
//applet->setWindowFlags(Qt::Window);
}
} else {
applet->restore(*applet->d->mainConfigGroup()); applet->restore(*applet->d->mainConfigGroup());
applet->init(); applet->init();
Plasma::Animation *anim = Plasma::Animator::create(Plasma::Animator::AppearAnimation); Plasma::Animation *anim = Plasma::Animator::create(Plasma::Animator::AppearAnimation);
@ -1696,51 +1687,8 @@ void Containment::wheelEvent(QGraphicsSceneWheelEvent *event)
bool Containment::sceneEventFilter(QGraphicsItem *watched, QEvent *event) bool Containment::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{ {
Applet *applet = qgraphicsitem_cast<Applet*>(watched); Q_UNUSED(watched)
Q_UNUSED(event)
// Otherwise we're watching something we shouldn't be...
Q_ASSERT(applet != 0);
if (!d->applets.contains(applet)) {
return false;
}
//kDebug() << "got sceneEvent";
switch (event->type()) {
case QEvent::GraphicsSceneHoverEnter:
//kDebug() << "got hoverenterEvent" << immutability() << " " << applet->immutability();
if (immutability() == Mutable && applet->immutability() == Mutable) {
QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(event);
if (d->handles.contains(applet)) {
AppletHandle *handle = d->handles.value(applet);
if (handle) {
handle->setHoverPos(he->pos());
}
} else {
//kDebug() << "generated applet handle";
AppletHandle *handle = new AppletHandle(this, applet, he->pos());
d->handles[applet] = handle;
connect(handle, SIGNAL(disappearDone(AppletHandle*)),
this, SLOT(handleDisappeared(AppletHandle*)));
connect(applet, SIGNAL(geometryChanged()),
handle, SLOT(appletResized()));
}
}
break;
case QEvent::GraphicsSceneHoverMove:
if (immutability() == Mutable && applet->immutability() == Mutable) {
QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(event);
if (d->handles.contains(applet)) {
AppletHandle *handle = d->handles.value(applet);
if (handle) {
handle->setHoverPos(he->pos());
}
}
}
break;
default:
break;
}
return false; return false;
} }
@ -2205,24 +2153,6 @@ void ContainmentPrivate::triggerShowAddWidgets()
emit q->showAddWidgetsInterface(QPointF()); emit q->showAddWidgetsInterface(QPointF());
} }
void ContainmentPrivate::handleDisappeared(AppletHandle *handle)
{
if (handles.contains(handle->applet())) {
handles.remove(handle->applet());
handle->detachApplet();
QGraphicsScene *scene = q->scene();
if (scene && handle->scene() == scene) {
scene->removeItem(handle);
}
handle->deleteLater();
}
}
void ContainmentPrivate::checkRemoveAction()
{
q->enableAction("remove", q->immutability() == Mutable);
}
void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constraints) void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constraints)
{ {
if (!q->isContainment()) { if (!q->isContainment()) {
@ -2242,22 +2172,6 @@ void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constra
a->setImmutability(q->immutability()); a->setImmutability(q->immutability());
a->updateConstraints(ImmutableConstraint); a->updateConstraints(ImmutableConstraint);
} }
//clear handles on lock
if (!unlocked) {
QMap<Applet*, AppletHandle*> h = handles;
handles.clear();
foreach (AppletHandle *handle, h) {
handle->disconnect(q);
if (q->scene()) {
q->scene()->removeItem(handle);
}
handle->deleteLater();
}
}
} }
// pass on the constraints that are relevant here // pass on the constraints that are relevant here
@ -2341,10 +2255,6 @@ void ContainmentPrivate::appletDestroyed(Plasma::Applet *applet)
focusedApplet = 0; focusedApplet = 0;
} }
if (handles.contains(applet)) {
handles.remove(applet);
}
emit q->appletRemoved(applet); emit q->appletRemoved(applet);
emit q->configNeedsSaving(); emit q->configNeedsSaving();
} }
@ -2362,11 +2272,7 @@ void ContainmentPrivate::appletAppearAnimationComplete()
void ContainmentPrivate::appletAppeared(Applet *applet) void ContainmentPrivate::appletAppeared(Applet *applet)
{ {
kDebug() << type << Containment::DesktopContainment; //kDebug() << type << Containment::DesktopContainment;
if (type == Containment::DesktopContainment) {
applet->installSceneEventFilter(q);
}
KConfigGroup *cg = applet->d->mainConfigGroup(); KConfigGroup *cg = applet->d->mainConfigGroup();
applet->save(*cg); applet->save(*cg);
emit q->configNeedsSaving(); emit q->configNeedsSaving();

View File

@ -644,7 +644,6 @@ Q_SIGNALS:
Q_PRIVATE_SLOT(d, void appletDestroyed(Plasma::Applet*)) Q_PRIVATE_SLOT(d, void appletDestroyed(Plasma::Applet*))
Q_PRIVATE_SLOT(d, void appletAppearAnimationComplete()) Q_PRIVATE_SLOT(d, void appletAppearAnimationComplete())
Q_PRIVATE_SLOT(d, void triggerShowAddWidgets()) Q_PRIVATE_SLOT(d, void triggerShowAddWidgets())
Q_PRIVATE_SLOT(d, void handleDisappeared(AppletHandle *handle))
Q_PRIVATE_SLOT(d, void positionToolBox()) Q_PRIVATE_SLOT(d, void positionToolBox())
Q_PRIVATE_SLOT(d, void requestConfiguration()) Q_PRIVATE_SLOT(d, void requestConfiguration())
Q_PRIVATE_SLOT(d, void updateToolBoxVisibility()) Q_PRIVATE_SLOT(d, void updateToolBoxVisibility())

View File

@ -29,6 +29,7 @@
#include <kconfigdialog.h> #include <kconfigdialog.h>
#include "plasma/animator.h" #include "plasma/animator.h"
#include "plasma/private/applethandle_p.h"
#include "plasma/private/dataengineconsumer_p.h" #include "plasma/private/dataengineconsumer_p.h"
#include "plasma/ui_publish.h" #include "plasma/ui_publish.h"
@ -107,6 +108,7 @@ public:
*/ */
void setIsContainment(bool isContainment, bool forceUpdate = false); void setIsContainment(bool isContainment, bool forceUpdate = false);
void handleDisappeared(AppletHandle *handle);
QString globalName() const; QString globalName() const;
QString instanceName(); QString instanceName();
void scheduleConstraintsUpdate(Plasma::Constraints c); void scheduleConstraintsUpdate(Plasma::Constraints c);
@ -174,17 +176,18 @@ public:
AppletOverlayWidget *messageOverlay; AppletOverlayWidget *messageOverlay;
QGraphicsProxyWidget *messageOverlayProxy; QGraphicsProxyWidget *messageOverlayProxy;
Plasma::BusyWidget *busyWidget; Plasma::BusyWidget *busyWidget;
// sripting and package stuff
AppletScript *script;
Package *package;
ConfigLoader *configLoader;
QWeakPointer<Plasma::PushButton> messageOkButton; QWeakPointer<Plasma::PushButton> messageOkButton;
QWeakPointer<Plasma::PushButton> messageYesButton; QWeakPointer<Plasma::PushButton> messageYesButton;
QWeakPointer<Plasma::PushButton> messageNoButton; QWeakPointer<Plasma::PushButton> messageNoButton;
QWeakPointer<Plasma::PushButton> messageCancelButton; QWeakPointer<Plasma::PushButton> messageCancelButton;
QWeakPointer<QAction> messageCloseAction; QWeakPointer<QAction> messageCloseAction;
// sripting and package stuff
AppletScript *script;
Package *package;
ConfigLoader *configLoader;
QWeakPointer<AppletHandle> handle;
// actions stuff; put activationAction into actions? // actions stuff; put activationAction into actions?
KActionCollection *actions; KActionCollection *actions;
KAction *activationAction; KAction *activationAction;

View File

@ -58,10 +58,10 @@ qreal _k_pointAngle(QPointF point);
QPointF _k_rotatePoint(QPointF point, qreal angle); QPointF _k_rotatePoint(QPointF point, qreal angle);
QPointF _k_projectPoint(QPointF point, QPointF v); QPointF _k_projectPoint(QPointF point, QPointF v);
AppletHandle::AppletHandle(Containment *parent, Applet *applet, const QPointF &hoverPos) AppletHandle::AppletHandle(Containment *containment, Applet *applet, const QPointF &hoverPos)
: QGraphicsObject(applet), : QGraphicsObject(applet),
m_pressedButton(NoButton), m_pressedButton(NoButton),
m_containment(parent), m_containment(containment),
m_applet(applet), m_applet(applet),
m_iconSize(KIconLoader::SizeSmall), m_iconSize(KIconLoader::SizeSmall),
m_opacity(0.0), m_opacity(0.0),
@ -116,6 +116,11 @@ AppletHandle::~AppletHandle()
delete m_backgroundBuffer; delete m_backgroundBuffer;
} }
bool AppletHandle::shown() const
{
return !m_hoverTimer->isActive();
}
Applet *AppletHandle::applet() const Applet *AppletHandle::applet() const
{ {
return m_applet; return m_applet;

View File

@ -61,8 +61,9 @@ class AppletHandle : public QGraphicsObject
AppletHandle(Containment *parent, Applet *applet, const QPointF &hoverPos); AppletHandle(Containment *parent, Applet *applet, const QPointF &hoverPos);
virtual ~AppletHandle(); virtual ~AppletHandle();
void detachApplet (); bool shown() const;
void detachApplet();
Applet *applet() const; Applet *applet() const;
QRectF boundingRect() const; QRectF boundingRect() const;

View File

@ -96,7 +96,6 @@ public:
QPointF preferredPos(Corona *corona) const; QPointF preferredPos(Corona *corona) const;
QPointF preferredPanelPos(Corona *corona) const; QPointF preferredPanelPos(Corona *corona) const;
void setLockToolText(); void setLockToolText();
void handleDisappeared(AppletHandle *handle);
void appletDestroyed(Applet*); void appletDestroyed(Applet*);
void appletAppearAnimationComplete(); void appletAppearAnimationComplete();
void appletAppeared(Applet*); void appletAppeared(Applet*);
@ -172,7 +171,6 @@ public:
Applet::List applets; Applet::List applets;
Applet *focusedApplet; Applet *focusedApplet;
Plasma::Wallpaper *wallpaper; Plasma::Wallpaper *wallpaper;
QMap<Applet*, AppletHandle*> handles;
QHash<QString, ContainmentActions*> localActionPlugins; QHash<QString, ContainmentActions*> localActionPlugins;
int screen; int screen;
int lastScreen; int lastScreen;