mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 14:45:14 +00:00
LibNotify Linux notifications support added, testing.
This commit is contained in:
118
Telegram/SourceFiles/platform/linux/linux_libnotify.cpp
Normal file
118
Telegram/SourceFiles/platform/linux/linux_libnotify.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "platform/linux/linux_libnotify.h"
|
||||
|
||||
#include "platform/linux/linux_libs.h"
|
||||
|
||||
namespace Platform {
|
||||
namespace Libs {
|
||||
namespace {
|
||||
|
||||
bool loadLibrary(QLibrary &lib, const char *name, int version) {
|
||||
DEBUG_LOG(("Loading '%1' with version %2...").arg(QLatin1String(name)).arg(version));
|
||||
lib.setFileNameAndVersion(QLatin1String(name), version);
|
||||
if (lib.load()) {
|
||||
DEBUG_LOG(("Loaded '%1' with version %2!").arg(QLatin1String(name)).arg(version));
|
||||
return true;
|
||||
}
|
||||
lib.setFileNameAndVersion(QLatin1String(name), QString());
|
||||
if (lib.load()) {
|
||||
DEBUG_LOG(("Loaded '%1' without version!").arg(QLatin1String(name)));
|
||||
return true;
|
||||
}
|
||||
LOG(("Could not load '%1' with version %2 :(").arg(QLatin1String(name)).arg(version));
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
f_notify_init notify_init = nullptr;
|
||||
f_notify_uninit notify_uninit = nullptr;
|
||||
f_notify_is_initted notify_is_initted = nullptr;
|
||||
f_notify_get_app_name notify_get_app_name = nullptr;
|
||||
f_notify_set_app_name notify_set_app_name = nullptr;
|
||||
f_notify_get_server_caps notify_get_server_caps = nullptr;
|
||||
f_notify_get_server_info notify_get_server_info = nullptr;
|
||||
|
||||
f_notify_notification_new notify_notification_new = nullptr;
|
||||
f_notify_notification_update notify_notification_update = nullptr;
|
||||
f_notify_notification_show notify_notification_show = nullptr;
|
||||
f_notify_notification_set_app_name notify_notification_set_app_name = nullptr;
|
||||
f_notify_notification_set_timeout notify_notification_set_timeout = nullptr;
|
||||
f_notify_notification_set_category notify_notification_set_category = nullptr;
|
||||
f_notify_notification_set_urgency notify_notification_set_urgency = nullptr;
|
||||
f_notify_notification_set_icon_from_pixbuf notify_notification_set_icon_from_pixbuf = nullptr;
|
||||
f_notify_notification_set_image_from_pixbuf notify_notification_set_image_from_pixbuf = nullptr;
|
||||
f_notify_notification_set_hint notify_notification_set_hint = nullptr;
|
||||
f_notify_notification_set_hint_int32 notify_notification_set_hint_int32 = nullptr;
|
||||
f_notify_notification_set_hint_uint32 notify_notification_set_hint_uint32 = nullptr;
|
||||
f_notify_notification_set_hint_double notify_notification_set_hint_double = nullptr;
|
||||
f_notify_notification_set_hint_string notify_notification_set_hint_string = nullptr;
|
||||
f_notify_notification_set_hint_byte notify_notification_set_hint_byte = nullptr;
|
||||
f_notify_notification_set_hint_byte_array notify_notification_set_hint_byte_array = nullptr;
|
||||
f_notify_notification_clear_hints notify_notification_clear_hints = nullptr;
|
||||
f_notify_notification_add_action notify_notification_add_action = nullptr;
|
||||
f_notify_notification_clear_actions notify_notification_clear_actions = nullptr;
|
||||
f_notify_notification_close notify_notification_close = nullptr;
|
||||
f_notify_notification_get_closed_reason notify_notification_get_closed_reason = nullptr;
|
||||
|
||||
void startLibNotify() {
|
||||
DEBUG_LOG(("Loading libnotify"));
|
||||
|
||||
QLibrary lib_notify;
|
||||
if (!loadLibrary(lib_notify, "notify", 4)) {
|
||||
return;
|
||||
}
|
||||
|
||||
load(lib_notify, "notify_init", notify_init);
|
||||
load(lib_notify, "notify_uninit", notify_uninit);
|
||||
load(lib_notify, "notify_is_initted", notify_is_initted);
|
||||
load(lib_notify, "notify_get_app_name", notify_get_app_name);
|
||||
load(lib_notify, "notify_set_app_name", notify_set_app_name);
|
||||
load(lib_notify, "notify_get_server_caps", notify_get_server_caps);
|
||||
load(lib_notify, "notify_get_server_info", notify_get_server_info);
|
||||
|
||||
load(lib_notify, "notify_notification_new", notify_notification_new);
|
||||
load(lib_notify, "notify_notification_update", notify_notification_update);
|
||||
load(lib_notify, "notify_notification_show", notify_notification_show);
|
||||
load(lib_notify, "notify_notification_set_app_name", notify_notification_set_app_name);
|
||||
load(lib_notify, "notify_notification_set_timeout", notify_notification_set_timeout);
|
||||
load(lib_notify, "notify_notification_set_category", notify_notification_set_category);
|
||||
load(lib_notify, "notify_notification_set_urgency", notify_notification_set_urgency);
|
||||
load(lib_notify, "notify_notification_set_icon_from_pixbuf", notify_notification_set_icon_from_pixbuf);
|
||||
load(lib_notify, "notify_notification_set_image_from_pixbuf", notify_notification_set_image_from_pixbuf);
|
||||
load(lib_notify, "notify_notification_set_hint", notify_notification_set_hint);
|
||||
load(lib_notify, "notify_notification_set_hint_int32", notify_notification_set_hint_int32);
|
||||
load(lib_notify, "notify_notification_set_hint_uint32", notify_notification_set_hint_uint32);
|
||||
load(lib_notify, "notify_notification_set_hint_double", notify_notification_set_hint_double);
|
||||
load(lib_notify, "notify_notification_set_hint_string", notify_notification_set_hint_string);
|
||||
load(lib_notify, "notify_notification_set_hint_byte", notify_notification_set_hint_byte);
|
||||
load(lib_notify, "notify_notification_set_hint_byte_array", notify_notification_set_hint_byte_array);
|
||||
load(lib_notify, "notify_notification_clear_hints", notify_notification_clear_hints);
|
||||
load(lib_notify, "notify_notification_add_action", notify_notification_add_action);
|
||||
load(lib_notify, "notify_notification_clear_actions", notify_notification_clear_actions);
|
||||
load(lib_notify, "notify_notification_close", notify_notification_close);
|
||||
load(lib_notify, "notify_notification_get_closed_reason", notify_notification_get_closed_reason);
|
||||
}
|
||||
|
||||
} // namespace Libs
|
||||
} // namespace Platform
|
131
Telegram/SourceFiles/platform/linux/linux_libnotify.h
Normal file
131
Telegram/SourceFiles/platform/linux/linux_libnotify.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#undef signals
|
||||
#include <gtk/gtk.h>
|
||||
#define signals public
|
||||
} // extern "C"
|
||||
|
||||
namespace Platform {
|
||||
namespace Libs {
|
||||
|
||||
void startLibNotify();
|
||||
|
||||
constexpr gint NOTIFY_EXPIRES_DEFAULT = -1;
|
||||
constexpr gint NOTIFY_EXPIRES_NEVER = 0;
|
||||
|
||||
struct NotifyNotification;
|
||||
typedef enum {
|
||||
NOTIFY_URGENCY_LOW,
|
||||
NOTIFY_URGENCY_NORMAL,
|
||||
NOTIFY_URGENCY_CRITICAL,
|
||||
} NotifyUrgency;
|
||||
|
||||
using NotifyActionCallback = void (*)(NotifyNotification *notification, char *action, gpointer user_data);
|
||||
|
||||
using f_notify_init = gboolean (*)(const char *app_name);
|
||||
extern f_notify_init notify_init;
|
||||
|
||||
using f_notify_uninit = void (*)(void);
|
||||
extern f_notify_uninit notify_uninit;
|
||||
|
||||
using f_notify_is_initted = gboolean (*)(void);
|
||||
extern f_notify_is_initted notify_is_initted;
|
||||
|
||||
using f_notify_get_app_name = const char* (*)(void);
|
||||
extern f_notify_get_app_name notify_get_app_name;
|
||||
|
||||
using f_notify_set_app_name = void (*)(const char *app_name);
|
||||
extern f_notify_set_app_name notify_set_app_name;
|
||||
|
||||
using f_notify_get_server_caps = GList* (*)(void);
|
||||
extern f_notify_get_server_caps notify_get_server_caps;
|
||||
|
||||
using f_notify_get_server_info = gboolean (*)(char **ret_name, char **ret_vendor, char **ret_version, char **ret_spec_version);
|
||||
extern f_notify_get_server_info notify_get_server_info;
|
||||
|
||||
using f_notify_notification_new = NotifyNotification* (*)(const char *summary, const char *body, const char *icon);
|
||||
extern f_notify_notification_new notify_notification_new;
|
||||
|
||||
using f_notify_notification_update = gboolean (*)(NotifyNotification *notification, const char *summary, const char *body, const char *icon);
|
||||
extern f_notify_notification_update notify_notification_update;
|
||||
|
||||
using f_notify_notification_show = gboolean (*)(NotifyNotification *notification, GError **error);
|
||||
extern f_notify_notification_show notify_notification_show;
|
||||
|
||||
using f_notify_notification_set_app_name = void (*)(NotifyNotification *notification, const char *app_name);
|
||||
extern f_notify_notification_set_app_name notify_notification_set_app_name;
|
||||
|
||||
using f_notify_notification_set_timeout = void (*)(NotifyNotification *notification, gint timeout);
|
||||
extern f_notify_notification_set_timeout notify_notification_set_timeout;
|
||||
|
||||
using f_notify_notification_set_category = void (*)(NotifyNotification *notification, const char *category);
|
||||
extern f_notify_notification_set_category notify_notification_set_category;
|
||||
|
||||
using f_notify_notification_set_urgency = void (*)(NotifyNotification *notification, NotifyUrgency urgency);
|
||||
extern f_notify_notification_set_urgency notify_notification_set_urgency;
|
||||
|
||||
using f_notify_notification_set_icon_from_pixbuf = void (*)(NotifyNotification *notification, GdkPixbuf *icon);
|
||||
extern f_notify_notification_set_icon_from_pixbuf notify_notification_set_icon_from_pixbuf;
|
||||
|
||||
using f_notify_notification_set_image_from_pixbuf = void (*)(NotifyNotification *notification, GdkPixbuf *pixbuf);
|
||||
extern f_notify_notification_set_image_from_pixbuf notify_notification_set_image_from_pixbuf;
|
||||
|
||||
using f_notify_notification_set_hint = void (*)(NotifyNotification *notification, const char *key, GVariant *value);
|
||||
extern f_notify_notification_set_hint notify_notification_set_hint;
|
||||
|
||||
using f_notify_notification_set_hint_int32 = void (*)(NotifyNotification *notification, const char *key, gint value);
|
||||
extern f_notify_notification_set_hint_int32 notify_notification_set_hint_int32;
|
||||
|
||||
using f_notify_notification_set_hint_uint32 = void (*)(NotifyNotification *notification, const char *key, guint value);
|
||||
extern f_notify_notification_set_hint_uint32 notify_notification_set_hint_uint32;
|
||||
|
||||
using f_notify_notification_set_hint_double = void (*)(NotifyNotification *notification, const char *key, gdouble value);
|
||||
extern f_notify_notification_set_hint_double notify_notification_set_hint_double;
|
||||
|
||||
using f_notify_notification_set_hint_string = void (*)(NotifyNotification *notification, const char *key, const char *value);
|
||||
extern f_notify_notification_set_hint_string notify_notification_set_hint_string;
|
||||
|
||||
using f_notify_notification_set_hint_byte = void (*)(NotifyNotification *notification, const char *key, guchar value);
|
||||
extern f_notify_notification_set_hint_byte notify_notification_set_hint_byte;
|
||||
|
||||
using f_notify_notification_set_hint_byte_array = void (*)(NotifyNotification *notification, const char *key, const guchar *value, gsize len);
|
||||
extern f_notify_notification_set_hint_byte_array notify_notification_set_hint_byte_array;
|
||||
|
||||
using f_notify_notification_clear_hints = void (*)(NotifyNotification *notification);
|
||||
extern f_notify_notification_clear_hints notify_notification_clear_hints;
|
||||
|
||||
using f_notify_notification_add_action = void (*)(NotifyNotification *notification, const char *action, const char *label, NotifyActionCallback callback, gpointer user_data, GFreeFunc free_func);
|
||||
extern f_notify_notification_add_action notify_notification_add_action;
|
||||
|
||||
using f_notify_notification_clear_actions = void (*)(NotifyNotification *notification);
|
||||
extern f_notify_notification_clear_actions notify_notification_clear_actions;
|
||||
|
||||
using f_notify_notification_close = gboolean (*)(NotifyNotification *notification, GError **error);
|
||||
extern f_notify_notification_close notify_notification_close;
|
||||
|
||||
using f_notify_notification_get_closed_reason = gint (*)(const NotifyNotification *notification);
|
||||
extern f_notify_notification_get_closed_reason notify_notification_get_closed_reason;
|
||||
|
||||
} // namespace Libs
|
||||
} // namespace Platform
|
@@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "platform/linux/linux_libs.h"
|
||||
|
||||
#include "platform/linux/linux_gdk_helper.h"
|
||||
#include "platform/linux/linux_libnotify.h"
|
||||
|
||||
namespace Platform {
|
||||
namespace Libs {
|
||||
@@ -175,6 +176,7 @@ f_app_indicator_set_menu app_indicator_set_menu = nullptr;
|
||||
f_app_indicator_set_icon_full app_indicator_set_icon_full = nullptr;
|
||||
f_gdk_init_check gdk_init_check = nullptr;
|
||||
f_gdk_pixbuf_new_from_data gdk_pixbuf_new_from_data = nullptr;
|
||||
f_gdk_pixbuf_new_from_file gdk_pixbuf_new_from_file = nullptr;
|
||||
f_gtk_status_icon_new_from_pixbuf gtk_status_icon_new_from_pixbuf = nullptr;
|
||||
f_gtk_status_icon_set_from_pixbuf gtk_status_icon_set_from_pixbuf = nullptr;
|
||||
f_gtk_status_icon_new_from_file gtk_status_icon_new_from_file = nullptr;
|
||||
@@ -233,6 +235,7 @@ void start() {
|
||||
if (gtkLoaded) {
|
||||
load(lib_gtk, "gdk_init_check", gdk_init_check);
|
||||
load(lib_gtk, "gdk_pixbuf_new_from_data", gdk_pixbuf_new_from_data);
|
||||
load(lib_gtk, "gdk_pixbuf_new_from_file", gdk_pixbuf_new_from_file);
|
||||
load(lib_gtk, "gtk_status_icon_new_from_pixbuf", gtk_status_icon_new_from_pixbuf);
|
||||
load(lib_gtk, "gtk_status_icon_set_from_pixbuf", gtk_status_icon_set_from_pixbuf);
|
||||
load(lib_gtk, "gtk_status_icon_new_from_file", gtk_status_icon_new_from_file);
|
||||
@@ -266,6 +269,10 @@ void start() {
|
||||
load(lib_unity, "unity_launcher_entry_set_count_visible", unity_launcher_entry_set_count_visible);
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
|
||||
|
||||
if (gtkLoaded) {
|
||||
startLibNotify();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Libs
|
||||
|
@@ -273,6 +273,9 @@ extern f_gdk_init_check gdk_init_check;
|
||||
typedef GdkPixbuf* (*f_gdk_pixbuf_new_from_data)(const guchar *data, GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample, int width, int height, int rowstride, GdkPixbufDestroyNotify destroy_fn, gpointer destroy_fn_data);
|
||||
extern f_gdk_pixbuf_new_from_data gdk_pixbuf_new_from_data;
|
||||
|
||||
typedef GdkPixbuf* (*f_gdk_pixbuf_new_from_file)(const gchar *filename, GError **error);
|
||||
extern f_gdk_pixbuf_new_from_file gdk_pixbuf_new_from_file;
|
||||
|
||||
typedef GtkStatusIcon* (*f_gtk_status_icon_new_from_pixbuf)(GdkPixbuf *pixbuf);
|
||||
extern f_gtk_status_icon_new_from_pixbuf gtk_status_icon_new_from_pixbuf;
|
||||
|
||||
|
@@ -63,22 +63,11 @@ gboolean _trayIconResized(GtkStatusIcon *status_icon, gint size, gpointer popup_
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
|
||||
#define QT_RED 3
|
||||
#define QT_GREEN 2
|
||||
#define QT_BLUE 1
|
||||
#define QT_ALPHA 0
|
||||
|
||||
#else
|
||||
|
||||
#define QT_RED 0
|
||||
#define QT_GREEN 1
|
||||
#define QT_BLUE 2
|
||||
#define QT_ALPHA 3
|
||||
|
||||
#endif
|
||||
|
||||
#define GTK_RED 2
|
||||
#define GTK_GREEN 1
|
||||
#define GTK_BLUE 0
|
||||
|
@@ -21,17 +21,210 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "stdafx.h"
|
||||
#include "platform/linux/notifications_manager_linux.h"
|
||||
|
||||
#include "window/notifications_utilities.h"
|
||||
#include "platform/linux/linux_libnotify.h"
|
||||
#include "platform/linux/linux_libs.h"
|
||||
|
||||
namespace Platform {
|
||||
namespace Notifications {
|
||||
namespace {
|
||||
|
||||
void start() {
|
||||
NeverFreedPointer<Manager> ManagerInstance;
|
||||
|
||||
bool supported() {
|
||||
return (Libs::notify_init != nullptr)
|
||||
&& (Libs::notify_uninit != nullptr)
|
||||
&& (Libs::notify_is_initted != nullptr)
|
||||
// && (Libs::notify_get_app_name != nullptr)
|
||||
// && (Libs::notify_set_app_name != nullptr)
|
||||
&& (Libs::notify_get_server_caps != nullptr)
|
||||
&& (Libs::notify_get_server_info != nullptr)
|
||||
&& (Libs::notify_notification_new != nullptr)
|
||||
&& (Libs::notify_notification_update != nullptr)
|
||||
&& (Libs::notify_notification_show != nullptr)
|
||||
// && (Libs::notify_notification_set_app_name != nullptr)
|
||||
// && (Libs::notify_notification_set_timeout != nullptr)
|
||||
// && (Libs::notify_notification_set_category != nullptr)
|
||||
// && (Libs::notify_notification_set_urgency != nullptr)
|
||||
// && (Libs::notify_notification_set_icon_from_pixbuf != nullptr)
|
||||
&& (Libs::notify_notification_set_image_from_pixbuf != nullptr)
|
||||
// && (Libs::notify_notification_set_hint != nullptr)
|
||||
// && (Libs::notify_notification_set_hint_int32 != nullptr)
|
||||
// && (Libs::notify_notification_set_hint_uint32 != nullptr)
|
||||
// && (Libs::notify_notification_set_hint_double != nullptr)
|
||||
// && (Libs::notify_notification_set_hint_string != nullptr)
|
||||
// && (Libs::notify_notification_set_hint_byte != nullptr)
|
||||
// && (Libs::notify_notification_set_hint_byte_array != nullptr)
|
||||
// && (Libs::notify_notification_clear_hints != nullptr)
|
||||
// && (Libs::notify_notification_add_action != nullptr)
|
||||
// && (Libs::notify_notification_clear_actions != nullptr)
|
||||
&& (Libs::notify_notification_close != nullptr)
|
||||
&& (Libs::notify_notification_get_closed_reason != nullptr)
|
||||
&& (Libs::g_object_unref != nullptr)
|
||||
// && (Libs::gdk_pixbuf_new_from_data != nullptr)
|
||||
&& (Libs::gdk_pixbuf_new_from_file != nullptr);
|
||||
}
|
||||
|
||||
Window::Notifications::Manager *manager() {
|
||||
return nullptr;
|
||||
} // namespace
|
||||
|
||||
void start() {
|
||||
if (supported()) {
|
||||
if (Libs::notify_is_initted() || Libs::notify_init("Telegram Desktop")) {
|
||||
ManagerInstance.makeIfNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Manager *manager() {
|
||||
return ManagerInstance.data();
|
||||
}
|
||||
|
||||
void finish() {
|
||||
if (manager()) {
|
||||
ManagerInstance.reset();
|
||||
Libs::notify_uninit();
|
||||
}
|
||||
}
|
||||
|
||||
class Manager::Impl {
|
||||
public:
|
||||
void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton);
|
||||
void clearAll();
|
||||
void clearFromHistory(History *history);
|
||||
|
||||
private:
|
||||
static void notificationClosed(Libs::NotifyNotification *notification, gpointer data);
|
||||
void clearNotification(Libs::NotifyNotification *notification);
|
||||
|
||||
using Notifications = QMap<PeerId, QMap<MsgId, Libs::NotifyNotification*>>;
|
||||
Notifications _notifications;
|
||||
|
||||
using NotificationsData = QMap<Libs::NotifyNotification*, QPair<PeerId, MsgId>>;
|
||||
NotificationsData _notificationsData;
|
||||
|
||||
Window::Notifications::CachedUserpics _cachedUserpics;
|
||||
|
||||
};
|
||||
|
||||
void Manager::Impl::notificationClosed(Libs::NotifyNotification *notification, gpointer data) {
|
||||
if (auto manager = ManagerInstance.data()) {
|
||||
manager->_impl->clearNotification(notification);
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::Impl::clearNotification(Libs::NotifyNotification *notification) {
|
||||
auto dataIt = _notificationsData.find(notification);
|
||||
if (dataIt == _notificationsData.cend()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto peerId = dataIt->first;
|
||||
auto msgId = dataIt->second;
|
||||
_notificationsData.erase(dataIt);
|
||||
|
||||
auto i = _notifications.find(peerId);
|
||||
if (i != _notifications.cend()) {
|
||||
auto it = i.value().find(msgId);
|
||||
if (it != i.value().cend()) {
|
||||
Libs::g_object_unref(Libs::g_object_cast(it.value()));
|
||||
i.value().erase(it);
|
||||
if (i.value().isEmpty()) {
|
||||
_notifications.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) {
|
||||
auto titleUtf8 = title.toUtf8();
|
||||
auto bodyUtf8 = (subtitle.isEmpty() ? msg : ("<b>" + subtitle + "</b>\n" + msg)).toUtf8();
|
||||
auto notification = Libs::notify_notification_new(titleUtf8.constData(), bodyUtf8.constData(), nullptr);
|
||||
if (!notification) {
|
||||
return;
|
||||
}
|
||||
|
||||
Libs::g_signal_connect_helper(Libs::g_object_cast(notification), "closed", G_CALLBACK(Manager::Impl::notificationClosed), peer);
|
||||
|
||||
StorageKey key;
|
||||
if (showUserpic) {
|
||||
key = peer->userpicUniqueKey();
|
||||
} else {
|
||||
key = StorageKey(0, 0);
|
||||
}
|
||||
auto userpicPath = _cachedUserpics.get(key, peer);
|
||||
auto userpicPathNative = QFile::encodeName(userpicPath);
|
||||
if (auto pixbuf = Libs::gdk_pixbuf_new_from_file(userpicPathNative.constData(), nullptr)) {
|
||||
Libs::notify_notification_set_image_from_pixbuf(notification, pixbuf);
|
||||
Libs::g_object_unref(Libs::g_object_cast(pixbuf));
|
||||
}
|
||||
|
||||
auto i = _notifications.find(peer->id);
|
||||
if (i != _notifications.cend()) {
|
||||
auto j = i->find(msgId);
|
||||
if (j != i->cend()) {
|
||||
auto oldNotification = j.value();
|
||||
i->erase(j);
|
||||
_notificationsData.remove(oldNotification);
|
||||
Libs::notify_notification_close(oldNotification, nullptr);
|
||||
Libs::g_object_unref(Libs::g_object_cast(oldNotification));
|
||||
i = _notifications.find(peer->id);
|
||||
}
|
||||
}
|
||||
if (i == _notifications.cend()) {
|
||||
i = _notifications.insert(peer->id, QMap<MsgId, Libs::NotifyNotification*>());
|
||||
}
|
||||
auto result = Libs::notify_notification_show(notification, nullptr);
|
||||
if (!result) {
|
||||
Libs::g_object_unref(Libs::g_object_cast(notification));
|
||||
i = _notifications.find(peer->id);
|
||||
if (i != _notifications.cend() && i->isEmpty()) _notifications.erase(i);
|
||||
return;
|
||||
}
|
||||
_notifications[peer->id].insert(msgId, notification);
|
||||
_notificationsData.insert(notification, qMakePair(peer->id, msgId));
|
||||
}
|
||||
|
||||
void Manager::Impl::clearAll() {
|
||||
_notificationsData.clear();
|
||||
|
||||
auto temp = createAndSwap(_notifications);
|
||||
for_const (auto ¬ifications, temp) {
|
||||
for_const (auto notification, notifications) {
|
||||
Libs::notify_notification_close(notification, nullptr);
|
||||
Libs::g_object_unref(Libs::g_object_cast(notification));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::Impl::clearFromHistory(History *history) {
|
||||
auto i = _notifications.find(history->peer->id);
|
||||
if (i != _notifications.cend()) {
|
||||
auto temp = createAndSwap(i.value());
|
||||
_notifications.erase(i);
|
||||
|
||||
for_const (auto notification, temp) {
|
||||
_notificationsData.remove(notification);
|
||||
Libs::notify_notification_close(notification, nullptr);
|
||||
Libs::g_object_unref(Libs::g_object_cast(notification));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Manager::Manager() : _impl(std_::make_unique<Impl>()) {
|
||||
}
|
||||
|
||||
Manager::~Manager() = default;
|
||||
|
||||
void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) {
|
||||
_impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton);
|
||||
}
|
||||
|
||||
void Manager::doClearAllFast() {
|
||||
_impl->clearAll();
|
||||
}
|
||||
|
||||
void Manager::doClearFromHistory(History *history) {
|
||||
_impl->clearFromHistory(history);
|
||||
}
|
||||
|
||||
} // namespace Notifications
|
||||
|
@@ -25,12 +25,31 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
namespace Platform {
|
||||
namespace Notifications {
|
||||
|
||||
class Manager;
|
||||
|
||||
void start();
|
||||
Window::Notifications::Manager *manager();
|
||||
Manager *manager();
|
||||
void finish();
|
||||
|
||||
inline void defaultNotificationShown(QWidget *widget) {
|
||||
}
|
||||
|
||||
class Manager : public Window::Notifications::NativeManager {
|
||||
public:
|
||||
Manager();
|
||||
~Manager();
|
||||
|
||||
protected:
|
||||
void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override;
|
||||
void doClearAllFast() override;
|
||||
void doClearFromHistory(History *history) override;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
friend class Impl;
|
||||
std_::unique_ptr<Impl> _impl;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Notifications
|
||||
} // namespace Platform
|
||||
|
Reference in New Issue
Block a user