增加客户端重连功能,增加测试demo,增加.cmake,.pc文件

This commit is contained in:
iaom 2023-02-09 13:54:53 +08:00
parent 923dff43f9
commit 423ab2f445
15 changed files with 189 additions and 26 deletions

View File

@ -15,5 +15,7 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core LinguistTools DBus Network Gu
add_subdirectory(notification-server) add_subdirectory(notification-server)
add_subdirectory(libukui-notification) add_subdirectory(libukui-notification)
if(BUILD_TEST)
add_subdirectory(test)
endif()

View File

@ -21,3 +21,14 @@ target_link_libraries(ukui-notification
Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Gui
) )
target_compile_definitions(ukui-notification PRIVATE UKUINOTIFICATION_LIBRARY) target_compile_definitions(ukui-notification PRIVATE UKUINOTIFICATION_LIBRARY)
include(CMakePackageConfigHelpers)
set(CMAKECONFIG_INSTALL_DIR "/usr/lib/ukui-notification")
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/ukui-notification-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/ukui-notification-config.cmake"
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR})
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})

View File

@ -15,7 +15,7 @@ class NotificationClientPrivate : public QObject
public: public:
explicit NotificationClientPrivate(NotificationClient *q, QObject *parent = nullptr); explicit NotificationClientPrivate(NotificationClient *q, QObject *parent = nullptr);
~NotificationClientPrivate() override; ~NotificationClientPrivate() override;
bool registerClient(); bool init();
static QString clientServicePath(); static QString clientServicePath();
static QString clientServiceInterface(); static QString clientServiceInterface();
@ -28,8 +28,12 @@ public:
const QVariantMap &hints, const QVariantMap &hints,
int timeout); int timeout);
void closeNotification(uint id, NotificationClient::CloseReason reason); void closeNotification(uint id, NotificationClient::CloseReason reason);
private: private Q_SLOTS:
void notificationClosed(uint id, uint reason); 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; OrgFreedesktopNotificationsInterface* m_notificationsInterface = nullptr;
QDBusInterface *m_serverInterface = nullptr; QDBusInterface *m_serverInterface = nullptr;
NotificationClient *q; NotificationClient *q;

View File

