Fix notification actions for Cinnamon, fix notification icon for Gnome, add support for TDESKTOP_LAUNCHER_FILENAME in notifications and fix indentation

This commit is contained in:
Ilya Fedin 2020-01-17 11:18:25 +04:00 committed by John Preston
parent 6fdd1389e6
commit ee9336f781
1 changed files with 59 additions and 54 deletions

View File

@ -28,12 +28,12 @@ std::vector<QString> GetServerInformation(
const std::shared_ptr<QDBusInterface> &notificationInterface) { const std::shared_ptr<QDBusInterface> &notificationInterface) {
std::vector<QString> serverInformation; std::vector<QString> serverInformation;
auto serverInformationReply = notificationInterface auto serverInformationReply = notificationInterface
->call("GetServerInformation"); ->call(qsl("GetServerInformation"));
if (serverInformationReply.type() == QDBusMessage::ReplyMessage) { if (serverInformationReply.type() == QDBusMessage::ReplyMessage) {
for (const auto &arg : serverInformationReply.arguments()) { for (const auto &arg : serverInformationReply.arguments()) {
if (static_cast<QMetaType::Type>(arg.type()) if (static_cast<QMetaType::Type>(arg.type())
== QMetaType::QString) { == QMetaType::QString) {
serverInformation.push_back(arg.toString()); serverInformation.push_back(arg.toString());
} else { } else {
LOG(("Native notification error: " LOG(("Native notification error: "
@ -55,7 +55,7 @@ std::vector<QString> GetServerInformation(
std::vector<QString> GetCapabilities( std::vector<QString> GetCapabilities(
const std::shared_ptr<QDBusInterface> &notificationInterface) { const std::shared_ptr<QDBusInterface> &notificationInterface) {
QDBusReply<QStringList> capabilitiesReply = notificationInterface QDBusReply<QStringList> capabilitiesReply = notificationInterface
->call("GetCapabilities"); ->call(qsl("GetCapabilities"));
if (capabilitiesReply.isValid()) { if (capabilitiesReply.isValid()) {
return capabilitiesReply.value().toVector().toStdVector(); return capabilitiesReply.value().toVector().toStdVector();
@ -96,23 +96,25 @@ NotificationData::NotificationData(
if (ranges::find(capabilities, qsl("body-markup")) != capabilitiesEnd) { if (ranges::find(capabilities, qsl("body-markup")) != capabilitiesEnd) {
_body = subtitle.isEmpty() _body = subtitle.isEmpty()
? msg.toHtmlEscaped() ? msg.toHtmlEscaped()
: qsl("<b>%1</b>\n%2").arg(subtitle.toHtmlEscaped()) : qsl("<b>%1</b>\n%2").arg(subtitle.toHtmlEscaped())
.arg(msg.toHtmlEscaped()); .arg(msg.toHtmlEscaped());
} else { } else {
_body = subtitle.isEmpty() _body = subtitle.isEmpty()
? msg ? msg
: qsl("%1\n%2").arg(subtitle).arg(msg); : qsl("%1\n%2").arg(subtitle).arg(msg);
} }
if (ranges::find(capabilities, qsl("actions")) != capabilitiesEnd) { if (ranges::find(capabilities, qsl("actions")) != capabilitiesEnd) {
_actions << qsl("default") << QString();
// icon name according to https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html // icon name according to https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
_actions << "mail-reply-sender" _actions << qsl("mail-reply-sender")
<< tr::lng_notification_reply(tr::now); << tr::lng_notification_reply(tr::now);
connect(_notificationInterface.get(), connect(_notificationInterface.get(),
SIGNAL(ActionInvoked(uint, QString)), SIGNAL(ActionInvoked(uint, QString)),
this, SLOT(notificationClicked(uint))); this, SLOT(notificationClicked(uint)));
} }
if (ranges::find(capabilities, qsl("action-icons")) != capabilitiesEnd) { if (ranges::find(capabilities, qsl("action-icons")) != capabilitiesEnd) {
@ -125,26 +127,35 @@ NotificationData::NotificationData(
_hints["suppress-sound"] = true; _hints["suppress-sound"] = true;
} else { } else {
// sound name according to http://0pointer.de/public/sound-naming-spec.html // sound name according to http://0pointer.de/public/sound-naming-spec.html
_hints["sound-name"] = "message-new-instant"; _hints["sound-name"] = qsl("message-new-instant");
} }
} }
if (ranges::find(capabilities, qsl("x-canonical-append")) if (ranges::find(capabilities, qsl("x-canonical-append"))
!= capabilitiesEnd) { != capabilitiesEnd) {
_hints["x-canonical-append"] = "true"; _hints["x-canonical-append"] = qsl("true");
} }
_hints["category"] = "im.received"; _hints["category"] = qsl("im.received");
_hints["desktop-entry"] = "telegramdesktop";
#ifdef TDESKTOP_LAUNCHER_FILENAME
#define TDESKTOP_LAUNCHER_FILENAME_TO_STRING_HELPER(V) #V
#define TDESKTOP_LAUNCHER_FILENAME_TO_STRING(V) TDESKTOP_LAUNCHER_FILENAME_TO_STRING_HELPER(V)
_hints["desktop-entry"] =
qsl(TDESKTOP_LAUNCHER_FILENAME_TO_STRING(TDESKTOP_LAUNCHER_FILENAME))
.remove(QRegExp(qsl("\\.desktop$"), Qt::CaseInsensitive));
#else
_hints["desktop-entry"] = qsl("telegramdesktop");
#endif
connect(_notificationInterface.get(), connect(_notificationInterface.get(),
SIGNAL(NotificationClosed(uint, uint)), SIGNAL(NotificationClosed(uint, uint)),
this, SLOT(notificationClosed(uint))); this, SLOT(notificationClosed(uint)));
} }
bool NotificationData::show() { bool NotificationData::show() {
QDBusReply<uint> notifyReply = _notificationInterface->call("Notify", QDBusReply<uint> notifyReply = _notificationInterface->call(qsl("Notify"),
str_const_toString(AppName), uint(0), "telegram", _title, _body, str_const_toString(AppName), uint(0), QString(), _title, _body,
_actions, _hints, -1); _actions, _hints, -1);
if (notifyReply.isValid()) { if (notifyReply.isValid()) {
@ -159,7 +170,7 @@ bool NotificationData::show() {
bool NotificationData::close() { bool NotificationData::close() {
QDBusReply<void> closeReply = _notificationInterface QDBusReply<void> closeReply = _notificationInterface
->call("CloseNotification", _notificationId); ->call(qsl("CloseNotification"), _notificationId);
if (!closeReply.isValid()) { if (!closeReply.isValid()) {
LOG(("Native notification error: %1") LOG(("Native notification error: %1")
@ -180,12 +191,12 @@ void NotificationData::setImage(const QString &imagePath) {
const auto minorVersion = specificationVersion.minorVersion(); const auto minorVersion = specificationVersion.minorVersion();
if ((majorVersion == 1 && minorVersion >= 2) || majorVersion > 1) { if ((majorVersion == 1 && minorVersion >= 2) || majorVersion > 1) {
imageKey = "image-data"; imageKey = qsl("image-data");
} else if (majorVersion == 1 && minorVersion) { } else if (majorVersion == 1 && minorVersion == 1) {
imageKey = "image_data"; imageKey = qsl("image_data");
} else if ((majorVersion == 1 && minorVersion < 1) } else if ((majorVersion == 1 && minorVersion < 1)
|| majorVersion < 1) { || majorVersion < 1) {
imageKey = "icon_data"; imageKey = qsl("icon_data");
} else { } else {
LOG(("Native notification error: unknown specification version")); LOG(("Native notification error: unknown specification version"));
return; return;
@ -197,7 +208,7 @@ void NotificationData::setImage(const QString &imagePath) {
auto image = QImage(imagePath).convertToFormat(QImage::Format_RGBA8888); auto image = QImage(imagePath).convertToFormat(QImage::Format_RGBA8888);
QByteArray imageBytes((const char*)image.constBits(), QByteArray imageBytes((const char*)image.constBits(),
image.sizeInBytes()); image.sizeInBytes());
ImageData imageData; ImageData imageData;
imageData.width = image.width(); imageData.width = image.width();
@ -233,12 +244,12 @@ QDBusArgument &operator<<(QDBusArgument &argument,
const NotificationData::ImageData &imageData) { const NotificationData::ImageData &imageData) {
argument.beginStructure(); argument.beginStructure();
argument << imageData.width argument << imageData.width
<< imageData.height << imageData.height
<< imageData.rowStride << imageData.rowStride
<< imageData.hasAlpha << imageData.hasAlpha
<< imageData.bitsPerSample << imageData.bitsPerSample
<< imageData.channels << imageData.channels
<< imageData.data; << imageData.data;
argument.endStructure(); argument.endStructure();
return argument; return argument;
} }
@ -247,29 +258,23 @@ const QDBusArgument &operator>>(const QDBusArgument &argument,
NotificationData::ImageData &imageData) { NotificationData::ImageData &imageData) {
argument.beginStructure(); argument.beginStructure();
argument >> imageData.width argument >> imageData.width
>> imageData.height >> imageData.height
>> imageData.rowStride >> imageData.rowStride
>> imageData.hasAlpha >> imageData.hasAlpha
>> imageData.bitsPerSample >> imageData.bitsPerSample
>> imageData.channels >> imageData.channels
>> imageData.data; >> imageData.data;
argument.endStructure(); argument.endStructure();
return argument; return argument;
} }
bool Supported() { bool Supported() {
static auto Checked = false; static auto Available = QDBusInterface(
static auto NotificationDaemonRunning = false; str_const_toString(kService),
str_const_toString(kObjectPath),
str_const_toString(kInterface)).isValid();
if (!Checked) { return Available;
Checked = true;
NotificationDaemonRunning = QDBusInterface(
str_const_toString(kService),
str_const_toString(kObjectPath),
str_const_toString(kInterface)).isValid();
}
return NotificationDaemonRunning;
} }
std::unique_ptr<Window::Notifications::Manager> Create( std::unique_ptr<Window::Notifications::Manager> Create(
@ -284,9 +289,9 @@ Manager::Private::Private(Manager *manager, Type type)
: _cachedUserpics(type) : _cachedUserpics(type)
, _manager(manager) , _manager(manager)
, _notificationInterface(std::make_shared<QDBusInterface>( , _notificationInterface(std::make_shared<QDBusInterface>(
str_const_toString(kService), str_const_toString(kService),
str_const_toString(kObjectPath), str_const_toString(kObjectPath),
str_const_toString(kInterface))) { str_const_toString(kInterface))) {
qDBusRegisterMetaType<NotificationData::ImageData>(); qDBusRegisterMetaType<NotificationData::ImageData>();
auto specificationVersion = ParseSpecificationVersion( auto specificationVersion = ParseSpecificationVersion(