diff --git a/Telegram/SourceFiles/platform/linux/integration_linux.cpp b/Telegram/SourceFiles/platform/linux/integration_linux.cpp index 147a9f03c..e8696772e 100644 --- a/Telegram/SourceFiles/platform/linux/integration_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/integration_linux.cpp @@ -10,10 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/platform_integration.h" #include "base/platform/base_platform_info.h" #include "base/platform/linux/base_linux_xdp_utilities.h" -#include "window/notifications_manager.h" #include "core/sandbox.h" #include "core/application.h" -#include "core/core_settings.h" #include "base/random.h" #include @@ -27,32 +25,6 @@ namespace { using namespace gi::repository; namespace GObject = gi::repository::GObject; -std::vector AnyVectorFromVariant(GLib::Variant value) { - std::vector result; - - GLib::VariantIter iter; - iter.allocate_(); - iter.init(value); - - const auto uint64Type = GLib::VariantType::new_("t"); - const auto int64Type = GLib::VariantType::new_("x"); - - while (auto value = iter.next_value()) { - value = value.get_variant(); - if (value.is_of_type(uint64Type)) { - result.push_back(std::make_any(value.get_uint64())); - } else if (value.is_of_type(int64Type)) { - result.push_back(std::make_any(value.get_int64())); - } else if (value.is_container()) { - result.push_back( - std::make_any>( - AnyVectorFromVariant(value))); - } - } - - return result; -} - class Application : public Gio::impl::ApplicationImpl { public: Application(); @@ -125,42 +97,18 @@ Application::Application() }); actionMap.add_action(quitAction); - using Window::Notifications::Manager; - using NotificationId = Manager::NotificationId; - - const auto notificationIdVariantType = GLib::VariantType::new_("av"); + const auto notificationIdVariantType = GLib::VariantType::new_("a{sv}"); auto notificationActivateAction = Gio::SimpleAction::new_( "notification-activate", notificationIdVariantType); - notificationActivateAction.signal_activate().connect([]( - Gio::SimpleAction, - GLib::Variant parameter) { - Core::Sandbox::Instance().customEnterFromEventLoop([&] { - Core::App().notifications().manager().notificationActivated( - NotificationId::FromAnyVector( - AnyVectorFromVariant(parameter))); - }); - }); - actionMap.add_action(notificationActivateAction); auto notificationMarkAsReadAction = Gio::SimpleAction::new_( "notification-mark-as-read", notificationIdVariantType); - notificationMarkAsReadAction.signal_activate().connect([]( - Gio::SimpleAction, - GLib::Variant parameter) { - Core::Sandbox::Instance().customEnterFromEventLoop([&] { - Core::App().notifications().manager().notificationReplied( - NotificationId::FromAnyVector( - AnyVectorFromVariant(parameter)), - {}); - }); - }); - actionMap.add_action(notificationMarkAsReadAction); } diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index 5120200cc..4a8ac2b12 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -139,32 +139,6 @@ bool UseGNotification() { return KSandbox::isFlatpak() && !ServiceRegistered; } -GLib::Variant AnyVectorToVariant(const std::vector &value) { - return GLib::Variant::new_array( - value | ranges::views::transform([](const std::any &value) { - try { - return GLib::Variant::new_variant( - GLib::Variant::new_uint64(std::any_cast(value))); - } catch (...) { - } - - try { - return GLib::Variant::new_variant( - GLib::Variant::new_int64(std::any_cast(value))); - } catch (...) { - } - - try { - return GLib::Variant::new_variant( - AnyVectorToVariant( - std::any_cast>(value))); - } catch (...) { - } - - return GLib::Variant(nullptr); - }) | ranges::to_vector); -} - class NotificationData final : public base::has_weak_ptr { public: using NotificationId = Window::Notifications::Manager::NotificationId; @@ -212,6 +186,8 @@ private: ulong _notificationRepliedSignalId = 0; ulong _notificationClosedSignalId = 0; + rpl::lifetime _lifetime; + }; using Notification = std::unique_ptr; @@ -238,6 +214,57 @@ bool NotificationData::init(const Info &info) { const auto &subtitle = info.subtitle; if (_application) { + auto actionMap = Gio::ActionMap(_application); + + const auto dictToNotificationId = [](GLib::VariantDict dict) { + using ContextId = Window::Notifications::Manager::ContextId; + return NotificationId{ + .contextId = ContextId{ + .sessionId = dict.lookup_value("session").get_uint64(), + .peerId = PeerId(dict.lookup_value("peer").get_uint64()), + .topicRootId = dict.lookup_value("topic").get_int64(), + }, + .msgId = dict.lookup_value("msgid").get_int64(), + }; + }; + + auto activate = gi::wrap( + G_SIMPLE_ACTION( + actionMap.lookup_action("notification-activate").gobj_()), + gi::transfer_none); + + const auto activateSig = activate.signal_activate().connect([=]( + Gio::SimpleAction, + GLib::Variant parameter) { + Core::Sandbox::Instance().customEnterFromEventLoop([&] { + _manager->notificationActivated( + dictToNotificationId(GLib::VariantDict::new_(parameter))); + }); + }); + + _lifetime.add([=]() mutable { + activate.disconnect(activateSig); + }); + + auto markAsRead = gi::wrap( + G_SIMPLE_ACTION( + actionMap.lookup_action("notification-mark-as-read").gobj_()), + gi::transfer_none); + + const auto markAsReadSig = markAsRead.signal_activate().connect([=]( + Gio::SimpleAction, + GLib::Variant parameter) { + Core::Sandbox::Instance().customEnterFromEventLoop([&] { + _manager->notificationReplied( + dictToNotificationId(GLib::VariantDict::new_(parameter)), + {}); + }); + }); + + _lifetime.add([=]() mutable { + markAsRead.disconnect(markAsReadSig); + }); + _notification = Gio::Notification::new_( subtitle.isEmpty() ? title.toStdString() @@ -264,17 +291,40 @@ bool NotificationData::init(const Info &info) { set_category(_notification.gobj_(), "im.received"); } - const auto idVariant = AnyVectorToVariant(_id.toAnyVector()); + const auto peer = info.peer; + + const auto notificationVariant = GLib::Variant::new_array({ + GLib::Variant::new_dict_entry( + GLib::Variant::new_string("session"), + GLib::Variant::new_variant( + GLib::Variant::new_uint64(peer->session().uniqueId()))), + GLib::Variant::new_dict_entry( + GLib::Variant::new_string("peer"), + GLib::Variant::new_variant( + GLib::Variant::new_uint64(peer->id.value))), + GLib::Variant::new_dict_entry( + GLib::Variant::new_string("peer"), + GLib::Variant::new_variant( + GLib::Variant::new_uint64(peer->id.value))), + GLib::Variant::new_dict_entry( + GLib::Variant::new_string("topic"), + GLib::Variant::new_variant( + GLib::Variant::new_int64(info.topicRootId.bare))), + GLib::Variant::new_dict_entry( + GLib::Variant::new_string("msgid"), + GLib::Variant::new_variant( + GLib::Variant::new_int64(info.itemId.bare))), + }); _notification.set_default_action_and_target( "app.notification-activate", - idVariant); + notificationVariant); if (!info.options.hideMarkAsRead) { _notification.add_button_with_target( tr::lng_context_mark_read(tr::now).toStdString(), "app.notification-mark-as-read", - idVariant); + notificationVariant); } return true; diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index 3e8f8812e..ce39e6fb1 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -212,11 +212,6 @@ void System::setManager(Fn()> create) { } } -Manager &System::manager() const { - Expects(_manager != nullptr); - return *_manager; -} - Main::Session *System::findSession(uint64 sessionId) const { for (const auto &[index, account] : Core::App().domain().accounts()) { if (const auto session = account->maybeSession()) { diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index fa88f6c0a..833a79d00 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -100,7 +100,6 @@ public: void createManager(); void setManager(Fn()> create); - [[nodiscard]] Manager &manager() const; void checkDelayed(); void schedule(Data::ItemNotification notification); @@ -237,22 +236,6 @@ public: friend inline auto operator<=>( const ContextId&, const ContextId&) = default; - - [[nodiscard]] auto toAnyVector() const { - return std::vector{ - std::make_any(sessionId), - std::make_any(peerId.value), - std::make_any(topicRootId.bare), - }; - } - - [[nodiscard]] static auto FromAnyVector(const auto &vector) { - return ContextId{ - std::any_cast(vector[0]), - PeerIdHelper(std::any_cast(vector[1])), - std::any_cast(vector[2]), - }; - } }; struct NotificationId { ContextId contextId; @@ -261,21 +244,6 @@ public: friend inline auto operator<=>( const NotificationId&, const NotificationId&) = default; - - [[nodiscard]] auto toAnyVector() const { - return std::vector{ - std::make_any>(contextId.toAnyVector()), - std::make_any(msgId.bare), - }; - } - - [[nodiscard]] static auto FromAnyVector(const auto &vector) { - return NotificationId{ - ContextId::FromAnyVector( - std::any_cast>(vector[0])), - std::any_cast(vector[1]), - }; - } }; struct NotificationFields { not_null item;