@ -17,10 +17,12 @@ NotificationClientPrivate::~NotificationClientPrivate()
{ {
if(m_notificationsInterface) { if(m_notificationsInterface) {
m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("UnRegisterClient")); m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("UnRegisterClient"));
delete m_notificationsInterface;
m_notificationsInterface = nullptr;
} }
} }
bool NotificationClientPrivate::registerClient() bool NotificationClientPrivate::init()
{ {
new NotificationClientAdaptor(this); new NotificationClientAdaptor(this);
QDBusConnection conn = QDBusConnection::sessionBus(); QDBusConnection conn = QDBusConnection::sessionBus();
@ -29,20 +31,32 @@ bool NotificationClientPrivate::registerClient()
qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError(); qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError();
return false; return false;
} }
QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QStringLiteral("org.freedesktop.Notifications"),
conn,
QDBusServiceWatcher::WatchForOwnerChange,
this);
connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, [](const QString &service, const QString &oldOwner, const QString &newOwner){
qDebug() << "serviceOwnerChanged" << service << oldOwner << newOwner;
});
return registerClient();
}
bool NotificationClientPrivate::registerClient()
{
QDBusConnection conn = QDBusConnection::sessionBus();
m_notificationsInterface = new OrgFreedesktopNotificationsInterface(QStringLiteral("org.freedesktop.Notifications"), m_notificationsInterface = new OrgFreedesktopNotificationsInterface(QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("/org/freedesktop/Notifications"), QStringLiteral("/org/freedesktop/Notifications"),
conn, conn);
this);
if(!m_notificationsInterface->isValid()) { if(!m_notificationsInterface->isValid()) {
qWarning() << "Failed to creat dbus interface for notification server!" << conn.lastError(); qWarning() << "Failed to creat dbus interface for notification server!" << conn.lastError();
return false; return false;
} }
connect(m_notificationsInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed, connect(m_notificationsInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed,
this, &NotificationClientPrivate::notificationClosed); this, &NotificationClientPrivate::notificationClosed);
if(!m_serverInterface) { if(!m_serverInterface) {
m_serverInterface = new QDBusInterface(QStringLiteral("org.freedesktop.Notifications"), m_serverInterface = new QDBusInterface(QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("/org/ukui/NotificationServer"), QStringLiteral("/org/freedesktop/Notifications"),
QStringLiteral("org.ukui.NotificationServer"), QStringLiteral("org.ukui.NotificationServer"),
conn, conn,
this); this);
@ -51,14 +65,25 @@ bool NotificationClientPrivate::registerClient()
return false; return false;
} }
} }
QDBusMessage reply = m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("RegisterClient"));
if (reply.type() == QDBusMessage::ErrorMessage) { QDBusMessage reply = m_serverInterface->call(QStringLiteral("RegisterClient"));
qWarning() << "Failed to call RegisterClient!" << conn.lastError(); if (reply.type() == QDBusMessage::ErrorMessage || reply.type() == QDBusMessage::InvalidMessage) {
qWarning() << "Failed to call RegisterClient!" << conn.lastError() << reply.type();
return false; return false;
} }
return true; return true;
} }
void NotificationClientPrivate::unRegisterClient()
{
disconnect(m_notificationsInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed,
this, &NotificationClientPrivate::notificationClosed);
if(m_notificationsInterface) {
delete m_notificationsInterface;
m_notificationsInterface = nullptr;
}
}
QString NotificationClientPrivate::clientServicePath() QString NotificationClientPrivate::clientServicePath()
{ {
return QStringLiteral("/NotificationClient"); return QStringLiteral("/NotificationClient");
@ -112,15 +137,26 @@ void NotificationClientPrivate::closeNotification(uint id, NotificationClient::C
} }
} }
void NotificationClientPrivate::serviceChange(const QString &service, const QString &oldOwner, const QString &newOwner)
{
qDebug() << "Notification Service" << service << "status change, old owner:" << oldOwner << "new:" << newOwner;
if(newOwner.isEmpty()) {
unRegisterClient();
} else if (oldOwner.isEmpty()) {
registerClient();
}
}
NotificationClient::NotificationClient(QObject *parent) : QObject(parent), d(new NotificationClientPrivate(this)) NotificationClient::NotificationClient(QObject *parent) : QObject(parent), d(new NotificationClientPrivate(this))
{ {
qRegisterMetaType<PopupNotification>("PopupNotification");
} }
NotificationClient::~NotificationClient() = default; NotificationClient::~NotificationClient() = default;
bool NotificationClient::registerClient() bool NotificationClient::registerClient()
{ {
return d->registerClient(); return d->init();
} }
void NotificationClient::closeNotification(uint id, NotificationClient::CloseReason reason) void NotificationClient::closeNotification(uint id, NotificationClient::CloseReason reason)

View File

@ -14,8 +14,8 @@ class UKUINOTIFICATION_EXPORT NotificationClient : public QObject
Q_OBJECT Q_OBJECT
public: public:
/** /**
* The reason a notification was closed * The reason a notification was closed
*/ */
enum CloseReason { enum CloseReason {
Expired = 1, // The notification expired(timed out). Expired = 1, // The notification expired(timed out).
DismissedByUser = 2, // The notification was dismissed by the user. DismissedByUser = 2, // The notification was dismissed by the user.

View File

@ -37,7 +37,6 @@ public:
QString m_soundFile; QString m_soundFile;
bool m_suppressSound = false; bool m_suppressSound = false;
QString m_display; QString m_display;
}; };
} }
using namespace UkuiNotification; using namespace UkuiNotification;
@ -244,7 +243,7 @@ void PopupNotification::setActions(const QStringList &actions)
} }
} }
QList<QPair<QString, QString>> PopupNotification::getActions() QList<QPair<QString, QString>> PopupNotification::actions() const
{ {
return d->m_actions; return d->m_actions;
} }

View File

