diff --git a/dbus/org.ukui.NotificationServer.xml b/dbus/org.ukui.NotificationServer.xml
index 2a37cf7..d250743 100644
--- a/dbus/org.ukui.NotificationServer.xml
+++ b/dbus/org.ukui.NotificationServer.xml
@@ -10,6 +10,7 @@
+
diff --git a/libukui-notification/CMakeLists.txt b/libukui-notification/CMakeLists.txt
index 9912aa2..c4b68c5 100644
--- a/libukui-notification/CMakeLists.txt
+++ b/libukui-notification/CMakeLists.txt
@@ -1,11 +1,22 @@
+set(VERSION_MAJOR 1)
+set(VERSION_MINOR 0)
+set(VERSION_MICRO 0)
+set(UKUI_NOTIFICATION_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO})
+find_package(KF5WindowSystem)
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
- )
+ notification-client.cpp
+ notification-client.h
+ popup-notification.h
+ popup-notification.cpp
+ ukui-notification_global.h
+ notification-client-private.h
+ utils.h
+ utils.cpp)
+set(HEADERS
+ notification-client.h
+ popup-notification.h
+ ukui-notification_global.h
+ utils.h)
if(COMMAND qt_add_dbus_interface)
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)
@@ -19,6 +30,7 @@ target_link_libraries(ukui-notification
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::DBus
Qt${QT_VERSION_MAJOR}::Gui
+ KF5::WindowSystem
)
target_compile_definitions(ukui-notification PRIVATE UKUINOTIFICATION_LIBRARY)
include(CMakePackageConfigHelpers)
@@ -31,4 +43,11 @@ set(PC_INSTALL_DIR "/usr/lib/pkgconfig")
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/ukui-notification.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/ukui-notification.pc.in"
- INSTALL_DESTINATION ${PC_INSTALL_DIR})
\ No newline at end of file
+ INSTALL_DESTINATION ${PC_INSTALL_DIR})
+set_target_properties(ukui-notification PROPERTIES
+ VERSION ${UKUI_NOTIFICATION_VERSION}
+ SOVERSION "1"
+ OUTPUT_NAME ukui-notification
+ )
+install(TARGETS ukui-notification DESTINATION /usr/lib)
+install(FILES ${HEADERS} DESTINATION /usr/include/ukui-notification)
\ No newline at end of file
diff --git a/libukui-notification/notification-client-private.h b/libukui-notification/notification-client-private.h
index 2d56092..b53f2f4 100644
--- a/libukui-notification/notification-client-private.h
+++ b/libukui-notification/notification-client-private.h
@@ -28,11 +28,14 @@ public:
const QVariantMap &hints,
int timeout);
void closeNotification(uint id, NotificationClient::CloseReason reason);
+ void invokeAction(uint id, const QString &action_key, const QString &action, const QString &display);
+
private Q_SLOTS:
void notificationClosed(uint id, uint reason);
void serviceChange(const QString &service, const QString &oldOwner, const QString &newOwner);
bool registerClient();
void unRegisterClient();
+
private:
OrgFreedesktopNotificationsInterface* m_notificationsInterface = nullptr;
QDBusInterface *m_serverInterface = nullptr;
diff --git a/libukui-notification/notification-client.cpp b/libukui-notification/notification-client.cpp
index 0fdbe97..483e629 100644
--- a/libukui-notification/notification-client.cpp
+++ b/libukui-notification/notification-client.cpp
@@ -31,7 +31,7 @@ bool NotificationClientPrivate::init()
qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError();
return false;
}
- QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QStringLiteral("org.freedesktop.Notifications"),
+ auto *watcher = new QDBusServiceWatcher(QStringLiteral("org.freedesktop.Notifications"),
conn,
QDBusServiceWatcher::WatchForOwnerChange,
this);
@@ -147,6 +147,20 @@ void NotificationClientPrivate::serviceChange(const QString &service, const QStr
}
}
+void NotificationClientPrivate::invokeAction(uint id, const QString &action_key, const QString &action,
+ const QString &display)
+{
+ if(!m_notificationsInterface) {
+ return;
+ }
+ QDBusMessage reply = m_notificationsInterface->callWithArgumentList(QDBus::NoBlock,
+ QStringLiteral("InvokedAction"),
+ {id, action_key, action, display});
+ if (reply.type() == QDBusMessage::ErrorMessage) {
+ qWarning() << "Failed to call InvokedAction!" << QDBusConnection::sessionBus().lastError();
+ }
+}
+
NotificationClient::NotificationClient(QObject *parent) : QObject(parent), d(new NotificationClientPrivate(this))
{
qRegisterMetaType("PopupNotification");
@@ -162,4 +176,9 @@ bool NotificationClient::registerClient()
void NotificationClient::closeNotification(uint id, NotificationClient::CloseReason reason)
{
d->closeNotification(id, reason);
-}
\ No newline at end of file
+}
+
+void NotificationClient::invokeAction(uint id, const QString &action_key, const QString &action, const QString &display)
+{
+ d->invokeAction(id, action_key, action, display);
+}
diff --git a/libukui-notification/notification-client.h b/libukui-notification/notification-client.h
index 4bfab05..e6e8334 100644
--- a/libukui-notification/notification-client.h
+++ b/libukui-notification/notification-client.h
@@ -31,6 +31,7 @@ public:
*/
bool registerClient();
void closeNotification(uint id, CloseReason reason);
+ void invokeAction(uint id, const QString &action_key, const QString &action, const QString &display);
Q_SIGNALS:
void newNotification(const PopupNotification ¬ification);
void notificationClosed(uint id, CloseReason closeReason);
diff --git a/libukui-notification/utils.cpp b/libukui-notification/utils.cpp
new file mode 100644
index 0000000..a9a426c
--- /dev/null
+++ b/libukui-notification/utils.cpp
@@ -0,0 +1,32 @@
+//
+// Created by zpf on 2023/2/13.
+//
+#include "utils.h"
+#include
+#include
+#include
+using namespace UkuiNotification;
+QString Utils::desktopEntryFromPid(uint pid)
+{
+ return QString();
+}
+QString Utils::displayFromPid(uint pid)
+{
+ QFile environFile(QStringLiteral("/proc/%1/environ").arg(QString::number(pid)));
+ if (environFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ const QByteArray DISPLAY = KWindowSystem::isPlatformWayland() ? QByteArrayLiteral("WAYLAND_DISPLAY") : QByteArrayLiteral("DISPLAY");
+ const auto lines = environFile.readAll().split('\0');
+ for (const QByteArray &line : lines) {
+ const int equalsIdx = line.indexOf('=');
+ if (equalsIdx <= 0) {
+ continue;
+ }
+ const QByteArray key = line.left(equalsIdx);
+ if (key == DISPLAY) {
+ const QByteArray value = line.mid(equalsIdx + 1);
+ return value;
+ }
+ }
+ }
+ return QString();
+}
\ No newline at end of file
diff --git a/libukui-notification/utils.h b/libukui-notification/utils.h
new file mode 100644
index 0000000..308f4db
--- /dev/null
+++ b/libukui-notification/utils.h
@@ -0,0 +1,14 @@
+//
+// Created by zpf on 2023/2/13.
+//
+
+#ifndef UKUI_NOTIFICATION_UTILS_H
+#define UKUI_NOTIFICATION_UTILS_H
+#include
+namespace UkuiNotification {
+namespace Utils {
+ QString desktopEntryFromPid(uint pid);
+ QString displayFromPid(uint pid);
+}
+}
+#endif //UKUI_NOTIFICATION_UTILS_H
diff --git a/notification-server/CMakeLists.txt b/notification-server/CMakeLists.txt
index 869b2bf..62e1f9b 100644
--- a/notification-server/CMakeLists.txt
+++ b/notification-server/CMakeLists.txt
@@ -1,7 +1,8 @@
-set (VERSION_MAJOR 1)
-set (VERSION_MINOR 0)
-set (VERSION_MICRO 0)
-set (NOTIFICATION_SERVER_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO})
+set(VERSION_MAJOR 1)
+set(VERSION_MINOR 0)
+set(VERSION_MICRO 0)
+set(NOTIFICATION_SERVER_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO})
+
configure_file (notification-server-config.h.in notification-server-config.h @ONLY)
set(3rdParties_DIR ../3rd-parties/qtsingleapplication/src/)
set(notificationServer_SRCS
@@ -26,6 +27,7 @@ else()
qt5_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.ukui.NotificationServer.xml server-private.h NotificationServer::ServerPrivate)
endif()
add_executable(ukui-notification-server ${notificationServer_SRCS})
+include_directories(../libukui-notification)
target_include_directories(ukui-notification-server PUBLIC ${3rdParties_DIR})
target_link_libraries(ukui-notification-server
@@ -33,10 +35,14 @@ target_link_libraries(ukui-notification-server
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::DBus
Qt${QT_VERSION_MAJOR}::Network
+ ukui-notification
)
set(TS_FILES ukui-notification_zh_CN.ts)
if(COMMAND qt_create_translation)
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR}/translations ${TS_FILES})
else()
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR}/translations ${TS_FILES})
-endif()
\ No newline at end of file
+endif()
+set(DBUS_SERVICE_FILE data/org.freedesktop.Notifications.service)
+install(TARGETS ukui-notification-server DESTINATION /usr/bin)
+install(FILES ${DBUS_SERVICE_FILE} DESTINATION /usr/share/dbus-1/services)
\ No newline at end of file
diff --git a/notification-server/data/org.freedesktop.Notifications.service b/notification-server/data/org.freedesktop.Notifications.service
new file mode 100644
index 0000000..928c2ae
--- /dev/null
+++ b/notification-server/data/org.freedesktop.Notifications.service
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.Notification
+Exec=/usr/bin/ukui-notification-server
\ No newline at end of file
diff --git a/notification-server/server-private.h b/notification-server/server-private.h
index 8984d14..9c36ef0 100644
--- a/notification-server/server-private.h
+++ b/notification-server/server-private.h
@@ -51,7 +51,7 @@ public:
* @param reason 关闭原因
*/
void CloseNotification(uint id, uint);
- void InvokedAction(uint id, const QString &action_key, const QString &display);
+ void InvokedAction(uint id, const QString &action_key, const QString &action, const QString &display);
Q_SIGNALS:
void NotificationClosed(uint id, uint reason);
void ActionInvoked(uint id, const QString &actionKey);
diff --git a/notification-server/server.cpp b/notification-server/server.cpp
index 64806f9..e30f54b 100644
--- a/notification-server/server.cpp
+++ b/notification-server/server.cpp
@@ -8,6 +8,7 @@
#include "notificationsadaptor.h"
#include "notificationserveradaptor.h"
#include "notification-server-config.h"
+#include "utils.h"
using namespace NotificationServer;
ServerPrivate::ServerPrivate(QObject *parent) : QObject(parent), m_notificationWatchers(new QDBusServiceWatcher(this))
@@ -35,7 +36,19 @@ uint ServerPrivate::Notify(const QString &app_name, uint replaces_id, const QStr
id = m_increasedNotificationId++;
}
- //TODO 在hint中增加DISPLAY信息,注意区分X和wayland,DISPLAY信息决定了通知弹窗显示和action执行所在的DISPLAY
+ uint pid = 0;
+ QDBusReply pidReply = connection().interface()->servicePid(message().service());
+ if(pidReply.isValid()) {
+ pid = pidReply.value();
+ }
+
+ QVariantMap newHints = hints;
+ if(newHints.value(QStringLiteral("x-ukui-display")).toString().isEmpty() && pid > 0) {
+ newHints.insert(QStringLiteral("x-ukui-display"), UkuiNotification::Utils::displayFromPid(pid));
+ }
+ if(newHints.value(QStringLiteral("desktop-entry")).toString().isEmpty() && pid > 0) {
+ newHints.insert(QStringLiteral("desktop-entry"), UkuiNotification::Utils::desktopEntryFromPid(pid));
+ }
qDebug() << "New message received:" << app_name << id << app_icon << summary << body << actions << hints << timeout;
for(const QString &service : m_notificationWatchers->watchedServices()) {
@@ -43,7 +56,7 @@ uint ServerPrivate::Notify(const QString &app_name, uint replaces_id, const QStr
QStringLiteral("/NotificationClient"),
QStringLiteral("org.ukui.NotificationClient"),
QStringLiteral("Notify"));
- msg.setArguments({app_name, id, app_icon, summary, body, actions, hints, timeout});
+ msg.setArguments({app_name, id, app_icon, summary, body, actions, newHints, timeout});
QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
}
return id;
@@ -120,7 +133,7 @@ void ServerPrivate::CloseNotification(uint id, uint reason)
Q_EMIT NotificationClosed(id, reason);
}
-void ServerPrivate::InvokedAction(uint id, const QString &action_key, const QString &display)
+void ServerPrivate::InvokedAction(uint id, const QString &action_key, const QString &action, const QString &display)
{
//TODO: 异步执行action
Q_EMIT ActionInvoked(id, action_key);