Fields must be created in the private struct

Also change unordered_map to list, we do not need hashing and stuff.
This commit is contained in:
LAGonauta 2021-02-23 22:05:02 -03:00
parent 91d61843f2
commit 6cdaad315a
6 changed files with 91 additions and 65 deletions

View file

@ -2,7 +2,9 @@
#include <string>
#include <string_view>
#include <vector>
#include <list>
#include <tuple>
#include <memory>
#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 T>
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<std::shared_ptr<Callback<NotificationCallbackActivated>>> activated;
std::list<std::shared_ptr<Callback<NotificationCallbackSimple>>> failed;
std::list<std::shared_ptr<Callback<NotificationCallbackSimple>>> dismissed;
};
typedef struct
{
std::unordered_map<winrtEventToken*, Callback<NotificationCallbackActivated>> activated;
std::unordered_map<winrtEventToken*, Callback<NotificationCallbackSimple>> 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<winrtWindowsUINotificationsToastNotification*>(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<std::tuple<std::wstring, std::wstring>> 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<NotificationCallbackActivated>(callback, context, free));
priv->notification->activated.push_back(std::make_shared<Callback<NotificationCallbackActivated>>(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())
priv->notification->activated.remove_if([&](const auto& callback) {
if (winrt_event_token_get_value(token) == winrt_event_token_get_value(callback->token))
{
auto local_token = std::get<0>(*item);
if (winrt_event_token_operator_bool(local_token))
if (winrt_event_token_operator_bool(callback->token))
{
priv->notification->data.Activated(*winrt_event_token_get_internal(local_token));
priv->notification->data.Activated(*winrt_event_token_get_internal(callback->token));
}
priv->activated.erase(item);
g_object_unref(callback->token);
return true;
}
return false;
});
}

View file

@ -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<winrtWindowsUINotificationsToastNotifier*>(g_object_new (WINRT_TYPE_WINDOWS_UI_NOTIFICATIONS_TOAST_NOTIFICATION, NULL));
auto ret = static_cast<winrtWindowsUINotificationsToastNotifier*>(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;

View file

@ -1,17 +1,24 @@
#include <iostream>
#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;

View file

@ -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);

View file

@ -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 = "<toast launch=\"action=viewPhoto&amp;photoId=92187\">
<visual>
<binding template=\"ToastGeneric\">
<image placement=\"appLogoOverride\" hint-crop=\"circle\" src=\"https://unsplash.it/64?image=669\"/>
<text>Adam Wilson tagged you in a photo</text>
<text>On top of McClellan Butte - with Andrew Bares</text>
<image src=\"https://unsplash.it/360/202?image=883\"/>
</binding>
</visual>
<actions>
<action
content=\"Like\"
activationType=\"background\"
arguments=\"likePhoto&amp;photoId=92187\"/>
<action
content=\"Comment\"
arguments=\"action=commentPhoto&amp;photoId=92187\"/>
</actions>
</toast>";
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());

View file

@ -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 ()")]