[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: [PATCH] Detecting notification popup server capabilities
From: Aurélien_Gâteau <aurelien.gateau () canonical ! com>
Date: 2009-08-28 14:01:55
Message-ID: 4A97E353.7040504 () canonical ! com
[Download RAW message or body]
Hi,
As you (may) know, KDE visual notifications (aka popup or bubbles) are
now using FreeDesktop notification spec, this makes it possible for a
GNOME app running on KDE to have its notifications displayed by Plasma,
or for a KDE app running on GNOME to have its notifications displayed by
notification-daemon (the original implementation) or notify-osd (Ubuntu
implemention of the spec).
You may also know that notify-osd is (in)famous for not supporting
notification with actions. A side effect of this is that KDE
applications running on a desktop which uses notify-osd now gets ugly
dialog boxes whenever they try to show a notification with actions.
The attached patches add a new static method to KNotification:
popupServerCapabilities(). This method makes it possible for KDE
applications to check what the notification server supports and act
accordingly.
What do you think about them? Can they go in?
Aurélien
["0001-Added-a-DBus-adaptor-to-NotifyByPopup-so-that-applica.diff" (text/x-diff)]
From 94092422de9e7535b046736a555a95f7d305f187 Mon Sep 17 00:00:00 2001
From: Aurelien Gateau <aurelien.gateau@canonical.com>
Date: Thu, 27 Aug 2009 17:50:58 +0200
Subject: [PATCH] Added a DBus adaptor to NotifyByPopup, so that applications can \
check the capabilities of the popup notification server
---
runtime/knotify/notifybypopup.cpp | 36 ++++++++++++++++++++++++++++++++++++
runtime/knotify/notifybypopup.h | 21 +++++++++++++++++++++
2 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/runtime/knotify/notifybypopup.cpp b/runtime/knotify/notifybypopup.cpp
index 91c9fee..57b6cf8 100644
--- a/runtime/knotify/notifybypopup.cpp
+++ b/runtime/knotify/notifybypopup.cpp
@@ -46,6 +46,9 @@ static const char dbusPath[] = "/org/freedesktop/Notifications";
NotifyByPopup::NotifyByPopup(QObject *parent)
: KNotifyPlugin(parent) , m_animationTimer(0), m_dbusServiceExists(false)
{
+ new NotifyByPopupAdaptor(this);
+ QDBusConnection::sessionBus().registerObject("/NotifyByPopup", this);
+
QRect screen = QApplication::desktop()->availableGeometry();
m_nextPosition = screen.top();
@@ -292,6 +295,8 @@ void NotifyByPopup::slotServiceOwnerChanged( const QString & \
serviceName,
kWarning(300) << "warning: failed to connect to NotificationClosed dbus signal";
}
}
+
+ emit popupServerChanged();
}
}
@@ -435,4 +440,35 @@ void NotifyByPopup::closeNotificationDBus(int id)
}
+QStringList NotifyByPopup::popupServerCapabilities() const
+{
+ if (!m_dbusServiceExists) {
+ // Return capabilities of the KPassivePopup implementation
+ return QStringList() << "actions" << "body" << "body-hyperlinks" << "body-markup";
+ }
+ QDBusMessage m = QDBusMessage::createMethodCall( dbusServiceName, dbusPath, \
dbusInterfaceName, "GetCapabilities" ); + QDBusMessage replyMsg = \
QDBusConnection::sessionBus().call(m); + if(replyMsg.type() != \
QDBusMessage::ReplyMessage) { + kWarning(300) << "Error while calling popup server \
GetCapabilities()"; + return QStringList();
+ }
+
+ if (replyMsg.arguments().isEmpty()) {
+ kWarning(300) << "popup server GetCapabilities() returned an empty reply";
+ return QStringList();
+ }
+
+ return replyMsg.arguments().at(0).toStringList();
+}
+
+NotifyByPopupAdaptor::NotifyByPopupAdaptor(QObject *parent)
+: QDBusAbstractAdaptor(parent)
+{
+ setAutoRelaySignals(true);
+}
+
+QStringList NotifyByPopupAdaptor::popupServerCapabilities() const
+{
+ return static_cast<NotifyByPopup*>(parent())->popupServerCapabilities();
+}
#include "notifybypopup.moc"
diff --git a/runtime/knotify/notifybypopup.h b/runtime/knotify/notifybypopup.h
index 6e7fc1d..80ed5e0 100644
--- a/runtime/knotify/notifybypopup.h
+++ b/runtime/knotify/notifybypopup.h
@@ -23,6 +23,7 @@
#define NOTIFYBYPOPUP_H
#include "knotifyplugin.h"
+#include <QDBusAbstractAdaptor>
#include <QMap>
#include <QHash>
@@ -38,6 +39,12 @@ class NotifyByPopup : public KNotifyPlugin
virtual void notify(int id , KNotifyConfig *config);
virtual void close( int id );
virtual void update(int id, KNotifyConfig *config);
+
+ QStringList popupServerCapabilities() const;
+
+ Q_SIGNALS:
+ void popupServerChanged();
+
private:
QMap<int, KPassivePopup * > m_popups;
// the y coordinate of the next position popup should appears
@@ -87,4 +94,18 @@ class NotifyByPopup : public KNotifyPlugin
QHash<int,uint> m_idMap;
};
+class NotifyByPopupAdaptor : public QDBusAbstractAdaptor
+{ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.kde.NotifyByPopup")
+
+public:
+ NotifyByPopupAdaptor(QObject *);
+
+public Q_SLOTS:
+ QStringList popupServerCapabilities() const;
+
+Q_SIGNALS:
+ void popupServerChanged();
+};
+
#endif
--
1.6.3.3
["0001-New-method-popupServerCapabilities.diff" (text/x-diff)]
From f6cd930732b13cb64eab796b3122787826948912 Mon Sep 17 00:00:00 2001
From: Aurelien Gateau <aurelien.gateau@canonical.com>
Date: Fri, 28 Aug 2009 15:35:13 +0200
Subject: [PATCH] New method: popupServerCapabilities()
Makes it possible to check what the server implementing the FreeDesktop.org \
notification spec can handle.
---
kdeui/util/knotification.cpp | 4 ++
kdeui/util/knotification.h | 43 +++++++++++++++++++++++++
kdeui/util/knotificationmanager.cpp | 59 ++++++++++++++++++++++++++++++++++-
kdeui/util/knotificationmanager_p.h | 9 +++++
4 files changed, 114 insertions(+), 1 deletions(-)
diff --git a/kdeui/util/knotification.cpp b/kdeui/util/knotification.cpp
index 59832c1..b8c007d 100644
--- a/kdeui/util/knotification.cpp
+++ b/kdeui/util/knotification.cpp
@@ -417,5 +417,9 @@ bool KNotification::eventFilter( QObject * watched, QEvent * \
event ) return false;
}
+KNotification::PopupServerCapabilities KNotification::popupServerCapabilities()
+{
+ return KNotificationManager::self()->popupServerCapabilities();
+}
#include "knotification.moc"
diff --git a/kdeui/util/knotification.h b/kdeui/util/knotification.h
index 22c0d1e..1a31c84 100644
--- a/kdeui/util/knotification.h
+++ b/kdeui/util/knotification.h
@@ -255,6 +255,38 @@ public:
*/
enum StandardEvent { Notification , Warning , Error , Catastrophe };
+ /**
+ * What the popup notification server is capable of doing
+ */
+ enum PopupServerCapability
+ {
+ /**
+ * The server can show actions
+ */
+ ActionCapability = 1<<0,
+
+ /**
+ * The server can show a text in addition to a title. Some
+ * implementations may only show the title (for instance, onscreen
+ * displays, marquee/scrollers)
+ */
+ TextCapability = 1<<1,
+
+ /**
+ * The server supports hyperlinks in the notifications.
+ */
+ HyperLinkCapability = 1<<2,
+
+ /**
+ * Supports markup in the text. If marked up text is sent to a server
+ * that does not give this cap, the markup will show through as regular
+ * text so must be stripped clientside.
+ */
+ MarkupCapability = 1<<3
+ };
+
+ Q_DECLARE_FLAGS(PopupServerCapabilities, PopupServerCapability)
+
/**
* Create a new notification.
*
@@ -567,11 +599,22 @@ public:
* @param widget the widget the notification refers to
*/
static void beep( const QString& reason = QString() , QWidget *widget=0L);
+
+ /**
+ * What is the popup notification server capable of showing.
+ *
+ * To ensure better cross-desktop integrations, applications should check
+ * whether a capability is available before using it.
+ *
+ * @since 4.4
+ */
+ static PopupServerCapabilities popupServerCapabilities();
//prevent warning
using QObject::event;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KNotification::NotificationFlags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(KNotification::PopupServerCapabilities)
#endif
diff --git a/kdeui/util/knotificationmanager.cpp \
b/kdeui/util/knotificationmanager.cpp index 01cffd8..efa1df3 100644
--- a/kdeui/util/knotificationmanager.cpp
+++ b/kdeui/util/knotificationmanager.cpp
@@ -32,13 +32,52 @@
#include <klocale.h>
typedef QHash<QString,QString> Dict;
+typedef QHash<QString,KNotification::PopupServerCapability> CapabilityDict;
struct KNotificationManager::Private
{
QHash<int , KNotification*> notifications;
QDBusInterface *knotify;
+ QDBusInterface *notifyByPopup;
+ bool popupServerCapabilitiesInitialized;
+ KNotification::PopupServerCapabilities popupServerCapabilities;
+
+ void initPopupServerCapabilities();
};
+void KNotificationManager::Private::initPopupServerCapabilities()
+{
+ if (popupServerCapabilitiesInitialized) {
+ return;
+ }
+
+ static CapabilityDict translator;
+ if (translator.isEmpty()) {
+ translator.insert("actions" , KNotification::ActionCapability);
+ translator.insert("body" , KNotification::TextCapability);
+ translator.insert("body-hyperlinks" , KNotification::HyperLinkCapability);
+ translator.insert("body-markup" , KNotification::MarkupCapability);
+ }
+
+ popupServerCapabilities = 0;
+
+ QDBusReply<QStringList> reply = notifyByPopup->call("popupServerCapabilities");
+ if (notifyByPopup->lastError().isValid()) {
+ kWarning() << "Error asking popupServerCapabilities():" << \
notifyByPopup->lastError().message(); + return;
+ }
+
+ CapabilityDict::ConstIterator end = translator.end();
+ foreach(const QString& str, reply.value()) {
+ CapabilityDict::ConstIterator it = translator.find(str);
+ if (it != end) {
+ popupServerCapabilities |= it.value();
+ }
+ }
+
+ popupServerCapabilitiesInitialized = true;
+}
+
KNotificationManager * KNotificationManager::self()
{
K_GLOBAL_STATIC(KNotificationManager, s_self)
@@ -49,6 +88,8 @@ KNotificationManager * KNotificationManager::self()
KNotificationManager::KNotificationManager()
: d(new Private)
{
+ d->popupServerCapabilitiesInitialized = false;
+ d->popupServerCapabilities = 0;
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.knotify")) \
{ QString error;
int ret = KToolInvocation::startServiceByDesktopPath("knotify4.desktop",
@@ -67,13 +108,19 @@ KNotificationManager::KNotificationManager()
QLatin1String("org.kde.KNotify"),
QLatin1String("notificationActivated"),
this, SLOT(notificationActivated(int,int)));
-
+ d->notifyByPopup =
+ new QDBusInterface(QLatin1String("org.kde.knotify"), \
QLatin1String("/NotifyByPopup"), QLatin1String("org.kde.NotifyByPopup"), \
QDBusConnection::sessionBus(), this); + \
d->notifyByPopup->connection().connect(QLatin1String("org.kde.knotify"), \
QLatin1String("/NotifyByPopup"), + \
QLatin1String("org.kde.NotifyByPopup"), + \
QLatin1String("popupServerChanged"), + this, \
SLOT(popupServerChanged())); }
KNotificationManager::~KNotificationManager()
{
delete d->knotify;
+ delete d->notifyByPopup;
delete d;
}
@@ -179,5 +226,15 @@ void KNotificationManager::reemit(KNotification * n, int id)
d->knotify->call(QDBus::NoBlock, "reemit", id, contextList);
}
+KNotification::PopupServerCapabilities \
KNotificationManager::popupServerCapabilities() const +{
+ d->initPopupServerCapabilities();
+ return d->popupServerCapabilities;
+}
+
+void KNotificationManager::popupServerChanged()
+{
+ d->popupServerCapabilitiesInitialized = false;
+}
#include "knotificationmanager_p.moc"
diff --git a/kdeui/util/knotificationmanager_p.h \
b/kdeui/util/knotificationmanager_p.h index 2500abc..f263417 100644
--- a/kdeui/util/knotificationmanager_p.h
+++ b/kdeui/util/knotificationmanager_p.h
@@ -66,9 +66,18 @@ public:
*/
void reemit(KNotification *n, int id);
+ /**
+ * What is the popup notification server capable of showing.
+ *
+ * To ensure better cross-desktop integration, applications should check
+ * whether a capability is available before using it.
+ */
+ KNotification::PopupServerCapabilities popupServerCapabilities() const;
+
private Q_SLOTS:
void notificationClosed( int id );
void notificationActivated( int id, int action);
+ void popupServerChanged();
private:
struct Private;
--
1.6.3.3
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic