Improve tray icon notification behavior
authorManuel Nickschas <sputnick@quassel-irc.org>
Thu, 10 Sep 2009 19:26:16 +0000 (21:26 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Thu, 10 Sep 2009 19:31:24 +0000 (21:31 +0200)
The tray icon now blinks as long as there are still buffers with unread highlights. As
added bonus, repeated clicks on the tray icon now switch to the next highlighted buffer in
line (rather than hiding the window).

Also, notifications (in KDE) will be properly closed as soon as you switch to the appropriate
buffer.

After all highlighted buffers have been visited, the icon stops blinking. Fixes #720.

src/qtui/knotificationbackend.cpp
src/qtui/knotificationbackend.h
src/qtui/systraynotificationbackend.cpp
src/qtui/systraynotificationbackend.h

index 4e13796..24974e0 100644 (file)
@@ -34,8 +34,7 @@
 #include "systemtray.h"
 
 KNotificationBackend::KNotificationBackend(QObject *parent)
-: AbstractNotificationBackend(parent),
-  _lastNotificationId(0)
+: AbstractNotificationBackend(parent)
 {
   connect(QtUi::mainWindow()->systemTray(), SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
                                             SLOT(notificationActivated(QSystemTrayIcon::ActivationReason)));
@@ -60,61 +59,51 @@ void KNotificationBackend::notify(const Notification &n) {
                                |KNotification::CloseWhenWidgetActivated
                                |KNotification::CloseOnTimeout);
   connect(notification, SIGNAL(activated(uint)), SLOT(notificationActivated()));
-  connect(notification, SIGNAL(closed()), SLOT(notificationClosed()));
   notification->setActions(QStringList("View"));
-  _notificationIds[notification] = _lastNotificationId = n.notificationId;
+  notification->setProperty("notificationId", n.notificationId);
+
+  _notifications.append(qMakePair(n.notificationId, QPointer<KNotification>(notification)));
 
   QtUi::mainWindow()->systemTray()->setAlert(true);
 }
 
 void KNotificationBackend::removeNotificationById(uint notificationId) {
-  QHash<KNotification *, uint>::iterator i = _notificationIds.begin();
-  while(i != _notificationIds.end()) {
-    if(i.value() == notificationId)
-      i = _notificationIds.erase(i);
-    else
+  QList<QPair<uint, QPointer<KNotification> > >::iterator i = _notifications.begin();
+  while(i != _notifications.end()) {
+    if(i->first == notificationId) {
+      if(i->second)
+        i->second->close();
+      i = _notifications.erase(i);
+    } else
       ++i;
   }
-  if(_lastNotificationId == notificationId)
-    _lastNotificationId = 0;
 }
 
 void KNotificationBackend::close(uint notificationId) {
   removeNotificationById(notificationId);
-  if(!_notificationIds.count())
+  if(!_notifications.count())
     QtUi::mainWindow()->systemTray()->setAlert(false);
 }
 
 void KNotificationBackend::notificationActivated() {
   uint id = 0;
   KNotification *n = qobject_cast<KNotification *>(sender());
-  if(n && _notificationIds.contains(n))
-    id = _notificationIds.value(n);
+  if(n)
+    id = n->property("notificationId").toUInt();
 
   notificationActivated(id);
 }
 
 void KNotificationBackend::notificationActivated(QSystemTrayIcon::ActivationReason reason) {
-  if(reason == QSystemTrayIcon::Trigger && _lastNotificationId > 0) {
-    notificationActivated(_lastNotificationId); // most recent one
+  if(reason == QSystemTrayIcon::Trigger && _notifications.count()) {
+    notificationActivated(_notifications.first().first); // oldest one
   }
 }
 
 void KNotificationBackend::notificationActivated(uint notificationId) {
-  removeNotificationById(notificationId);
-
   QtUi::mainWindow()->systemTray()->setInhibitActivation();
   emit activated(notificationId);
 
-  if(!_notificationIds.count())
-    QtUi::mainWindow()->systemTray()->setAlert(false);
-
-}
-
-void KNotificationBackend::notificationClosed() {
-  //KNotification *n = qobject_cast<KNotification *>(sender());
-  //if(n && _notificationIds.contains(n))
-  //  _notificationIds.remove(n);
 }
 
 SettingsPage *KNotificationBackend::createConfigWidget() const {
index d846417..5bdd6c6 100644 (file)
@@ -43,15 +43,13 @@ private slots:
   void notificationActivated();
   void notificationActivated(QSystemTrayIcon::ActivationReason);
   void notificationActivated(uint notificationId);
-  void notificationClosed();
 
 private:
   class ConfigWidget;
 
   void removeNotificationById(uint id);
 
-  QHash<KNotification *, uint> _notificationIds;
-  uint _lastNotificationId;
+  QList<QPair<uint, QPointer<KNotification> > > _notifications;
 };
 
 class KNotificationBackend::ConfigWidget : public SettingsPage {
index e82af91..b665296 100644 (file)
@@ -31,7 +31,7 @@
 #include "systemtray.h"
 
 SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent)
-  : AbstractNotificationBackend(parent), _activeId(0)
+  : AbstractNotificationBackend(parent)
 {
   NotificationSettings notificationSettings;
   _showBubble = notificationSettings.value("Systray/ShowBubble", true).toBool();
@@ -49,13 +49,6 @@ void SystrayNotificationBackend::notify(const Notification &notification) {
   if(notification.type != Highlight && notification.type != PrivMsg)
     return;
 
-  /* fancy stuff to be implemented later: show notifications in order
-  _notifications.append(notification);
-  if(_showBubble && _notifications.count() == 1) {
-    showBubble();
-  }
-  */
-  _notifications.clear();
   _notifications.append(notification);
   if(_showBubble)
     showBubble();
@@ -65,16 +58,18 @@ void SystrayNotificationBackend::notify(const Notification &notification) {
 }
 
 void SystrayNotificationBackend::close(uint notificationId) {
-  Q_UNUSED(notificationId);
-  /* fancy stuff to be implemented later
-  int idx = _notifications.indexOf(notificationId);
-
-  if(_notifications.isEmpty()) {
-  */
-  _notifications.clear();
-  _activeId = 0;
+  QList<Notification>::iterator i = _notifications.begin();
+  while(i != _notifications.end()) {
+    if(i->notificationId == notificationId)
+      i = _notifications.erase(i);
+    else
+      ++i;
+  }
+
   closeBubble();
-  QtUi::mainWindow()->systemTray()->setAlert(false);
+
+  if(!_notifications.count())
+    QtUi::mainWindow()->systemTray()->setAlert(false);
 }
 
 void SystrayNotificationBackend::showBubble() {
@@ -82,8 +77,7 @@ void SystrayNotificationBackend::showBubble() {
   // for now, we just show the last message
   if(_notifications.isEmpty())
     return;
-  Notification n = _notifications.takeLast();
-  _activeId = n.notificationId;
+  Notification n = _notifications.last();
   QString title = Client::networkModel()->networkName(n.bufferId) + " - " + Client::networkModel()->bufferName(n.bufferId);
   QString message = QString("<%1> %2").arg(n.sender, n.message);
   QtUi::mainWindow()->systemTray()->showMessage(title, message);
@@ -99,7 +93,8 @@ void SystrayNotificationBackend::closeBubble() {
 void SystrayNotificationBackend::notificationActivated() {
   if(QtUi::mainWindow()->systemTray()->isAlerted()) {
     QtUi::mainWindow()->systemTray()->setInhibitActivation();
-    emit activated(_activeId);
+    uint id = _notifications.count()? _notifications.last().notificationId : 0;
+    emit activated(id);
   }
 }
 
index 0895cbe..2134617 100644 (file)
@@ -54,7 +54,6 @@ private:
   bool _showBubble;
   bool _animate;
   QList<Notification> _notifications;
-  uint _activeId;
 };
 
 class SystrayNotificationBackend::ConfigWidget : public SettingsPage {