Rework tray icon activation behavior yet again
authorManuel Nickschas <sputnick@quassel-irc.org>
Tue, 16 Feb 2010 01:12:51 +0000 (02:12 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Tue, 16 Feb 2010 01:12:51 +0000 (02:12 +0100)
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
src/qtui/systemtray.cpp
src/qtui/systemtray.h
src/qtui/systraynotificationbackend.cpp
src/qtui/systraynotificationbackend.h

index d3939df..e261eac 100644 (file)
@@ -93,15 +93,16 @@ void KNotificationBackend::notificationActivated() {
 }
 
 void KNotificationBackend::notificationActivated(SystemTray::ActivationReason reason) {
 }
 
 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) {
   }
 }
 
 void KNotificationBackend::notificationActivated(uint notificationId) {
-  QtUi::mainWindow()->systemTray()->setInhibitActivation();
   emit activated(notificationId);
   emit activated(notificationId);
-
 }
 
 SettingsPage *KNotificationBackend::createConfigWidget() const {
 }
 
 SettingsPage *KNotificationBackend::createConfigWidget() const {
index 9125823..6b2b33c 100644 (file)
@@ -35,7 +35,6 @@ SystemTray::SystemTray(QWidget *parent)
 : QObject(parent),
   _mode(Invalid),
   _state(Passive),
 : QObject(parent),
   _mode(Invalid),
   _state(Passive),
-  _inhibitActivation(false),
   _passiveIcon(DesktopIcon("quassel_inactive")),
   _activeIcon(DesktopIcon("quassel")),
   _needsAttentionIcon(DesktopIcon("quassel_message")),
   _passiveIcon(DesktopIcon("quassel_inactive")),
   _activeIcon(DesktopIcon("quassel")),
   _needsAttentionIcon(DesktopIcon("quassel_message")),
@@ -43,8 +42,6 @@ SystemTray::SystemTray(QWidget *parent)
   _associatedWidget(parent)
 {
   Q_ASSERT(parent);
   _associatedWidget(parent)
 {
   Q_ASSERT(parent);
-
-  qApp->installEventFilter(this);
 }
 
 SystemTray::~SystemTray() {
 }
 
 SystemTray::~SystemTray() {
@@ -130,17 +127,5 @@ void SystemTray::showMessage(const QString &title, const QString &message, Messa
 }
 
 void SystemTray::activate(SystemTray::ActivationReason reason) {
 }
 
 void SystemTray::activate(SystemTray::ActivationReason reason) {
-
   emit activated(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);
 }
 }
index 7192b3f..dc31edc 100644 (file)
@@ -68,9 +68,7 @@ public:
   virtual inline bool isSystemTrayAvailable() const;
 
   void setAlert(bool alerted);
   virtual inline bool isSystemTrayAvailable() const;
 
   void setAlert(bool alerted);
-  virtual inline void setInhibitActivation();
   virtual inline bool isVisible() const { return false; }
   virtual inline bool isVisible() const { return false; }
-  inline bool isActivationInhibited() const;
 
   QWidget *associatedWidget() const;
 
 
   QWidget *associatedWidget() const;
 
@@ -100,16 +98,12 @@ protected:
   inline QMenu *trayMenu() const;
   void setTrayMenu(QMenu *);
 
   inline QMenu *trayMenu() const;
   void setTrayMenu(QMenu *);
 
-  virtual bool eventFilter(QObject *obj, QEvent *event);
-
 private slots:
 
 private:
   Mode _mode;
   State _state;
 
 private slots:
 
 private:
   Mode _mode;
   State _state;
 
-  bool _inhibitActivation;
-
   QString _toolTipTitle, _toolTipSubTitle;
   Icon _passiveIcon, _activeIcon, _needsAttentionIcon;
 
   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; }
 
 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; }
 SystemTray::Mode SystemTray::mode() const { return _mode; }
 SystemTray::State SystemTray::state() const { return _state; }
 QMenu *SystemTray::trayMenu() const { return _trayMenu; }
index a451665..fa7b245 100644 (file)
@@ -31,7 +31,8 @@
 #include "systemtray.h"
 
 SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent)
 #include "systemtray.h"
 
 SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent)
-  : AbstractNotificationBackend(parent)
+  : AbstractNotificationBackend(parent),
+  _blockActivation(false)
 {
   NotificationSettings notificationSettings;
   _showBubble = notificationSettings.value("Systray/ShowBubble", true).toBool();
 {
   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 &)));
 
   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(activated(SystemTray::ActivationReason)),
                                             SLOT(notificationActivated(SystemTray::ActivationReason)));
-  connect(QtUi::mainWindow()->systemTray(), SIGNAL(messageClicked()), SLOT(notificationActivated()));
+
+  QApplication::instance()->installEventFilter(this);
 }
 
 void SystrayNotificationBackend::notify(const Notification &notification) {
 }
 
 void SystrayNotificationBackend::notify(const Notification &notification) {
@@ -91,10 +94,13 @@ void SystrayNotificationBackend::closeBubble() {
 }
 
 void SystrayNotificationBackend::notificationActivated() {
 }
 
 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();
 }
 void SystrayNotificationBackend::showBubbleChanged(const QVariant &v) {
   _showBubble = v.toBool();
 }
index c96958d..46591b3 100644 (file)
@@ -37,6 +37,9 @@ public:
   void close(uint notificationId);
   virtual SettingsPage *createConfigWidget() const;
 
   void close(uint notificationId);
   virtual SettingsPage *createConfigWidget() const;
 
+protected:
+  virtual bool eventFilter(QObject *obj, QEvent *event);
+
 private slots:
   void showBubble();
   void closeBubble();
 private slots:
   void showBubble();
   void closeBubble();
@@ -52,6 +55,7 @@ private:
   bool _showBubble;
   bool _animate;
   QList<Notification> _notifications;
   bool _showBubble;
   bool _animate;
   QList<Notification> _notifications;
+  bool _blockActivation;
 };
 
 class SystrayNotificationBackend::ConfigWidget : public SettingsPage {
 };
 
 class SystrayNotificationBackend::ConfigWidget : public SettingsPage {