@ -52,7 +52,7 @@ public:
bool hasDefaultAction() const; bool hasDefaultAction() const;
QString defauleActionLable(); QString defauleActionLable();
void setActions(const QStringList &actions); void setActions(const QStringList &actions);
QList<QPair<QString, QString>> getActions(); QList<QPair<QString, QString>> actions() const;
QVariantMap hints() const; QVariantMap hints() const;
void setHints(const QVariantMap &hints); void setHints(const QVariantMap &hints);
@ -98,12 +98,20 @@ public:
*/ */
QString soundFile() const; QString soundFile() const;
/** /**
* *
* @return * @return
*/ */
bool suppressSound() const; bool suppressSound() const;
/**
*
* @return
*/
bool transient() const; bool transient() const;
void setUrgency(Urgency urgency); void setUrgency(Urgency urgency);
/**
* display
* @return
*/
QString display() const; QString display() const;
private: private:

View File

@ -0,0 +1,10 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Qt@QT_MAJOR_VERSION@Core "@REQUIRED_QT_VERSION@")
if(TARGET Qt6::Core)
find_dependency(Qt6Core5Compat @REQUIRED_QT_VERSION@)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/ukui-notificationTargets.cmake")

View File

@ -0,0 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/include/ukui-notification
Name: ukui-notification
Description: ukui-notification header files
URL: https://www.ukui.org/
Version: @VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lukui-notification

View File

@ -1,9 +1,9 @@
#ifndef NOTIFICATION_SERVER_CONFIG_H_IN #ifndef NOTIFICATION_SERVER_CONFIG_H_IN
#define NOTIFICATION_SERVER_CONFIG_H_IN #define NOTIFICATION_SERVER_CONFIG_H_IN
#define VERSION_MAJOR "@ VERSION_MAJOR @" #define VERSION_MAJOR "@VERSION_MAJOR@"
#define VERSION_MINOR "@ VERSION_MINOR @" #define VERSION_MINOR "@VERSION_MINOR@"
#define VERSION_MICRO "@ VERSION_MICRO @" #define VERSION_MICRO "@VERSION_MICRO@"
#define NOTIFICATION_SERVER_VERSION "@ NOTIFICATION_SERVER_VERSION @" #define NOTIFICATION_SERVER_VERSION "@NOTIFICATION_SERVER_VERSION@"
#endif // NOTIFICATION_SERVER_CONFIG_H_IN #endif // NOTIFICATION_SERVER_CONFIG_H_INNOTIFICATION_SERVER_VERSION

View File

