diff --git a/CMakeLists.txt b/CMakeLists.txt
index d7836f9..d04c1ea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,9 +10,9 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(GNUInstallDirs)
-find_package(QT NAMES Qt6 Qt5 COMPONENTS Core LinguistTools DBus Network REQUIRED)
-find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core LinguistTools DBus Network REQUIRED)
-include_directories()
+find_package(QT NAMES Qt6 Qt5 COMPONENTS Core LinguistTools DBus Network Gui REQUIRED)
+find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core LinguistTools DBus Network Gui REQUIRED)
+
add_subdirectory(notification-server)
add_subdirectory(libukui-notification)
diff --git a/notification-server/dbus/org.freedesktop.Notifications.xml b/dbus/org.freedesktop.Notifications.xml
similarity index 100%
rename from notification-server/dbus/org.freedesktop.Notifications.xml
rename to dbus/org.freedesktop.Notifications.xml
diff --git a/dbus/org.ukui.NotificationClient.xml b/dbus/org.ukui.NotificationClient.xml
new file mode 100644
index 0000000..caecb8c
--- /dev/null
+++ b/dbus/org.ukui.NotificationClient.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notification-server/dbus/org.ukui.notificationServer.xml b/dbus/org.ukui.NotificationServer.xml
similarity index 62%
rename from notification-server/dbus/org.ukui.notificationServer.xml
rename to dbus/org.ukui.NotificationServer.xml
index d6bb928..74539fa 100644
--- a/notification-server/dbus/org.ukui.notificationServer.xml
+++ b/dbus/org.ukui.NotificationServer.xml
@@ -3,5 +3,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/libukui-notification/CMakeLists.txt b/libukui-notification/CMakeLists.txt
index e69de29..14439fe 100644
--- a/libukui-notification/CMakeLists.txt
+++ b/libukui-notification/CMakeLists.txt
@@ -0,0 +1,20 @@
+set(ukui-notification_LIB_SRCS
+ notification-client.cpp
+ notification-client.h
+ popup-notification.h
+ popup-notification.cpp
+ ukui-notification_global.h
+ notification-client-private.h
+ )
+
+qt_add_dbus_interface(ukui-notification_LIB_SRCS ../dbus/org.freedesktop.Notifications.xml notifications_interface)
+qt_add_dbus_adaptor(ukui-notification_LIB_SRCS ../dbus/org.ukui.NotificationClient.xml notification-client-private.h UkuiNotification::NotificationClientPrivate)
+
+add_library(ukui-notification SHARED ${ukui-notification_LIB_SRCS})
+target_link_libraries(ukui-notification
+ PRIVATE
+ Qt${QT_VERSION_MAJOR}::Core
+ Qt${QT_VERSION_MAJOR}::DBus
+ Qt${QT_VERSION_MAJOR}::Gui
+ )
+target_compile_definitions(ukui-notification PRIVATE UKUINOTIFICATION_LIBRARY)
\ No newline at end of file
diff --git a/libukui-notification/notification-client-private.h b/libukui-notification/notification-client-private.h
new file mode 100644
index 0000000..d7d8275
--- /dev/null
+++ b/libukui-notification/notification-client-private.h
@@ -0,0 +1,35 @@
+//
+// Created by zpf on 23-2-3.
+//
+
+#ifndef UKUI_NOTIFICATION_NOTIFICATION_CLIENT_PRIVATE_H
+#define UKUI_NOTIFICATION_NOTIFICATION_CLIENT_PRIVATE_H
+#include
+#include
+#include "notifications_interface.h"
+namespace UkuiNotification {
+class NotificationClientPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit NotificationClientPrivate(QObject *parent = nullptr);
+ ~NotificationClientPrivate() override;
+ bool registerClient();
+ static QString clientServicePath();
+ static QString clientServiceInterface();
+
+ void Notify(const QString &app_name,
+ uint replaces_id,
+ const QString &app_icon,
+ const QString &summary,
+ const QString &body,
+ const QStringList &actions,
+ const QVariantMap &hints,
+ int timeout);
+ void notificationClosed(uint id, uint reason);
+private:
+ OrgFreedesktopNotificationsInterface* m_notificationsInterface = nullptr;
+ QDBusInterface *m_serverInterface = nullptr;
+};
+}
+#endif //UKUI_NOTIFICATION_NOTIFICATION_CLIENT_PRIVATE_H
diff --git a/libukui-notification/notification-client.cpp b/libukui-notification/notification-client.cpp
new file mode 100644
index 0000000..ba5cdf5
--- /dev/null
+++ b/libukui-notification/notification-client.cpp
@@ -0,0 +1,99 @@
+//
+// Created by zpf on 23-2-2.
+//
+
+#include "notification-client.h"
+#include "notification-client-private.h"
+#include
+#include "notificationclientadaptor.h"
+
+using namespace UkuiNotification;
+
+NotificationClientPrivate::NotificationClientPrivate(QObject *parent) : QObject(parent)
+{
+}
+
+NotificationClientPrivate::~NotificationClientPrivate()
+{
+ if(m_notificationsInterface) {
+ m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("UnRegisterClient"));
+ }
+}
+
+bool NotificationClientPrivate::registerClient()
+{
+ new NotificationClientAdaptor(this);
+ QDBusConnection conn = QDBusConnection::sessionBus();
+
+
+ if(!conn.registerObject(clientServicePath(), clientServiceInterface(), this)) {
+ qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError();
+ return false;
+ }
+ m_notificationsInterface = new OrgFreedesktopNotificationsInterface(QStringLiteral("org.freedesktop.Notifications"),
+ QStringLiteral("/org/freedesktop/Notifications"),
+ conn,
+ this);
+ if(!m_notificationsInterface->isValid()) {
+ qWarning() << "Failed to creat dbus interface for notification server!" << conn.lastError();
+ return false;
+ }
+ connect(m_notificationsInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed,
+ this, &NotificationClientPrivate::notificationClosed);
+
+ if(!m_serverInterface) {
+ m_serverInterface = new QDBusInterface(QStringLiteral("org.freedesktop.Notifications"),
+ QStringLiteral("/org/ukui/NotificationServer"),
+ QStringLiteral("org.ukui.NotificationServer"),
+ conn,
+ this);
+ if(!m_serverInterface->isValid()) {
+ qWarning() << "Failed to create notification server interface! " << conn.lastError();
+ return false;
+ }
+ }
+ QDBusMessage reply = m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("RegisterClient"));
+ if (reply.type() == QDBusMessage::ErrorMessage) {
+ qWarning() << "Failed to call RegisterClient!" << conn.lastError();
+ return false;
+ }
+ return true;
+}
+
+QString NotificationClientPrivate::clientServicePath()
+{
+ return QStringLiteral("/NotificationClient");
+}
+
+QString NotificationClientPrivate::clientServiceInterface()
+{
+ return QStringLiteral("org.ukui.NotificationClient");
+}
+
+void NotificationClientPrivate::Notify(const QString &app_name, uint replaces_id, const QString &app_icon,
+ const QString &summary, const QString &body, const QStringList &actions,
+ const QVariantMap &hints, int timeout)
+{
+}
+
+void NotificationClientPrivate::notificationClosed(uint id, uint reason)
+{
+ if(!m_notificationsInterface) {
+ return;
+ }
+ QDBusMessage reply = m_notificationsInterface->callWithArgumentList(QDBus::NoBlock, QStringLiteral("CloseNotification"), {id, reason});
+ if (reply.type() == QDBusMessage::ErrorMessage) {
+ qWarning() << "Failed to call CloseNotification!" << QDBusConnection::sessionBus().lastError();
+ }
+}
+
+NotificationClient::NotificationClient(QObject *parent) : QObject(parent), d(new NotificationClientPrivate(this))
+{
+}
+
+NotificationClient::~NotificationClient() = default;
+
+bool NotificationClient::registerClient()
+{
+ return d->registerClient();
+}
\ No newline at end of file
diff --git a/libukui-notification/notification-client.h b/libukui-notification/notification-client.h
new file mode 100644
index 0000000..aa89aa4
--- /dev/null
+++ b/libukui-notification/notification-client.h
@@ -0,0 +1,24 @@
+//
+// Created by zpf on 23-2-2.
+//
+
+#ifndef UKUI_NOTIFICATION_NOTIFICATION_CLIENT_H
+#define UKUI_NOTIFICATION_NOTIFICATION_CLIENT_H
+#include "ukui-notification_global.h"
+#include
+namespace UkuiNotification {
+class NotificationClientPrivate;
+class UKUINOTIFICATION_EXPORT NotificationClient : public QObject
+{
+ Q_OBJECT
+public:
+ NotificationClient(QObject *parent);
+ ~NotificationClient() override;
+ bool registerClient();
+private:
+ NotificationClientPrivate *d = nullptr;
+};
+
+} // UkuiNotification
+
+#endif //UKUI_NOTIFICATION_NOTIFICATION_CLIENT_H
diff --git a/libukui-notification/popup-notification.cpp b/libukui-notification/popup-notification.cpp
new file mode 100644
index 0000000..c7e0ec8
--- /dev/null
+++ b/libukui-notification/popup-notification.cpp
@@ -0,0 +1,175 @@
+//
+// Created by zpf on 23-2-2.
+//
+
+#include "popup-notification.h"
+class PopupNotificationPrvate
+{
+public:
+ PopupNotificationPrvate();
+ ~PopupNotificationPrvate();
+
+};
+PopupNotificationPrvate::PopupNotificationPrvate()
+{
+
+}
+
+PopupNotificationPrvate::~PopupNotificationPrvate()
+{
+
+}
+
+PopupNotification::PopupNotification(uint id, QObject *parent) : QObject(parent)
+{
+
+}
+
+PopupNotification::PopupNotification(const PopupNotification &other)
+{
+
+}
+
+PopupNotification &PopupNotification::operator=( const PopupNotification &other)
+{
+ *d = *other.d;
+ return *this;
+}
+
+PopupNotification &PopupNotification::operator=(PopupNotification &&other) Q_DECL_NOEXCEPT
+{
+ d = other.d;
+ other.d = nullptr;
+ return *this;
+}
+PopupNotification::~PopupNotification()
+{
+
+}
+
+QString PopupNotification::applicationName() const
+{
+ return QString();
+}
+
+void PopupNotification::setApplicationName(const QString &applicationName)
+{
+
+}
+
+QString PopupNotification::icon() const
+{
+ return QString();
+}
+
+void PopupNotification::setIcon(const QString &icon)
+{
+
+}
+
+QString PopupNotification::summary() const
+{
+ return QString();
+}
+
+void PopupNotification::setSummary(const QString &summary)
+{
+
+}
+
+QString PopupNotification::body() const
+{
+ return QString();
+}
+
+void PopupNotification::setBody(const QString &body)
+{
+
+}
+
+bool PopupNotification::hasDefaultAction() const
+{
+ return false;
+}
+
+void PopupNotification::setActions(const QStringList &actions)
+{
+
+}
+
+QList> PopupNotification::getActions()
+{
+ return QList>();
+}
+
+QVariantMap PopupNotification::hints() const
+{
+ return QVariantMap();
+}
+
+void PopupNotification::setHints(const QVariantMap &hints)
+{
+
+}
+
+int PopupNotification::timeout() const
+{
+ return 0;
+}
+
+void PopupNotification::setTimeout(int timeout)
+{
+
+}
+
+QDateTime PopupNotification::created() const
+{
+ return QDateTime();
+}
+
+void PopupNotification::setCreated(const QDateTime &created)
+{
+
+}
+
+bool PopupNotification::enableActionIcons() const
+{
+ return false;
+}
+
+QString PopupNotification::category() const
+{
+ return QString();
+}
+
+QString PopupNotification::desktopEntry() const
+{
+ return QString();
+}
+
+QImage PopupNotification::image() const
+{
+ return QImage();
+}
+
+bool PopupNotification::resident() const
+{
+ return false;
+}
+
+QString PopupNotification::soundFile() const
+{
+ return QString();
+}
+
+bool PopupNotification::transient() const
+{
+ return false;
+}
+
+void PopupNotification::setUrgency(PopupNotification::Urgency urgency)
+{
+
+}
+
+
diff --git a/libukui-notification/popup-notification.h b/libukui-notification/popup-notification.h
new file mode 100644
index 0000000..bb7126a
--- /dev/null
+++ b/libukui-notification/popup-notification.h
@@ -0,0 +1,80 @@
+//
+// Created by zpf on 23-2-2.
+//
+
+#ifndef UKUI_NOTIFICATION_POPUP_NOTIFICATION_H
+#define UKUI_NOTIFICATION_POPUP_NOTIFICATION_H
+#include "ukui-notification_global.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+class PopupNotificationPrvate;
+class UKUINOTIFICATION_EXPORT PopupNotification : public QObject
+{
+ Q_OBJECT
+public:
+/**
+ * The notification urgency.
+ */
+ enum Urgency {
+ LowUrgency = 1 << 0,
+ NormalUrgency = 1 << 1,
+ CriticalUrgency = 1 << 2,
+ };
+ Q_ENUM(Urgency)
+ Q_DECLARE_FLAGS(Urgencies, Urgency)
+ Q_FLAG(Urgencies)
+
+ explicit PopupNotification(uint id = 0, QObject *parent = nullptr);
+ PopupNotification(const PopupNotification &other);
+ PopupNotification &operator=(const PopupNotification &other);
+ PopupNotification &operator=(PopupNotification &&other) Q_DECL_NOEXCEPT;
+ ~PopupNotification();
+
+ QString applicationName() const;
+ void setApplicationName(const QString &applicationName);
+
+ QString icon() const;
+ void setIcon(const QString &icon);
+
+ QString summary() const;
+ void setSummary(const QString &summary);
+
+ QString body() const;
+ void setBody(const QString &body);
+
+ bool hasDefaultAction() const;
+ void setActions(const QStringList &actions);
+ QList> getActions();
+
+ QVariantMap hints() const;
+ void setHints(const QVariantMap &hints);
+
+ int timeout() const;
+ void setTimeout(int timeout);
+
+ QDateTime created() const;
+ void setCreated(const QDateTime &created);
+
+ //hints
+ bool enableActionIcons() const;
+ QString category() const;
+ QString desktopEntry() const;
+ QImage image() const;
+ bool resident() const;
+ QString soundFile() const;
+ bool transient() const;
+
+ void setUrgency(Urgency urgency);
+
+
+private:
+ PopupNotificationPrvate *d = nullptr;
+};
+
+
+#endif //UKUI_NOTIFICATION_POPUP_NOTIFICATION_H
diff --git a/libukui-notification/ukui-notification_global.h b/libukui-notification/ukui-notification_global.h
new file mode 100644
index 0000000..83887e2
--- /dev/null
+++ b/libukui-notification/ukui-notification_global.h
@@ -0,0 +1,16 @@
+//
+// Created by zpf on 23-2-2.
+//
+
+#ifndef UKUINOTIFICATION_GLOBAL_H
+#define UKUINOTIFICATION_GLOBAL_H
+
+#include
+
+#if defined(UKUINOTIFICATION_LIBRARY)
+# define UKUINOTIFICATION_EXPORT Q_DECL_EXPORT
+#else
+# define UKUINOTIFICATION_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // UKUINOTIFICATION_GLOBAL_H
diff --git a/notification-server/CMakeLists.txt b/notification-server/CMakeLists.txt
index bef5b2e..7cecbf9 100644
--- a/notification-server/CMakeLists.txt
+++ b/notification-server/CMakeLists.txt
@@ -13,9 +13,14 @@ set(notificationServer_SRCS
${3rdParties_DIR}qtsinglecoreapplication.cpp
${3rdParties_DIR}qtlocalpeer.h
${3rdParties_DIR}qtlocalpeer.cpp
- notification-server-application.cpp notification-server-application.h notification.cpp notification.h)
-qt_add_dbus_adaptor(notificationServer_SRCS dbus/org.freedesktop.Notifications.xml server-private.h NotificationServer::ServerPrivate)
-qt_add_dbus_adaptor(notificationServer_SRCS dbus/org.ukui.notificationServer.xml server-private.h NotificationServer::ServerPrivate)
+ notification-server-application.cpp
+ notification-server-application.h
+ notification.cpp
+ notification.h
+ )
+
+qt_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.freedesktop.Notifications.xml server-private.h NotificationServer::ServerPrivate)
+qt_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.ukui.NotificationServer.xml server-private.h NotificationServer::ServerPrivate)
add_executable(ukui-notification-server ${notificationServer_SRCS})
target_include_directories(ukui-notification-server PUBLIC ${3rdParties_DIR})
diff --git a/notification-server/server-private.h b/notification-server/server-private.h
index 8a52b7b..0dfd010 100644
--- a/notification-server/server-private.h
+++ b/notification-server/server-private.h
@@ -12,14 +12,18 @@ namespace NotificationServer {
class ServerPrivate : public QObject, protected QDBusContext
{
Q_OBJECT
+//dbus interface
public:
- ServerPrivate(QObject *parent);
- ~ServerPrivate();
- bool init();
-
- static QString notificationServiceName();
- static QString notificationServicePath();
- static QString notificationServiceInterface();
+ /**
+ * The reason a notification was closed
+ */
+ enum CloseReason {
+ Expired = 1, // The notification expired(timed out).
+ DismissedByUser = 2, // The notification was dismissed by the user.
+ Revoked = 3, //< The notification was closed by sender by a call to CloseNotification.
+ Undefined = 4, //Undefined/reserved reasons.
+ };
+ Q_ENUM(CloseReason)
QStringList GetCapabilities() const;
uint Notify(const QString &app_name,
@@ -41,12 +45,27 @@ public:
* 注销
*/
void UnRegisterClient();
+ /**
+ * 通知中心关闭通知
+ * @param id 通知id
+ * @param reason 关闭原因
+ */
+ void CloseNotification(uint id, uint);
Q_SIGNALS:
void NotificationClosed(uint id, uint reason);
void ActionInvoked(uint id, const QString &actionKey);
void ActivationToken(uint id, const QString &ActivationToken);
+public:
+ explicit ServerPrivate(QObject *parent = nullptr);
+ ~ServerPrivate() override;
+ bool init();
+
+ static QString notificationServiceName();
+ static QString notificationServicePath();
+ static QString notificationServiceInterface();
private:
QDBusServiceWatcher *m_notificationWatchers = nullptr;
+ uint m_increasedNotificationId = 1;
};
diff --git a/notification-server/server.cpp b/notification-server/server.cpp
index a52d56d..598ee61 100644
--- a/notification-server/server.cpp
+++ b/notification-server/server.cpp
@@ -7,12 +7,13 @@
#include "server-private.h"
#include "notificationsadaptor.h"
-namespace NotificationServer {
+using namespace NotificationServer;
ServerPrivate::ServerPrivate(QObject *parent) : QObject(parent), m_notificationWatchers(new QDBusServiceWatcher(this))
{
m_notificationWatchers->setConnection(QDBusConnection::sessionBus());
m_notificationWatchers->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
- connect(m_notificationWatchers, &QDBusServiceWatcher::serviceUnregistered, m_notificationWatchers, &QDBusServiceWatcher::removeWatchedService);
+ connect(m_notificationWatchers, &QDBusServiceWatcher::serviceUnregistered,
+ m_notificationWatchers, &QDBusServiceWatcher::removeWatchedService);
}
ServerPrivate::~ServerPrivate() = default;
@@ -25,7 +26,24 @@ QStringList ServerPrivate::GetCapabilities() const
uint ServerPrivate::Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary,
const QString &body, const QStringList &actions, const QVariantMap &hints, int timeout)
{
- return 0;
+ uint id = 0;
+ if(replaces_id > 0) {
+ id = replaces_id;
+ } else {
+ id = m_increasedNotificationId++;
+ }
+
+ //TODO 在hint中增加DISPLAY信息。
+
+ for(const QString &service : m_notificationWatchers->watchedServices()) {
+ QDBusMessage msg = QDBusMessage::createMethodCall(service,
+ QStringLiteral("/NotificationClient"),
+ QStringLiteral("org.ukui.NotificationClient"),
+ QStringLiteral("Notify"));
+ msg.setArguments({app_name, id, app_icon, summary, body, actions, hints, timeout});
+ QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
+ }
+ return id;
}
QString ServerPrivate::GetServerInformation(QString &vendor, QString &version, QString &specVersion) const
@@ -35,7 +53,14 @@ QString ServerPrivate::GetServerInformation(QString &vendor, QString &version, Q
void ServerPrivate::CloseNotification(uint id)
{
-
+ for(const QString &service : m_notificationWatchers->watchedServices()) {
+ QDBusMessage msg = QDBusMessage::createMethodCall(service,
+ QStringLiteral("/NotificationClient"),
+ QStringLiteral("org.ukui.NotificationClient"),
+ QStringLiteral("CloseNotification"));
+ msg.setArguments({id, CloseReason::Revoked});
+ QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
+ }
}
bool ServerPrivate::init()
@@ -81,6 +106,10 @@ void ServerPrivate::UnRegisterClient()
m_notificationWatchers->removeWatchedService(message().service());
}
+void ServerPrivate::CloseNotification(uint id, uint)
+{
+}
+
Server::Server(QObject *parent): QObject(parent), d(new ServerPrivate(this))
{
}
@@ -96,5 +125,4 @@ bool Server::init()
return d->init();
}
-Server::~Server() = default;
-} // NotificationServer
\ No newline at end of file
+Server::~Server() = default;
\ No newline at end of file