From aac15c8e68e98cc85ed519d49f33b11ebb1caff9 Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Tue, 14 Dec 2010 03:14:14 +0000 Subject: [PATCH] the fix for 242173 in r1140471 broke use cases where the applet is activated and then showPopup(someInterval) is called. the showPopup call would get made, and then it would be overridden at the next event loop with a timeout of 0 due to the QTimer::singleShot in appletActivated. this queues _all_ calls to showPopup using a QBasicTimer, which should address the focus issues a bit more comprehensively for 242173 and not break, e.g., the autohide on the device notifier. BUG:242173 svn path=/trunk/KDE/kdelibs/; revision=1206270 --- popupapplet.cpp | 66 +++++++++++++++++++++++++++-------------- popupapplet.h | 5 ++++ private/popupapplet_p.h | 4 ++- 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/popupapplet.cpp b/popupapplet.cpp index 80908c8a7..3910d4324 100644 --- a/popupapplet.cpp +++ b/popupapplet.cpp @@ -435,7 +435,7 @@ void PopupAppletPrivate::popupConstraintsEvent(Plasma::Constraints constraints) void PopupAppletPrivate::appletActivated() { q->setStatus(Plasma::NeedsAttentionStatus); - QTimer::singleShot(0, q, SLOT(showPopup())); + q->showPopup(); } QSizeF PopupApplet::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const @@ -568,29 +568,51 @@ void PopupApplet::dropEvent(QGraphicsSceneDragDropEvent *event) void PopupApplet::showPopup(uint popupDuration) { - Dialog *dialog = d->dialogPtr.data(); - if (dialog) { - // move the popup before its fist show, even if the show isn't triggered by - // a click, this should fix the first random position seen in some widgets - if (!dialog->isVisible()) { - d->internalTogglePopup(); + // use autohideTimer to store when the next show should be + if (popupDuration > 0 || d->autohideTimer) { + if (!d->autohideTimer) { + d->autohideTimer = new QTimer(this); + d->autohideTimer->setSingleShot(true); + connect(d->autohideTimer, SIGNAL(timeout()), this, SLOT(hideTimedPopup())); } - if (popupDuration > 0) { - if (!d->timer) { - d->timer = new QTimer(this); - connect(d->timer, SIGNAL(timeout()), this, SLOT(hideTimedPopup())); + d->autohideTimer->stop(); + d->autohideTimer->setInterval(popupDuration); + } + + //kDebug() << "starting delayed show, duration for popup is" << popupDuration; + d->delayedShowTimer.start(0, this); +} + +void PopupApplet::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == d->delayedShowTimer.timerId()) { + d->delayedShowTimer.stop(); + Dialog *dialog = d->dialogPtr.data(); + if (dialog) { + // move the popup before its fist show, even if the show isn't triggered by + // a click, this should fix the first random position seen in some widgets + if (!dialog->isVisible()) { + d->internalTogglePopup(); } - d->timer->start(popupDuration); - } else if (d->timer) { - d->timer->stop(); + const int popupDuration = d->autohideTimer ? d->autohideTimer->interval() : 0; + kDebug() << d->autohideTimer->interval(); + if (popupDuration > 0) { + d->autohideTimer->start(); + } else if (d->autohideTimer) { + d->autohideTimer->stop(); + } } + } else { + Applet::timerEvent(event); } } void PopupApplet::hidePopup() { + d->delayedShowTimer.stop(); + Dialog *dialog = d->dialogPtr.data(); if (dialog) { if (location() != Floating) { @@ -656,7 +678,7 @@ PopupAppletPrivate::PopupAppletPrivate(PopupApplet *applet) popupPlacement(Plasma::FloatingPopup), popupAlignment(Qt::AlignLeft), savedAspectRatio(Plasma::InvalidAspectRatioMode), - timer(0), + autohideTimer(0), popupLostFocus(false), passive(false) { @@ -687,10 +709,12 @@ void PopupAppletPrivate::iconSizeChanged(int group) void PopupAppletPrivate::internalTogglePopup() { - if (timer) { - timer->stop(); + if (autohideTimer) { + autohideTimer->stop(); } + delayedShowTimer.stop(); + Plasma::Dialog *dialog = dialogPtr.data(); if (!dialog) { q->setFocus(Qt::ShortcutFocusReason); @@ -701,11 +725,8 @@ void PopupAppletPrivate::internalTogglePopup() return; } - if (timer) { - timer->stop(); - } - if (dialog->isVisible()) { + if (q->location() != Floating) { dialog->animatedHide(locationToInverseDirection(q->location())); } else { @@ -743,7 +764,7 @@ void PopupAppletPrivate::internalTogglePopup() void PopupAppletPrivate::hideTimedPopup() { - timer->stop(); + autohideTimer->stop(); q->hidePopup(); } @@ -752,6 +773,7 @@ void PopupAppletPrivate::clearPopupLostFocus() if (!icon || !icon->isDown()) { q->hidePopup(); } + popupLostFocus = false; } diff --git a/popupapplet.h b/popupapplet.h index 884362c4f..9dbba38ec 100644 --- a/popupapplet.h +++ b/popupapplet.h @@ -206,6 +206,11 @@ protected: */ void dropEvent(QGraphicsSceneDragDropEvent *event); + /** + * Reimplemented from QGraphicsLayoutItem + */ + void timerEvent(QTimerEvent *event); + private: /** * @internal This constructor is to be used with the Package loading system. diff --git a/private/popupapplet_p.h b/private/popupapplet_p.h index bb9f876e9..023b90b9a 100644 --- a/private/popupapplet_p.h +++ b/private/popupapplet_p.h @@ -20,6 +20,7 @@ #ifndef POPUPAPPLET_P_H #define POPUPAPPLET_P_H +#include #include #include @@ -55,7 +56,8 @@ public: Plasma::PopupPlacement popupPlacement; Qt::AlignmentFlag popupAlignment; Plasma::AspectRatioMode savedAspectRatio; - QTimer *timer; + QTimer *autohideTimer; + QBasicTimer delayedShowTimer; QPoint clicked; bool popupLostFocus : 1; bool passive : 1;