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()
{
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;
}

View File

@ -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.

View File

@ -20,6 +20,7 @@
#ifndef POPUPAPPLET_P_H
#define POPUPAPPLET_P_H
#include <QBasicTimer>
#include <QWeakPointer>
#include <plasma/plasma.h>
@ -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;