summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/Toaster/src/main.cpp13
-rw-r--r--plugins/Toaster/src/services.cpp42
-rw-r--r--plugins/Toaster/src/stdafx.h13
-rw-r--r--plugins/Toaster/src/toast_event_handler.cpp25
-rw-r--r--plugins/Toaster/src/toast_event_handler.h9
-rw-r--r--plugins/Toaster/src/toast_notification.cpp14
-rw-r--r--plugins/Toaster/src/toast_notification.h4
7 files changed, 94 insertions, 26 deletions
diff --git a/plugins/Toaster/src/main.cpp b/plugins/Toaster/src/main.cpp
index 6ce8fd69af..4f3515ffdf 100644
--- a/plugins/Toaster/src/main.cpp
+++ b/plugins/Toaster/src/main.cpp
@@ -39,7 +39,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD)
extern "C" int __declspec(dllexport) Load(void)
{
mir_getLP(&pluginInfo);
-
+ HookEvent(ME_SYSTEM_SHUTDOWN, &OnPreShutdown);
InitServices();
return 0;
@@ -49,3 +49,14 @@ extern "C" int __declspec(dllexport) Unload(void)
{
return 0;
}
+
+int OnPreShutdown(WPARAM, LPARAM)
+{
+ mir_cslock lck(csNotifications);
+ for (int i = 0; i < lstNotifications.getCount(); i++)
+ lstNotifications[0].Hide();
+
+ lstNotifications.destroy();
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/Toaster/src/services.cpp b/plugins/Toaster/src/services.cpp
index 79e8fba2b0..1168e8cc95 100644
--- a/plugins/Toaster/src/services.cpp
+++ b/plugins/Toaster/src/services.cpp
@@ -1,12 +1,16 @@
#include "stdafx.h"
+mir_cs csNotifications;
+OBJLIST<ToastNotification> lstNotifications(1);
+
__forceinline bool isChatRoom(MCONTACT hContact)
-{ return (bool)db_get_b(hContact, GetContactProto(hContact), "ChatRoom", 0);
+{ return (db_get_b(hContact, GetContactProto(hContact), "ChatRoom", 0) == 1);
}
static void __cdecl OnToastNotificationClicked(void* arg)
{
- MCONTACT hContact = (MCONTACT)arg;
+ callbackArg *cb = (callbackArg*)arg;
+ MCONTACT hContact = cb->hContact;
if (hContact)
{
if (!isChatRoom(hContact))
@@ -16,13 +20,13 @@ static void __cdecl OnToastNotificationClicked(void* arg)
else
{
const char *szProto = GetContactProto(hContact);
- ptrT szChatRoom(db_get_tsa(hContact, szProto, "ChatRoomID"));
- GCDEST gcd = { szProto, szChatRoom, GC_EVENT_CONTROL };
+ ptrT tszChatRoom(db_get_tsa(hContact, szProto, "ChatRoomID"));
+ GCDEST gcd = { szProto, tszChatRoom, GC_EVENT_CONTROL };
GCEVENT gce = { sizeof(gce), &gcd };
- gce.time = time(NULL);
- CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, reinterpret_cast<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, (LPARAM)&gce);
}
}
+ lstNotifications.remove(cb->notification);
}
static void ShowToastNotification(TCHAR* text, TCHAR* title, MCONTACT hContact)
@@ -31,25 +35,25 @@ static void ShowToastNotification(TCHAR* text, TCHAR* title, MCONTACT hContact)
return;
ptrT imagePath;
- ToastEventHandler *eventHandler;
+ callbackArg *arg = (callbackArg*)mir_calloc(sizeof(callbackArg));
if (hContact)
{
- eventHandler = new ToastEventHandler(OnToastNotificationClicked, (void*)hContact);
-
+ arg->hContact = hContact;
const char* szProto = GetContactProto(hContact);
- PROTO_AVATAR_INFORMATION pai = { 0 };
- pai.hContact = hContact;
+
if (ProtoServiceExists(szProto, PS_GETAVATARINFO))
{
+ PROTO_AVATAR_INFORMATION pai = { 0 };
+ pai.hContact = hContact;
CallProtoService(szProto, PS_GETAVATARINFO, (WPARAM)0, (LPARAM)&pai);
imagePath = mir_tstrdup(pai.filename);
}
}
- else
- eventHandler = new ToastEventHandler(nullptr);
- ToastNotification notification(text, title, imagePath);
- notification.Show(eventHandler);
+ ToastNotification* notification = new ToastNotification (text, title, imagePath);
+ arg->notification = notification;
+ notification->Show(new ToastEventHandler(OnToastNotificationClicked, arg));
+ lstNotifications.insert(notification);
}
static INT_PTR CreatePopup(WPARAM wParam, LPARAM)
@@ -107,6 +111,14 @@ static INT_PTR PopupQuery(WPARAM wParam, LPARAM)
{
bool enabled = db_get_b(0, "Popup", "ModuleIsEnabled", 1) != 0;
if (enabled) db_set_b(0, "Popup", "ModuleIsEnabled", 0);
+
+ while (lstNotifications.getCount())
+ {
+ mir_cslock lck(csNotifications);
+ lstNotifications[0].Hide();
+ lstNotifications.remove(0);
+ }
+
return enabled;
}
break;
diff --git a/plugins/Toaster/src/stdafx.h b/plugins/Toaster/src/stdafx.h
index a113024828..8df66f4598 100644
--- a/plugins/Toaster/src/stdafx.h
+++ b/plugins/Toaster/src/stdafx.h
@@ -13,6 +13,8 @@
#include <windows.ui.notifications.h>
#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_system_cpp.h>
#include <m_core.h>
#include <m_utils.h>
#include <m_langpack.h>
@@ -33,10 +35,19 @@ const wchar_t AppUserModelID[] = _T("MirandaNG");
#include "toast_event_handler.h"
#include "toast_notification.h"
+extern mir_cs csNotifications;
+extern OBJLIST<ToastNotification> lstNotifications;
+
+struct callbackArg
+{
+ MCONTACT hContact;
+ ToastNotification* notification;
+};
+
#define MODULE "Toaster"
extern HINSTANCE g_hInstance;
void InitServices();
-
+int OnPreShutdown(WPARAM, LPARAM);
#endif //_COMMON_H_
diff --git a/plugins/Toaster/src/toast_event_handler.cpp b/plugins/Toaster/src/toast_event_handler.cpp
index e2ed29e165..c7f43ad115 100644
--- a/plugins/Toaster/src/toast_event_handler.cpp
+++ b/plugins/Toaster/src/toast_event_handler.cpp
@@ -1,5 +1,7 @@
#include "stdafx.h"
+using namespace ABI::Windows::UI::Notifications;
+
ToastEventHandler::ToastEventHandler() : _ref(1), _callback(nullptr), _arg(nullptr)
{
}
@@ -30,10 +32,13 @@ IFACEMETHODIMP ToastEventHandler::QueryInterface(_In_ REFIID riid, _COM_Outptr_
*ppv = static_cast<IUnknown*>(static_cast<DesktopToastActivatedEventHandler*>(this));
else if (IsEqualIID(riid, __uuidof(DesktopToastActivatedEventHandler)))
*ppv = static_cast<DesktopToastActivatedEventHandler*>(this);
+ else if (IsEqualIID(riid, __uuidof(DesktopToastDismissedEventHandler)))
+ *ppv = static_cast<DesktopToastDismissedEventHandler*>(this);
+ else if (IsEqualIID(riid, __uuidof(DesktopToastFailedEventHandler)))
+ *ppv = static_cast<DesktopToastFailedEventHandler*>(this);
else *ppv = nullptr;
- if (*ppv)
- {
+ if (*ppv) {
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
@@ -41,10 +46,24 @@ IFACEMETHODIMP ToastEventHandler::QueryInterface(_In_ REFIID riid, _COM_Outptr_
return E_NOINTERFACE;
}
-IFACEMETHODIMP ToastEventHandler::Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* /* sender */, _In_::IInspectable* /* args */)
+IFACEMETHODIMP ToastEventHandler::Invoke(_In_ IToastNotification* /* sender */, _In_ IInspectable* /* args */)
{
if (_callback != nullptr)
_callback(_arg);
return S_OK;
}
+
+IFACEMETHODIMP ToastEventHandler::Invoke(_In_ IToastNotification* /* sender */, _In_ IToastDismissedEventArgs* /* e */)
+{
+ callbackArg *cb = (callbackArg*)_arg;
+ lstNotifications.remove(cb->notification);
+ return S_OK;
+}
+
+IFACEMETHODIMP ToastEventHandler::Invoke(_In_ IToastNotification* /* sender */, _In_ IToastFailedEventArgs* /* e */)
+{
+ callbackArg *cb = (callbackArg*)_arg;
+ lstNotifications.remove(cb->notification);
+ return S_OK;
+} \ No newline at end of file
diff --git a/plugins/Toaster/src/toast_event_handler.h b/plugins/Toaster/src/toast_event_handler.h
index 10d2f1422f..8cf82b3e21 100644
--- a/plugins/Toaster/src/toast_event_handler.h
+++ b/plugins/Toaster/src/toast_event_handler.h
@@ -1,9 +1,12 @@
#ifndef _TOAST_EVENT_HANDLER_H_
#define _TOAST_EVENT_HANDLER_H_
-typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification*, ::IInspectable*> DesktopToastActivatedEventHandler;
+typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification *, ::IInspectable *> DesktopToastActivatedEventHandler;
+typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification *, ABI::Windows::UI::Notifications::ToastDismissedEventArgs *> DesktopToastDismissedEventHandler;
+typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification *, ABI::Windows::UI::Notifications::ToastFailedEventArgs *> DesktopToastFailedEventHandler;
-class ToastEventHandler : public Microsoft::WRL::Implements<ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification*, ::IInspectable*>>
+
+class ToastEventHandler : public Microsoft::WRL::Implements<DesktopToastActivatedEventHandler, DesktopToastDismissedEventHandler, DesktopToastFailedEventHandler>
{
public:
ToastEventHandler::ToastEventHandler();
@@ -16,6 +19,8 @@ public:
IFACEMETHODIMP QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppv);
IFACEMETHODIMP Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* sender, _In_ IInspectable* args);
+ IFACEMETHODIMP Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* /* sender */, _In_ ABI::Windows::UI::Notifications::IToastDismissedEventArgs* e);
+ IFACEMETHODIMP Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* /* sender */, _In_ ABI::Windows::UI::Notifications::IToastFailedEventArgs* /* e */);
private:
ULONG _ref;
diff --git a/plugins/Toaster/src/toast_notification.cpp b/plugins/Toaster/src/toast_notification.cpp
index 9e3ad1b915..7d11f9318e 100644
--- a/plugins/Toaster/src/toast_notification.cpp
+++ b/plugins/Toaster/src/toast_notification.cpp
@@ -215,21 +215,27 @@ HRESULT ToastNotification::Show(_In_ ToastEventHandler* handler)
if (FAILED(hr))
RaiseException(static_cast<DWORD>(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr);
- Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotifier> notifier;
hr = notificationManager->CreateToastNotifierWithId(StringReferenceWrapper(::AppUserModelID).Get(), &notifier);
if (FAILED(hr))
return hr;
-
- Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotification> notification;
hr = Create(&notification);
if (FAILED(hr))
return hr;
- EventRegistrationToken activatedToken;
+ EventRegistrationToken activatedToken, dismissedToken, failedToken;
Microsoft::WRL::ComPtr<ToastEventHandler> eventHandler(handler);
hr = notification->add_Activated(eventHandler.Get(), &activatedToken);
if (FAILED(hr))
return hr;
+ notification->add_Activated(eventHandler.Get(), &activatedToken);
+ notification->add_Dismissed(eventHandler.Get(), &dismissedToken);
+ notification->add_Failed(eventHandler.Get(), &failedToken);
+
return notifier->Show(notification.Get());
+}
+
+HRESULT ToastNotification::Hide()
+{
+ return notifier->Hide(notification.Get());
} \ No newline at end of file
diff --git a/plugins/Toaster/src/toast_notification.h b/plugins/Toaster/src/toast_notification.h
index 727966ac8f..0e4131b945 100644
--- a/plugins/Toaster/src/toast_notification.h
+++ b/plugins/Toaster/src/toast_notification.h
@@ -8,6 +8,9 @@ private:
wchar_t* _caption;
wchar_t* _imagePath;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotifier> notifier;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotification> notification;
+
HRESULT GetNodeByTag(_In_ HSTRING tagName, _Outptr_ ABI::Windows::Data::Xml::Dom::IXmlNode **node, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
HRESULT AddNode(_In_ HSTRING name, _Outptr_ ABI::Windows::Data::Xml::Dom::IXmlNode **node, _In_ ABI::Windows::Data::Xml::Dom::IXmlNode *rootNode, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
HRESULT SetNodeValueString(_In_ HSTRING inputString, _In_ ABI::Windows::Data::Xml::Dom::IXmlNode* node, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
@@ -26,6 +29,7 @@ public:
HRESULT Show();
HRESULT Show(_In_ ToastEventHandler* handler);
+ HRESULT Hide();
};
#endif //_TOAST_NOTIFICATION_H_ \ No newline at end of file