From 138bb708911ef06fa37859fa51bca5f47125ccdd Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 16 Feb 2010 02:12:51 +0100 Subject: [PATCH] Rework tray icon activation behavior yet again Finally figured out how to filter out double activation signals from QSystemTrayIcon. Additionally, main window toggling is now controlled by the systray notification backends rather than the tray itself. This ensures that we don't get a race condition where the notification wants to activate the window, and the tray wants to hide it. Consequently removing the crude inhibitActivation hack. --- src/qtui/knotificationbackend.cpp | 9 +++++---- src/qtui/systemtray.cpp | 15 -------------- src/qtui/systemtray.h | 8 -------- src/qtui/systraynotificationbackend.cpp | 26 +++++++++++++++++++------ src/qtui/systraynotificationbackend.h | 4 ++++ 5 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/qtui/knotificationbackend.cpp b/src/qtui/knotificationbackend.cpp index d3939dfb..e261eacf 100644 --- a/src/qtui/knotificationbackend.cpp +++ b/src/qtui/knotificationbackend.cpp @@ -93,15 +93,16 @@ void KNotificationBackend::notificationActivated() { } void KNotificationBackend::notificationActivated(SystemTray::ActivationReason reason) { - if(reason == SystemTray::Trigger && _notifications.count()) { - notificationActivated(_notifications.first().first); // oldest one + if(reason == SystemTray::Trigger) { + if( _notifications.count()) + notificationActivated(_notifications.first().first); // oldest one + else + GraphicalUi::toggleMainWidget(); } } void KNotificationBackend::notificationActivated(uint notificationId) { - QtUi::mainWindow()->systemTray()->setInhibitActivation(); emit activated(notificationId); - } SettingsPage *KNotificationBackend::createConfigWidget() const { diff --git a/src/qtui/systemtray.cpp b/src/qtui/systemtray.cpp index 91258230..6b2b33cd 100644 --- a/src/qtui/systemtray.cpp +++ b/src/qtui/systemtray.cpp @@ -35,7 +35,6 @@ SystemTray::SystemTray(QWidget *parent) : QObject(parent), _mode(Invalid), _state(Passive), - _inhibitActivation(false), _passiveIcon(DesktopIcon("quassel_inactive")), _activeIcon(DesktopIcon("quassel")), _needsAttentionIcon(DesktopIcon("quassel_message")), @@ -43,8 +42,6 @@ SystemTray::SystemTray(QWidget *parent) _associatedWidget(parent) { Q_ASSERT(parent); - - qApp->installEventFilter(this); } SystemTray::~SystemTray() { @@ -130,17 +127,5 @@ void SystemTray::showMessage(const QString &title, const QString &message, Messa } void SystemTray::activate(SystemTray::ActivationReason reason) { - emit activated(reason); - - if(reason == Trigger && !isActivationInhibited()) { - GraphicalUi::toggleMainWidget(); - } -} - -bool SystemTray::eventFilter(QObject *obj, QEvent *event) { - if(event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonRelease) { - _inhibitActivation = false; - } - return QObject::eventFilter(obj, event); } diff --git a/src/qtui/systemtray.h b/src/qtui/systemtray.h index 7192b3fe..dc31edc7 100644 --- a/src/qtui/systemtray.h +++ b/src/qtui/systemtray.h @@ -68,9 +68,7 @@ public: virtual inline bool isSystemTrayAvailable() const; void setAlert(bool alerted); - virtual inline void setInhibitActivation(); virtual inline bool isVisible() const { return false; } - inline bool isActivationInhibited() const; QWidget *associatedWidget() const; @@ -100,16 +98,12 @@ protected: inline QMenu *trayMenu() const; void setTrayMenu(QMenu *); - virtual bool eventFilter(QObject *obj, QEvent *event); - private slots: private: Mode _mode; State _state; - bool _inhibitActivation; - QString _toolTipTitle, _toolTipSubTitle; Icon _passiveIcon, _activeIcon, _needsAttentionIcon; @@ -121,8 +115,6 @@ private: bool SystemTray::isSystemTrayAvailable() const { return false; } bool SystemTray::isAlerted() const { return state() == NeedsAttention; } -void SystemTray::setInhibitActivation() { _inhibitActivation = true; } -bool SystemTray::isActivationInhibited() const { return _inhibitActivation; } SystemTray::Mode SystemTray::mode() const { return _mode; } SystemTray::State SystemTray::state() const { return _state; } QMenu *SystemTray::trayMenu() const { return _trayMenu; } diff --git a/src/qtui/systraynotificationbackend.cpp b/src/qtui/systraynotificationbackend.cpp index a4516659..fa7b2457 100644 --- a/src/qtui/systraynotificationbackend.cpp +++ b/src/qtui/systraynotificationbackend.cpp @@ -31,7 +31,8 @@ #include "systemtray.h" SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent) - : AbstractNotificationBackend(parent) + : AbstractNotificationBackend(parent), + _blockActivation(false) { NotificationSettings notificationSettings; _showBubble = notificationSettings.value("Systray/ShowBubble", true).toBool(); @@ -40,9 +41,11 @@ SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent) notificationSettings.notify("Systray/ShowBubble", this, SLOT(showBubbleChanged(const QVariant &))); notificationSettings.notify("Systray/Animate", this, SLOT(animateChanged(const QVariant &))); + connect(QtUi::mainWindow()->systemTray(), SIGNAL(messageClicked()), SLOT(notificationActivated())); connect(QtUi::mainWindow()->systemTray(), SIGNAL(activated(SystemTray::ActivationReason)), SLOT(notificationActivated(SystemTray::ActivationReason))); - connect(QtUi::mainWindow()->systemTray(), SIGNAL(messageClicked()), SLOT(notificationActivated())); + + QApplication::instance()->installEventFilter(this); } void SystrayNotificationBackend::notify(const Notification ¬ification) { @@ -91,10 +94,13 @@ void SystrayNotificationBackend::closeBubble() { } void SystrayNotificationBackend::notificationActivated() { - if(QtUi::mainWindow()->systemTray()->isAlerted() && !QtUi::mainWindow()->systemTray()->isActivationInhibited()) { - QtUi::mainWindow()->systemTray()->setInhibitActivation(); - uint id = _notifications.count()? _notifications.last().notificationId : 0; - emit activated(id); + if(!_blockActivation) { + if(QtUi::mainWindow()->systemTray()->isAlerted()) { + _blockActivation = true; // prevent double activation because both tray icon and bubble might send a signal + uint id = _notifications.count()? _notifications.last().notificationId : 0; + emit activated(id); + } else + GraphicalUi::toggleMainWidget(); } } @@ -104,6 +110,14 @@ void SystrayNotificationBackend::notificationActivated(SystemTray::ActivationRea } } +// moving the mouse or releasing the button means that we're not dealing with a double activation +bool SystrayNotificationBackend::eventFilter(QObject *obj, QEvent *event) { + if(event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonRelease) { + _blockActivation = false; + } + return AbstractNotificationBackend::eventFilter(obj, event); +} + void SystrayNotificationBackend::showBubbleChanged(const QVariant &v) { _showBubble = v.toBool(); } diff --git a/src/qtui/systraynotificationbackend.h b/src/qtui/systraynotificationbackend.h index c96958dd..46591b38 100644 --- a/src/qtui/systraynotificationbackend.h +++ b/src/qtui/systraynotificationbackend.h @@ -37,6 +37,9 @@ public: void close(uint notificationId); virtual SettingsPage *createConfigWidget() const; +protected: + virtual bool eventFilter(QObject *obj, QEvent *event); + private slots: void showBubble(); void closeBubble(); @@ -52,6 +55,7 @@ private: bool _showBubble; bool _animate; QList _notifications; + bool _blockActivation; }; class SystrayNotificationBackend::ConfigWidget : public SettingsPage { -- 2.20.1