@ -6,6 +6,8 @@
#include "server.h" #include "server.h"
#include "server-private.h" #include "server-private.h"
#include "notificationsadaptor.h" #include "notificationsadaptor.h"
#include "notificationserveradaptor.h"
#include "notification-server-config.h"
using namespace NotificationServer; using namespace NotificationServer;
ServerPrivate::ServerPrivate(QObject *parent) : QObject(parent), m_notificationWatchers(new QDBusServiceWatcher(this)) ServerPrivate::ServerPrivate(QObject *parent) : QObject(parent), m_notificationWatchers(new QDBusServiceWatcher(this))
@ -35,6 +37,7 @@ uint ServerPrivate::Notify(const QString &app_name, uint replaces_id, const QStr
//TODO 在hint中增加DISPLAY信息,注意区分X和waylandDISPLAY信息决定了通知弹窗显示和action执行所在的DISPLAY //TODO 在hint中增加DISPLAY信息,注意区分X和waylandDISPLAY信息决定了通知弹窗显示和action执行所在的DISPLAY
qDebug() << "New message received:" << app_name << id << app_icon << summary << body << actions << hints << timeout;
for(const QString &service : m_notificationWatchers->watchedServices()) { for(const QString &service : m_notificationWatchers->watchedServices()) {
QDBusMessage msg = QDBusMessage::createMethodCall(service, QDBusMessage msg = QDBusMessage::createMethodCall(service,
QStringLiteral("/NotificationClient"), QStringLiteral("/NotificationClient"),
@ -48,7 +51,10 @@ uint ServerPrivate::Notify(const QString &app_name, uint replaces_id, const QStr
QString ServerPrivate::GetServerInformation(QString &vendor, QString &version, QString &spec_version) const QString ServerPrivate::GetServerInformation(QString &vendor, QString &version, QString &spec_version) const
{ {
return QString(); vendor = QStringLiteral("Kylin");
version = QLatin1String(NOTIFICATION_SERVER_VERSION);
spec_version = QStringLiteral("1.2");
return QStringLiteral("UKUI");
} }
void ServerPrivate::CloseNotification(uint id) void ServerPrivate::CloseNotification(uint id)
@ -66,6 +72,7 @@ void ServerPrivate::CloseNotification(uint id)
bool ServerPrivate::init() bool ServerPrivate::init()
{ {
new NotificationsAdaptor(this); new NotificationsAdaptor(this);
new NotificationServerAdaptor(this);
QDBusConnection conn = QDBusConnection::sessionBus(); QDBusConnection conn = QDBusConnection::sessionBus();
auto registration = conn.interface()->registerService(notificationServiceName(), auto registration = conn.interface()->registerService(notificationServiceName(),
QDBusConnectionInterface::ReplaceExistingService, QDBusConnectionInterface::ReplaceExistingService,
@ -75,7 +82,7 @@ bool ServerPrivate::init()
return false; return false;
} }
if(!conn.registerObject(notificationServicePath(), this)) { if(!conn.registerObject(notificationServicePath(), this)) {
qWarning() << "Failed to register Notification DBus object!" << conn.lastError(); qWarning() << "Failed to register Notification DBus object!" << conn.lastError().message();
return false; return false;
} }
return true; return true;
@ -98,7 +105,9 @@ QString ServerPrivate::notificationServiceInterface()
void ServerPrivate::RegisterClient() void ServerPrivate::RegisterClient()
{ {
// qDebug() << "Client Register:" << message().service();
m_notificationWatchers->addWatchedService(message().service()); m_notificationWatchers->addWatchedService(message().service());
qDebug() << "Watched services:" << m_notificationWatchers->watchedServices();
} }
void ServerPrivate::UnRegisterClient() void ServerPrivate::UnRegisterClient()

12
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,12 @@
set(notificationClientTest_SRCS
notification-client-test.cpp
notification-client-test.h
main.cpp)
include_directories(${CMAKE_SOURCE_DIR}/libukui-notification)
add_executable(notification-client-test ${notificationClientTest_SRCS})
target_link_libraries(notification-client-test PRIVATE
Qt${QT_MAJOR_VERSION}::Core
Qt${QT_MAJOR_VERSION}::Gui
ukui-notification
)

13
test/main.cpp Normal file
View File

@ -0,0 +1,13 @@
//
// Created by zpf on 2023/2/7.
//
#include <QCoreApplication>
#include <QDebug>
#include "notification-client-test.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
NotificationClientTest ct;
return app.exec();
}

View File

@ -0,0 +1,27 @@
//
// Created by zpf on 2023/2/7.
//
#include "notification-client-test.h"
#include <QDebug>
NotificationClientTest::NotificationClientTest(QObject *parent) : QObject(parent)
{
m_client = new UkuiNotification::NotificationClient(this);
connect(m_client, &UkuiNotification::NotificationClient::newNotification,
[&](const UkuiNotification::PopupNotification &notification){
qDebug() << notification.applicationName()
<< notification.applicationIconName()
<< notification.summary()
<< notification.body()
<< notification.actions()
<< notification.hints()
<< notification.timeout();
});
qDebug() << "Register client" << m_client->registerClient();
}
NotificationClientTest::~NotificationClientTest()
{
}

View File

@ -0,0 +1,21 @@
//
// Created by zpf on 2023/2/7.
//
#ifndef UKUI_NOTIFICATION_NOTIFICATION_CLIENT_TEST_H
#define UKUI_NOTIFICATION_NOTIFICATION_CLIENT_TEST_H
#include "notification-client.h"
#include <QObject>
class NotificationClientTest : public QObject
{
Q_OBJECT
public:
explicit NotificationClientTest(QObject *parent = nullptr);
~NotificationClientTest();
private:
UkuiNotification::NotificationClient *m_client = nullptr;
};
#endif //UKUI_NOTIFICATION_NOTIFICATION_CLIENT_TEST_H