增加客户端重连功能,增加测试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(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
)
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:
explicit NotificationClientPrivate(NotificationClient *q, QObject *parent = nullptr);
~NotificationClientPrivate() override;
bool registerClient();
bool init();
static QString clientServicePath();
static QString clientServiceInterface();
@ -28,8 +28,12 @@ public:
const QVariantMap &hints,
int timeout);
void closeNotification(uint id, NotificationClient::CloseReason reason);
private:
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;
NotificationClient *q;

View File

@ -17,10 +17,12 @@ NotificationClientPrivate::~NotificationClientPrivate()
{
if(m_notificationsInterface) {
m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("UnRegisterClient"));
delete m_notificationsInterface;
m_notificationsInterface = nullptr;
}
}
bool NotificationClientPrivate::registerClient()
bool NotificationClientPrivate::init()
{
new NotificationClientAdaptor(this);
QDBusConnection conn = QDBusConnection::sessionBus();
@ -29,20 +31,32 @@ bool NotificationClientPrivate::registerClient()
qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError();
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"),
QStringLiteral("/org/freedesktop/Notifications"),
conn,
this);
conn);
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/freedesktop/Notifications"),
QStringLiteral("org.ukui.NotificationServer"),
conn,
this);
@ -51,14 +65,25 @@ bool NotificationClientPrivate::registerClient()
return false;
}
}
QDBusMessage reply = m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("RegisterClient"));
if (reply.type() == QDBusMessage::ErrorMessage) {
qWarning() << "Failed to call RegisterClient!" << conn.lastError();
QDBusMessage reply = m_serverInterface->call(QStringLiteral("RegisterClient"));
if (reply.type() == QDBusMessage::ErrorMessage || reply.type() == QDBusMessage::InvalidMessage) {
qWarning() << "Failed to call RegisterClient!" << conn.lastError() << reply.type();
return false;
}
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()
{
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))
{
qRegisterMetaType<PopupNotification>("PopupNotification");
}
NotificationClient::~NotificationClient() = default;
bool NotificationClient::registerClient()
{
return d->registerClient();
return d->init();
}
void NotificationClient::closeNotification(uint id, NotificationClient::CloseReason reason)

View File

@ -37,7 +37,6 @@ public:
QString m_soundFile;
bool m_suppressSound = false;
QString m_display;
};
}
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;
}

View File

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

@ -6,4 +6,4 @@
#define VERSION_MICRO "@VERSION_MICRO@"
#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-private.h"
#include "notificationsadaptor.h"
#include "notificationserveradaptor.h"
#include "notification-server-config.h"
using namespace NotificationServer;
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
qDebug() << "New message received:" << app_name << id << app_icon << summary << body << actions << hints << timeout;
for(const QString &service : m_notificationWatchers->watchedServices()) {
QDBusMessage msg = QDBusMessage::createMethodCall(service,
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
{
return QString();
vendor = QStringLiteral("Kylin");
version = QLatin1String(NOTIFICATION_SERVER_VERSION);
spec_version = QStringLiteral("1.2");
return QStringLiteral("UKUI");
}
void ServerPrivate::CloseNotification(uint id)
@ -66,6 +72,7 @@ void ServerPrivate::CloseNotification(uint id)
bool ServerPrivate::init()
{
new NotificationsAdaptor(this);
new NotificationServerAdaptor(this);
QDBusConnection conn = QDBusConnection::sessionBus();
auto registration = conn.interface()->registerService(notificationServiceName(),
QDBusConnectionInterface::ReplaceExistingService,
@ -75,7 +82,7 @@ bool ServerPrivate::init()
return false;
}
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 true;
@ -98,7 +105,9 @@ QString ServerPrivate::notificationServiceInterface()
void ServerPrivate::RegisterClient()
{
// qDebug() << "Client Register:" << message().service();
m_notificationWatchers->addWatchedService(message().service());
qDebug() << "Watched services:" << m_notificationWatchers->watchedServices();
}
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