From: Manuel Nickschas Date: Wed, 1 Apr 2009 10:03:47 +0000 (+0200) Subject: Improve systray notifications X-Git-Tag: 0.4.2~22 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=6e85a37d1b7d3501f0fd7cc94fd0fcd4ba0c6cc4 Improve systray notifications * Add an action button to KDE's notification bubble, as it doesn't report clicks other than action triggers * Bring Quassel to front on click (thanks Zarin for pointing out how to bypass focus stealing prevention) * Select buffer where the highlight occurred on click Note: Plasma notifications are mostly broken currently at least for me; YMMV. If it doesn't work for you, try using old-fashioned notifications in KDE and see if it works there. --- diff --git a/src/qtui/knotificationbackend.cpp b/src/qtui/knotificationbackend.cpp index 3596ae05..8cc58a9a 100644 --- a/src/qtui/knotificationbackend.cpp +++ b/src/qtui/knotificationbackend.cpp @@ -41,7 +41,11 @@ void KNotificationBackend::notify(const Notification &n) { QString message = QString("<%1> %2").arg(n.sender, Qt::escape(n.message)); KNotification *notification = KNotification::event("Highlight", message, DesktopIcon("dialog-information"), QtUi::mainWindow(), KNotification::Persistent|KNotification::RaiseWidgetOnActivation|KNotification::CloseWhenWidgetActivated); - connect(notification, SIGNAL(activated()), SLOT(notificationActivated())); + connect(notification, SIGNAL(activated(uint)), SLOT(notificationActivated())); + connect(notification, SIGNAL(closed()), SLOT(notificationClosed())); + notification->setActions(QStringList("View")); + _notificationIds[notification] = n.notificationId; + QtUi::mainWindow()->systemTray()->setAlert(true); } @@ -51,7 +55,18 @@ void KNotificationBackend::close(uint notificationId) { } void KNotificationBackend::notificationActivated() { - emit activated(); + uint id = 0; + KNotification *n = qobject_cast(sender()); + if(n && _notificationIds.contains(n)) + id = _notificationIds.value(n); + + emit activated(id); +} + +void KNotificationBackend::notificationClosed() { + KNotification *n = qobject_cast(sender()); + if(n && _notificationIds.contains(n)) + _notificationIds.remove(n); } SettingsPage *KNotificationBackend::createConfigWidget() const { diff --git a/src/qtui/knotificationbackend.h b/src/qtui/knotificationbackend.h index ca0585c7..04723d3a 100644 --- a/src/qtui/knotificationbackend.h +++ b/src/qtui/knotificationbackend.h @@ -39,9 +39,12 @@ public: private slots: void notificationActivated(); + void notificationClosed(); private: class ConfigWidget; + + QHash _notificationIds; }; class KNotificationBackend::ConfigWidget : public SettingsPage { diff --git a/src/qtui/qtui.cpp b/src/qtui/qtui.cpp index c1ed4aa0..30fe5a37 100644 --- a/src/qtui/qtui.cpp +++ b/src/qtui/qtui.cpp @@ -22,6 +22,7 @@ #include "abstractnotificationbackend.h" #include "actioncollection.h" +#include "buffermodel.h" #include "chatlinemodel.h" #include "contextmenuactionprovider.h" #include "mainwin.h" @@ -33,6 +34,11 @@ #include "util.h" QHash QtUi::_actionCollections; + +#ifdef Q_WS_X11 +# include +#endif + QPointer QtUi::_instance = 0; QPointer QtUi::_mainWin = 0; QList QtUi::_notificationBackends; @@ -97,7 +103,7 @@ void QtUi::disconnectedFromCore() { void QtUi::registerNotificationBackend(AbstractNotificationBackend *backend) { if(!_notificationBackends.contains(backend)) { _notificationBackends.append(backend); - instance()->connect(backend, SIGNAL(activated()), SLOT(notificationActivated())); + instance()->connect(backend, SIGNAL(activated(uint)), SLOT(notificationActivated(uint))); } } @@ -154,8 +160,30 @@ const QList &QtUi::activeNotification return _notifications; } -void QtUi::notificationActivated() { - // this might not work with some window managers +void QtUi::notificationActivated(uint notificationId) { + if(notificationId != 0) { + QList::iterator i = _notifications.begin(); + while(i != _notifications.end()) { + if((*i).notificationId == notificationId) { + BufferId bufId = (*i).bufferId; + if(bufId.isValid()) + Client::bufferModel()->switchToBuffer(bufId); + _notifications.erase(i); + break; + } + } + } + +#ifdef Q_WS_X11 + // Bypass focus stealing prevention + QX11Info::setAppUserTime(QX11Info::appTime()); +#endif + + if(_mainWin->windowState() & Qt::WindowMinimized) { + // restore + _mainWin->setWindowState((_mainWin->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + _mainWin->show(); + } _mainWin->raise(); _mainWin->activateWindow(); } diff --git a/src/qtui/qtui.h b/src/qtui/qtui.h index 77916ce2..cdee4e7d 100644 --- a/src/qtui/qtui.h +++ b/src/qtui/qtui.h @@ -75,7 +75,7 @@ public slots: protected slots: void connectedToCore(); void disconnectedFromCore(); - void notificationActivated(); + void notificationActivated(uint notificationId); private: static QPointer _instance; diff --git a/src/qtui/systraynotificationbackend.cpp b/src/qtui/systraynotificationbackend.cpp index 3d9d74be..6b67b202 100644 --- a/src/qtui/systraynotificationbackend.cpp +++ b/src/qtui/systraynotificationbackend.cpp @@ -31,7 +31,7 @@ #include "systemtray.h" SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent) - : AbstractNotificationBackend(parent) + : AbstractNotificationBackend(parent), _activeId(0) { NotificationSettings notificationSettings; _showBubble = notificationSettings.value("Systray/ShowBubble", true).toBool(); @@ -40,7 +40,7 @@ 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()), this, SIGNAL(activated())); + connect(QtUi::mainWindow()->systemTray(), SIGNAL(messageClicked()), SLOT(notificationActivated())); } void SystrayNotificationBackend::notify(const Notification ¬ification) { @@ -76,6 +76,7 @@ void SystrayNotificationBackend::showBubble() { // for now, we just show the last message if(_notifications.isEmpty()) return; Notification n = _notifications.takeLast(); + _activeId = n.notificationId; 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); @@ -88,6 +89,10 @@ void SystrayNotificationBackend::closeBubble() { #endif } +void SystrayNotificationBackend::notificationActivated() { + emit activated(_activeId); +} + void SystrayNotificationBackend::showBubbleChanged(const QVariant &v) { _showBubble = v.toBool(); } diff --git a/src/qtui/systraynotificationbackend.h b/src/qtui/systraynotificationbackend.h index 2a7784bd..f4e2c6e5 100644 --- a/src/qtui/systraynotificationbackend.h +++ b/src/qtui/systraynotificationbackend.h @@ -40,6 +40,7 @@ public: private slots: void showBubble(); void closeBubble(); + void notificationActivated(); void animateChanged(const QVariant &); void showBubbleChanged(const QVariant &); @@ -50,6 +51,7 @@ private: bool _showBubble; bool _animate; QList _notifications; + uint _activeId; }; class SystrayNotificationBackend::ConfigWidget : public SettingsPage { diff --git a/src/uisupport/abstractnotificationbackend.h b/src/uisupport/abstractnotificationbackend.h index 7882a21e..01324d40 100644 --- a/src/uisupport/abstractnotificationbackend.h +++ b/src/uisupport/abstractnotificationbackend.h @@ -57,7 +57,7 @@ public: signals: //! May be emitted by the notification to tell the MainWin to raise itself - void activated(); + void activated(uint notificationId = 0); };