From ca0cab0e36506138b80b2b5cecd0ce1c2e46ebbf Mon Sep 17 00:00:00 2001 From: LAGonauta Date: Sun, 21 Feb 2021 20:13:23 -0300 Subject: [PATCH] Initial code to allow buttons and text --- plugins/windows-notification/CMakeLists.txt | 5 +- .../api/include/gobject/winrt-headers.h | 1 + .../api/include/gobject/winrt-private.h | 2 +- .../gobject/winrt-toast-notification.h | 18 +-- .../api/include/gobject/winrt.h | 6 +- .../api/src/gobject/winrt-event-token.cpp | 5 +- .../src/gobject/winrt-toast-notification.cpp | 114 ++++++++++++------ .../api/src/gobject/winrt.cpp | 2 +- .../windows-notification/api/src/unity.cpp | 4 + .../vapi/winrt_windows_ui_notifications.vapi | 8 +- 10 files changed, 106 insertions(+), 59 deletions(-) create mode 100644 plugins/windows-notification/api/src/unity.cpp diff --git a/plugins/windows-notification/CMakeLists.txt b/plugins/windows-notification/CMakeLists.txt index 829f2c00..cb9998d3 100644 --- a/plugins/windows-notification/CMakeLists.txt +++ b/plugins/windows-notification/CMakeLists.txt @@ -27,10 +27,7 @@ PACKAGES ) set(WINDOWS_API_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt-enums.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt-event-token.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt-toast-notification.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/api/src/unity.cpp ${CMAKE_CURRENT_SOURCE_DIR}/api/src/win32.cpp ${CMAKE_CURRENT_SOURCE_DIR}/api/src/converter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/api/src/shortcutcreator.cpp diff --git a/plugins/windows-notification/api/include/gobject/winrt-headers.h b/plugins/windows-notification/api/include/gobject/winrt-headers.h index bd9bdb25..e5428c83 100644 --- a/plugins/windows-notification/api/include/gobject/winrt-headers.h +++ b/plugins/windows-notification/api/include/gobject/winrt-headers.h @@ -4,5 +4,6 @@ #include #include #include +#include #endif /* __WINRT_HEADERS_H__ */ diff --git a/plugins/windows-notification/api/include/gobject/winrt-private.h b/plugins/windows-notification/api/include/gobject/winrt-private.h index 6a66f079..a5249325 100644 --- a/plugins/windows-notification/api/include/gobject/winrt-private.h +++ b/plugins/windows-notification/api/include/gobject/winrt-private.h @@ -3,6 +3,6 @@ #include #include "winrt.h" -//#include "gobject/winrt-headers.h" +#include "gobject/winrt-headers.h" #endif // __WINRT_GLIB_H_PRIVATE__ \ No newline at end of file diff --git a/plugins/windows-notification/api/include/gobject/winrt-toast-notification.h b/plugins/windows-notification/api/include/gobject/winrt-toast-notification.h index 82a043f0..18874eda 100644 --- a/plugins/windows-notification/api/include/gobject/winrt-toast-notification.h +++ b/plugins/windows-notification/api/include/gobject/winrt-toast-notification.h @@ -25,25 +25,25 @@ extern "C" { #endif -typedef void(*Notification_Callback_Simple)(void* userdata); -typedef void(*Notification_Callback_ActivatedWithActionIndex)(int action_id, void* userdata); +typedef void(*NotificationCallbackSimple)(void* userdata); +typedef void(*NotificationCallbackActivated)(const gchar* arguments, gchar** userInput, gint count, void* userdata); //typedef void(*Notification_Callback_Dismissed)(Dismissed_Reason reason, void* userdata); -winrtWindowsUINotificationsToastNotification* winrt_windows_ui_notifications_toast_notification_new(const char* doc); +winrtWindowsUINotificationsToastNotification* winrt_windows_ui_notifications_toast_notification_new(const gchar* doc); void winrt_windows_ui_notifications_toast_notification_set_ExpiresOnReboot(winrtWindowsUINotificationsToastNotification* self, gboolean value); gboolean winrt_windows_ui_notifications_toast_notification_get_ExpiresOnReboot(winrtWindowsUINotificationsToastNotification* self); -void winrt_windows_ui_notifications_toast_notification_set_Tag(winrtWindowsUINotificationsToastNotification* self, const char* value); -char* winrt_windows_ui_notifications_toast_notification_get_Tag(winrtWindowsUINotificationsToastNotification* self); +void winrt_windows_ui_notifications_toast_notification_set_Tag(winrtWindowsUINotificationsToastNotification* self, const gchar* value); +gchar* winrt_windows_ui_notifications_toast_notification_get_Tag(winrtWindowsUINotificationsToastNotification* self); -void winrt_windows_ui_notifications_toast_notification_set_Group(winrtWindowsUINotificationsToastNotification* self, const char* value); -char* winrt_windows_ui_notifications_toast_notification_get_Group(winrtWindowsUINotificationsToastNotification* self); +void winrt_windows_ui_notifications_toast_notification_set_Group(winrtWindowsUINotificationsToastNotification* self, const gchar* value); +gchar* winrt_windows_ui_notifications_toast_notification_get_Group(winrtWindowsUINotificationsToastNotification* self); -winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(winrtWindowsUINotificationsToastNotification* self, Notification_Callback_Simple callback, void* context, void(*free)(void*)); +winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackActivated callback, void* context, void(*free)(void*)); void winrt_windows_ui_notifications_toast_notification_RemoveActivatedAction(winrtWindowsUINotificationsToastNotification* self, winrtEventToken* token); -winrtEventToken* winrt_windows_ui_notifications_toast_notification_Failed(winrtWindowsUINotificationsToastNotification* self, Notification_Callback_Simple callback, void* context, void(*free)(void*)); +winrtEventToken* winrt_windows_ui_notifications_toast_notification_Failed(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackSimple callback, void* context, void(*free)(void*)); //winrtEventToken* winrt_windows_ui_notifications_toast_notification_Dismissed(winrtWindowsUINotificationsToastNotification* self, Notification_Callback_Dismissed callback, void* context, void(*free)(void*)); #ifdef __cplusplus diff --git a/plugins/windows-notification/api/include/gobject/winrt.h b/plugins/windows-notification/api/include/gobject/winrt.h index 5fef5124..28520e97 100644 --- a/plugins/windows-notification/api/include/gobject/winrt.h +++ b/plugins/windows-notification/api/include/gobject/winrt.h @@ -1,5 +1,5 @@ -#ifndef __WINRT_GLIB_H__ -#define __WINRT_GLIB_H__ +#ifndef __WINRT_GLIB_2_H__ +#define __WINRT_GLIB_2_H__ #ifdef __cplusplus extern "C" @@ -12,4 +12,4 @@ gboolean winrt_InitApartment(); } #endif -#endif // __WINRT_GLIB_H__ \ No newline at end of file +#endif // __WINRT_GLIB_2_H__ \ No newline at end of file diff --git a/plugins/windows-notification/api/src/gobject/winrt-event-token.cpp b/plugins/windows-notification/api/src/gobject/winrt-event-token.cpp index 902bf5df..2981c2b0 100644 --- a/plugins/windows-notification/api/src/gobject/winrt-event-token.cpp +++ b/plugins/windows-notification/api/src/gobject/winrt-event-token.cpp @@ -68,10 +68,9 @@ gboolean winrt_event_token_operator_bool(winrtEventToken* self) return winrt_event_token_get_internal(self)->operator bool(); } -gint64 winrt_event_token_create_toast_notifier_get_value(winrtEventToken* self) +gint64 winrt_event_token_get_value(winrtEventToken* self) { g_return_val_if_fail (WINRT_IS_EVENT_TOKEN (self), 0); - //return winrt_event_token_get_internal(self)->value; - return 0; + return winrt_event_token_get_internal(self)->value; } \ No newline at end of file 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 3cae0a1c..2d20e759 100644 --- a/plugins/windows-notification/api/src/gobject/winrt-toast-notification.cpp +++ b/plugins/windows-notification/api/src/gobject/winrt-toast-notification.cpp @@ -12,6 +12,8 @@ #include #include +#include +#include #include "winrt-toast-notification-private.h" #include "winrt-event-token-private.h" @@ -25,15 +27,28 @@ typedef struct winrt::Windows::UI::Notifications::ToastNotification data; } _winrtWindowsUINotificationsToastNotificationPrivate; +template +class Callback { +public: + T callback; + void* context; + void(*free)(void*); + winrtEventToken* token; + + void Clear() + { + callback = nullptr; + context = nullptr; + free = nullptr; + g_clear_object(&token); + } +}; + typedef struct { - Notification_Callback_Simple activated; - void* activated_context; - void(*activated_free)(void*); + Callback activated; - Notification_Callback_Simple failed; - void* failed_context; - void(*failed_free)(void*); + Callback failed; // Notification_Callback_ActivatedWithActionIndex callback; // void* context; @@ -52,17 +67,24 @@ static void winrt_windows_ui_notifications_toast_notification_finalize(GObject* { winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE (self); - delete priv->notification; - - // TODO: save token to remove the notification - if (priv->activated && priv->activated_context && priv->activated_free) + if (winrt_event_token_operator_bool(priv->activated.token)) { - priv->activated_free(priv->activated_context); + priv->notification->data.Activated(*winrt_event_token_get_internal(priv->activated.token)); + g_clear_object(&priv->activated.token); } - if (priv->failed && priv->failed_context && priv->failed_free) + delete priv->notification; + + if (priv->activated.callback && priv->activated.context && priv->activated.free) { - priv->failed_free(priv->failed_context); + priv->activated.free(priv->activated.context); + priv->activated.Clear(); + } + + if (priv->failed.callback && priv->failed.context && priv->failed.free) + { + priv->failed.free(priv->failed.context); + priv->failed.Clear(); } G_OBJECT_CLASS(winrt_windows_ui_notifications_toast_notification_parent_class)->dispose(self); @@ -188,43 +210,67 @@ char* winrt_windows_ui_notifications_toast_notification_get_Group(winrtWindowsUI return wstr_to_char(std::wstring(winrt_windows_ui_notifications_toast_notification_get_internal(self)->Group())); } -winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(winrtWindowsUINotificationsToastNotification* self, Notification_Callback_Simple callback, void* context, void(*free)(void*)) +winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackActivated callback, void* context, void(*free)(void*)) { + g_return_val_if_fail (WINRT_IS_WINDOWS_UI_NOTIFICATIONS_TOAST_NOTIFICATION (self), NULL); + g_return_val_if_fail (callback != nullptr && context != nullptr && free != nullptr, NULL); + winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(self); - if (priv->activated && priv->activated_context && priv->activated_free) - { - // TODO: should also save token to unregister it - priv->activated_free(priv->activated_context); - } + winrt_windows_ui_notifications_toast_notification_RemoveActivatedAction(self, priv->activated.token); - priv->activated = callback; - priv->activated_context = context; - priv->activated_free = free; + priv->activated.callback = callback; + priv->activated.context = context; + priv->activated.free = free; auto token = priv->notification->data.Activated([&](auto sender, winrt::Windows::Foundation::IInspectable inspectable) { + std::wstring arguments; + std::vector> user_input; + { + auto args = inspectable.try_as(); + if (args != nullptr) + { + arguments = std::wstring(args.Arguments()); + } + } + + { + auto args = inspectable.try_as(); + if (args != nullptr) + { + for (const auto& item : args.UserInput()) + { + auto value = winrt::unbox_value_or(item.Value(), winrt::hstring()); + user_input.emplace_back(std::make_tuple(std::wstring(item.Key()), std::wstring(value))); + } + } + } + std::cout << "Notification activated!" << std::endl; - priv->activated(priv->activated_context); + priv->activated.callback(wstr_to_char(arguments.data()), nullptr, user_input.size(), priv->activated.context); }); - return winrt_event_token_new_from_token(&token); - return nullptr; + priv->activated.token = winrt_event_token_new_from_token(&token); + return priv->activated.token; } void winrt_windows_ui_notifications_toast_notification_RemoveActivatedAction(winrtWindowsUINotificationsToastNotification* self, winrtEventToken* token) { + g_return_if_fail (WINRT_IS_WINDOWS_UI_NOTIFICATIONS_TOAST_NOTIFICATION (self)); + winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(self); - if (winrt_event_token_operator_bool(token)) + if (winrt_event_token_get_value(token) == winrt_event_token_get_value(priv->activated.token)) { - priv->notification->data.Activated(*winrt_event_token_get_internal(token)); - } + if (winrt_event_token_operator_bool(token)) + { + priv->notification->data.Activated(*winrt_event_token_get_internal(token)); + } - if (priv->activated && priv->activated_context && priv->activated_free) - { - priv->activated_free(priv->activated_context); - priv->activated = nullptr; - priv->activated_context = nullptr; - priv->activated_free = nullptr; + if (priv->activated.callback && priv->activated.context && priv->activated.free) + { + priv->activated.free(priv->activated.context); + priv->activated.Clear(); + } } } \ No newline at end of file diff --git a/plugins/windows-notification/api/src/gobject/winrt.cpp b/plugins/windows-notification/api/src/gobject/winrt.cpp index 992874ad..faf1b6ef 100644 --- a/plugins/windows-notification/api/src/gobject/winrt.cpp +++ b/plugins/windows-notification/api/src/gobject/winrt.cpp @@ -6,7 +6,7 @@ gboolean winrt_InitApartment() { try { - //winrt::init_apartment(); // TODO: FIXME + winrt::init_apartment(); // TODO: FIXME, header only works with unity build return true; } catch(const std::exception& e) diff --git a/plugins/windows-notification/api/src/unity.cpp b/plugins/windows-notification/api/src/unity.cpp new file mode 100644 index 00000000..d996ab8d --- /dev/null +++ b/plugins/windows-notification/api/src/unity.cpp @@ -0,0 +1,4 @@ +#include "./gobject/winrt.cpp" +#include "./gobject/winrt-toast-notification.cpp" +#include "./gobject/winrt-event-token.cpp" +#include "./gobject/winrt-enums.cpp" \ No newline at end of file diff --git a/plugins/windows-notification/vapi/winrt_windows_ui_notifications.vapi b/plugins/windows-notification/vapi/winrt_windows_ui_notifications.vapi index a7bbf476..42eb1cb6 100644 --- a/plugins/windows-notification/vapi/winrt_windows_ui_notifications.vapi +++ b/plugins/windows-notification/vapi/winrt_windows_ui_notifications.vapi @@ -1,10 +1,10 @@ [CCode (cheader_filename = "gobject/winrt-glib.h")] namespace winrt.Windows.UI.Notifications { - [CCode (cname = "Notification_Callback_Simple", has_target = true)] + [CCode (cname = "NotificationCallbackSimple", has_target = true)] public delegate void NotificationCallbackSimple(); - // [CCode (cname = "Notification_Callback_ActivatedWithActionIndex", has_target = true)] - // public delegate void NotificationCallbackWithActionIndex(int actionId); + [CCode (cname = "NotificationCallbackActivated", has_target = true)] + public delegate void NotificationCallbackActivated(string? arguments, string[]? userInput); // [CCode (cname = "Notification_Callback_Dismissed", has_target = true)] // public delegate void NotificationCallbackDismissed(DismissedReason reason); @@ -15,7 +15,7 @@ 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 NotificationCallbackSimple handler); + public winrt.EventToken Activated(owned NotificationCallbackActivated handler); public void RemoveActivatedAction(winrt.EventToken token); } } \ No newline at end of file