diff --git a/plugins/windows-notification/api/src/gobject/winrt-toast-notification.cpp b/plugins/windows-notification/api/src/gobject/winrt-toast-notification.cpp index dac44880..ffaa9326 100644 --- a/plugins/windows-notification/api/src/gobject/winrt-toast-notification.cpp +++ b/plugins/windows-notification/api/src/gobject/winrt-toast-notification.cpp @@ -2,7 +2,9 @@ #include #include #include +#include #include +#include #include "winrt-toast-notification-private.h" #include "winrt-event-token-private.h" @@ -11,23 +13,19 @@ #define WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(obj) \ ((winrtWindowsUINotificationsToastNotificationPrivate*) winrt_windows_ui_notifications_toast_notification_get_instance_private ((winrtWindowsUINotificationsToastNotification*) (obj))) -typedef struct -{ - winrt::Windows::UI::Notifications::ToastNotification data; -} _winrtWindowsUINotificationsToastNotificationPrivate; - template -class Callback { -public: +struct Callback { T callback; void* context; void(*free)(void*); + winrtEventToken* token; - Callback(T callback, void* context, void(*free)(void*)) + Callback(T callback, void* context, void(*free)(void*), winrtEventToken* token) { this->callback = callback; this->free = free; this->context = context; + this->token = token; } ~Callback() @@ -42,30 +40,32 @@ public: this->free(this->context); } - callback = nullptr; - context = nullptr; - free = nullptr; + this->callback = nullptr; + this->context = nullptr; + this->free = nullptr; + this->token = nullptr; } // delete copy Callback(const Callback&) = delete; Callback& operator=(const Callback&) = delete; - // allow move - Callback(Callback&&) = default; - Callback& operator=(Callback&&) = default; + // delete move + Callback(Callback&&) = delete; + Callback& operator=(Callback&&) = delete; +}; + +struct _winrtWindowsUINotificationsToastNotificationPrivate +{ + winrt::Windows::UI::Notifications::ToastNotification data; + + std::list>> activated; + std::list>> failed; + std::list>> dismissed; }; typedef struct { - std::unordered_map> activated; - - std::unordered_map> failed; - - // Notification_Callback_Dismissed callback; - // void* context; - // void(*free)(void*); - _winrtWindowsUINotificationsToastNotificationPrivate* notification; } winrtWindowsUINotificationsToastNotificationPrivate; @@ -75,27 +75,25 @@ static void winrt_windows_ui_notifications_toast_notification_finalize(GObject* { winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE (self); - for (const auto& item : priv->activated) + for (const auto& item : priv->notification->activated) { - auto token = std::get<0>(item); + auto token = item->token; if (winrt_event_token_operator_bool(token)) { priv->notification->data.Activated(*winrt_event_token_get_internal(token)); } g_object_unref(token); } - priv->activated.clear(); - for (const auto& item : priv->failed) + for (const auto& item : priv->notification->failed) { - auto token = std::get<0>(item); + auto token = item->token; if (winrt_event_token_operator_bool(token)) { priv->notification->data.Failed(*winrt_event_token_get_internal(token)); } g_object_unref(token); } - priv->failed.clear(); delete priv->notification; @@ -155,7 +153,7 @@ void winrt_windows_ui_notifications_toast_notification_set_internal(winrtWindows */ winrtWindowsUINotificationsToastNotification* winrt_windows_ui_notifications_toast_notification_new(const char* doc) { - g_return_val_if_fail (doc == NULL, NULL); + g_return_val_if_fail (doc != NULL, NULL); auto ret = static_cast(g_object_new (WINRT_TYPE_WINDOWS_UI_NOTIFICATIONS_TOAST_NOTIFICATION, NULL)); winrt::Windows::Data::Xml::Dom::XmlDocument xmlDoc; @@ -229,7 +227,7 @@ winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(win winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(self); - auto token = priv->notification->data.Activated([&](auto sender, winrt::Windows::Foundation::IInspectable inspectable) + auto token = priv->notification->data.Activated([=](auto sender, winrt::Windows::Foundation::IInspectable inspectable) { std::wstring arguments; std::vector> user_input; @@ -254,12 +252,12 @@ winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(win } std::cout << "Notification activated!" << std::endl; - callback(wsview_to_char(arguments.data()), nullptr /* user_input */ , 0 /* user_input.size() */, context); + callback(wsview_to_char(arguments), nullptr /* user_input */ , 0 /* user_input.size() */, context); }); auto new_token = winrt_event_token_new_from_token(&token); g_object_ref(new_token); - priv->activated.emplace(new_token, Callback(callback, context, free)); + priv->notification->activated.push_back(std::make_shared>(callback, context, free, new_token)); return new_token; } @@ -269,15 +267,16 @@ void winrt_windows_ui_notifications_toast_notification_RemoveActivated(winrtWind winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(self); - auto item = priv->activated.find(token); - if (item != priv->activated.end()) - { - auto local_token = std::get<0>(*item); - if (winrt_event_token_operator_bool(local_token)) - { - priv->notification->data.Activated(*winrt_event_token_get_internal(local_token)); + priv->notification->activated.remove_if([&](const auto& callback) { + if (winrt_event_token_get_value(token) == winrt_event_token_get_value(callback->token)) + { + if (winrt_event_token_operator_bool(callback->token)) + { + priv->notification->data.Activated(*winrt_event_token_get_internal(callback->token)); + } + g_object_unref(callback->token); + return true; } - - priv->activated.erase(item); - } + return false; + }); } \ No newline at end of file diff --git a/plugins/windows-notification/api/src/gobject/winrt-toast-notifier.cpp b/plugins/windows-notification/api/src/gobject/winrt-toast-notifier.cpp index 35bb2e6d..5dd82279 100644 --- a/plugins/windows-notification/api/src/gobject/winrt-toast-notifier.cpp +++ b/plugins/windows-notification/api/src/gobject/winrt-toast-notifier.cpp @@ -83,9 +83,9 @@ void winrt_windows_ui_notifications_toast_notifier_set_internal(winrtWindowsUINo */ winrtWindowsUINotificationsToastNotifier* winrt_windows_ui_notifications_toast_notifier_new(const gchar* aumid) { - g_return_val_if_fail (aumid == NULL, NULL); + g_return_val_if_fail (aumid != NULL, NULL); - auto ret = static_cast(g_object_new (WINRT_TYPE_WINDOWS_UI_NOTIFICATIONS_TOAST_NOTIFICATION, NULL)); + auto ret = static_cast(g_object_new (WINRT_TYPE_WINDOWS_UI_NOTIFICATIONS_TOAST_NOTIFIER, NULL)); auto notifier = winrt::Windows::UI::Notifications::ToastNotificationManager::CreateToastNotifier(sview_to_wstr(aumid)); winrt_windows_ui_notifications_toast_notifier_set_internal(ret, notifier); return ret; diff --git a/plugins/windows-notification/api/src/gobject/winrt.cpp b/plugins/windows-notification/api/src/gobject/winrt.cpp index faf1b6ef..4cfe3b34 100644 --- a/plugins/windows-notification/api/src/gobject/winrt.cpp +++ b/plugins/windows-notification/api/src/gobject/winrt.cpp @@ -1,17 +1,24 @@ #include #include "gobject/winrt-private.h" +#include "converter.hpp" gboolean winrt_InitApartment() { try { - winrt::init_apartment(); // TODO: FIXME, header only works with unity build + winrt::init_apartment(); return true; } - catch(const std::exception& e) + catch(const winrt::hresult_error& e) { - std::cerr << e.what() << '\n'; + auto message = wsview_to_char(e.message()); + std::cerr << message << '\n'; + delete[] message; + if (e.code() == -2147417850 /* RPC_E_CHANGED_MODE */) // harmless + { + return true; + } } return false; diff --git a/plugins/windows-notification/api/src/shortcutcreator.cpp b/plugins/windows-notification/api/src/shortcutcreator.cpp index 2ef8c6fc..8084d218 100644 --- a/plugins/windows-notification/api/src/shortcutcreator.cpp +++ b/plugins/windows-notification/api/src/shortcutcreator.cpp @@ -131,7 +131,7 @@ int32_t TryCreateShortcutInternal(const std::wstring& aumid) if (shortcutPath && exePath) { - auto path = shortcutPath.value() + LR"(\Microsoft\Windows\Start Menu\Programs\Testando.lnk)"; + auto path = shortcutPath.value() + LR"(\Microsoft\Windows\Start Menu\Programs\Dino.lnk)"; if (!std::filesystem::exists(path)) { return InstallShortcut(exePath.value(), aumid, path); diff --git a/plugins/windows-notification/src/plugin.vala b/plugins/windows-notification/src/plugin.vala index 3a6b3758..fd804595 100644 --- a/plugins/windows-notification/src/plugin.vala +++ b/plugins/windows-notification/src/plugin.vala @@ -1,13 +1,14 @@ using Gee; using Dino.Entities; using Dino.Plugins.WindowsNotification.Vapi; +using winrt.Windows.UI.Notifications; namespace Dino.Plugins.WindowsNotification { public class Plugin : RootInterface, Object { private static string AUMID = "org.dino.Dino"; - - public int m { get; set; } + private ToastNotifier notifier; + private ToastNotification notification; // Notifications remove their actions when they get out of scope public void registered(Dino.Application app) { if (!winrt.InitApartment()) @@ -26,23 +27,40 @@ public class Plugin : RootInterface, Object { } { - var notifier = new winrt.Windows.UI.Notifications.ToastNotifier(AUMID); - var m = new winrt.Windows.UI.Notifications.ToastNotification("Test"); - var token = m.Activated((c, d) => { + var text = " + + + + Adam Wilson tagged you in a photo + On top of McClellan Butte - with Andrew Bares + + + + + + + + "; + + this.notifier = new ToastNotifier(AUMID); + this.notification = new ToastNotification(text); + var token = notification.Activated((c, d) => { var i = 2; + stdout.printf("Yay! Activated 1!\n"); }); - m.RemoveActivated(token); + notification.RemoveActivated(token); - var h = m.ExpiresOnReboot; - m.ExpiresOnReboot = false; + token = notification.Activated((c, d) => { + var i = 2; + stdout.printf("Yay! Activated 2!\n"); + }); - var a = m.Tag; - m.Tag = "a"; - - a = m.Group; - m.Group = "a"; - - notifier.Show(m); + notifier.Show(notification); } // var provider = new WindowsNotificationProvider(app, Win32Api.SupportsModernNotifications()); diff --git a/plugins/windows-notification/vapi/winrt_windows_ui_notifications.vapi b/plugins/windows-notification/vapi/winrt_windows_ui_notifications.vapi index f127327f..7e07ea36 100644 --- a/plugins/windows-notification/vapi/winrt_windows_ui_notifications.vapi +++ b/plugins/windows-notification/vapi/winrt_windows_ui_notifications.vapi @@ -1,3 +1,5 @@ +using winrt; + [CCode (cheader_filename = "gobject/winrt-glib.h")] namespace winrt.Windows.UI.Notifications { [CCode (cname = "NotificationCallbackSimple", has_target = true)] @@ -15,8 +17,8 @@ namespace winrt.Windows.UI.Notifications { public bool ExpiresOnReboot { get; set; } public string Tag { get; set; } // TODO: check if valac is cleaning this string public string Group { get; set; } - public winrt.EventToken Activated(owned NotificationCallbackActivated handler); - public void RemoveActivated(winrt.EventToken token); + public EventToken Activated(owned NotificationCallbackActivated handler); + public void RemoveActivated(EventToken token); } [CCode (type_id = "winrt_windows_ui_notifications_toast_notifier_get_type ()")]