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
This commit is contained in:
Aaron J. Seigo 2010-12-14 03:14:14 +00:00
parent 0594bd9d85
commit aac15c8e68
3 changed files with 52 additions and 23 deletions

View File

@ -435,7 +435,7 @@ void PopupAppletPrivate::popupConstraintsEvent(Plasma::Constraints constraints)
void PopupAppletPrivate::appletActivated() void PopupAppletPrivate::appletActivated()
{ {
q->setStatus(Plasma::NeedsAttentionStatus); q->setStatus(Plasma::NeedsAttentionStatus);
QTimer::singleShot(0, q, SLOT(showPopup())); q->showPopup();
} }
QSizeF PopupApplet::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const QSizeF PopupApplet::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
@ -568,29 +568,51 @@ void PopupApplet::dropEvent(QGraphicsSceneDragDropEvent *event)
void PopupApplet::showPopup(uint popupDuration) void PopupApplet::showPopup(uint popupDuration)
{ {
Dialog *dialog = d->dialogPtr.data(); // use autohideTimer to store when the next show should be
if (dialog) { if (popupDuration > 0 || d->autohideTimer) {
// move the popup before its fist show, even if the show isn't triggered by if (!d->autohideTimer) {
// a click, this should fix the first random position seen in some widgets d->autohideTimer = new QTimer(this);
if (!dialog->isVisible()) { d->autohideTimer->setSingleShot(true);
d->internalTogglePopup(); connect(d->autohideTimer, SIGNAL(timeout()), this, SLOT(hideTimedPopup()));
} }
if (popupDuration > 0) { d->autohideTimer->stop();
if (!d->timer) { d->autohideTimer->setInterval(popupDuration);
d->timer = new QTimer(this); }
connect(d->timer, SIGNAL(timeout()), this, SLOT(hideTimedPopup()));
//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); const int popupDuration = d->autohideTimer ? d->autohideTimer->interval() : 0;
} else if (d->timer) { kDebug() << d->autohideTimer->interval();
d->timer->stop(); if (popupDuration > 0) {
d->autohideTimer->start();
} else if (d->autohideTimer) {
d->autohideTimer->stop();
}
} }
} else {
Applet::timerEvent(event);
} }
} }
void PopupApplet::hidePopup() void PopupApplet::hidePopup()
{ {
d->delayedShowTimer.stop();
Dialog *dialog = d->dialogPtr.data(); Dialog *dialog = d->dialogPtr.data();
if (dialog) { if (dialog) {
if (location() != Floating) { if (location() != Floating) {
@ -656,7 +678,7 @@ PopupAppletPrivate::PopupAppletPrivate(PopupApplet *applet)
popupPlacement(Plasma::FloatingPopup), popupPlacement(Plasma::FloatingPopup),
popupAlignment(Qt::AlignLeft), popupAlignment(Qt::AlignLeft),
savedAspectRatio(Plasma::InvalidAspectRatioMode), savedAspectRatio(Plasma::InvalidAspectRatioMode),
timer(0), autohideTimer(0),
popupLostFocus(false), popupLostFocus(false),
passive(false) passive(false)
{ {
@ -687,10 +709,12 @@ void PopupAppletPrivate::iconSizeChanged(int group)
void PopupAppletPrivate::internalTogglePopup() void PopupAppletPrivate::internalTogglePopup()
{ {
if (timer) { if (autohideTimer) {
timer->stop(); autohideTimer->stop();
} }
delayedShowTimer.stop();
Plasma::Dialog *dialog = dialogPtr.data(); Plasma::Dialog *dialog = dialogPtr.data();
if (!dialog) { if (!dialog) {
q->setFocus(Qt::ShortcutFocusReason); q->setFocus(Qt::ShortcutFocusReason);
@ -701,11 +725,8 @@ void PopupAppletPrivate::internalTogglePopup()
return; return;
} }
if (timer) {
timer->stop();
}
if (dialog->isVisible()) { if (dialog->isVisible()) {
if (q->location() != Floating) { if (q->location() != Floating) {
dialog->animatedHide(locationToInverseDirection(q->location())); dialog->animatedHide(locationToInverseDirection(q->location()));
} else { } else {
@ -743,7 +764,7 @@ void PopupAppletPrivate::internalTogglePopup()
void PopupAppletPrivate::hideTimedPopup() void PopupAppletPrivate::hideTimedPopup()
{ {
timer->stop(); autohideTimer->stop();
q->hidePopup(); q->hidePopup();
} }
@ -752,6 +773,7 @@ void PopupAppletPrivate::clearPopupLostFocus()
if (!icon || !icon->isDown()) { if (!icon || !icon->isDown()) {
q->hidePopup(); q->hidePopup();
} }
popupLostFocus = false; popupLostFocus = false;
} }

View File

@ -206,6 +206,11 @@ protected:
*/ */
void dropEvent(QGraphicsSceneDragDropEvent *event); void dropEvent(QGraphicsSceneDragDropEvent *event);
/**
* Reimplemented from QGraphicsLayoutItem
*/
void timerEvent(QTimerEvent *event);
private: private:
/** /**
* @internal This constructor is to be used with the Package loading system. * @internal This constructor is to be used with the Package loading system.

View File

@ -20,6 +20,7 @@
#ifndef POPUPAPPLET_P_H #ifndef POPUPAPPLET_P_H
#define POPUPAPPLET_P_H #define POPUPAPPLET_P_H
#include <QBasicTimer>
#include <QWeakPointer> #include <QWeakPointer>
#include <plasma/plasma.h> #include <plasma/plasma.h>
@ -55,7 +56,8 @@ public:
Plasma::PopupPlacement popupPlacement; Plasma::PopupPlacement popupPlacement;
Qt::AlignmentFlag popupAlignment; Qt::AlignmentFlag popupAlignment;
Plasma::AspectRatioMode savedAspectRatio; Plasma::AspectRatioMode savedAspectRatio;
QTimer *timer; QTimer *autohideTimer;
QBasicTimer delayedShowTimer;
QPoint clicked; QPoint clicked;
bool popupLostFocus : 1; bool popupLostFocus : 1;
bool passive : 1; bool passive : 1;