mirror of
https://github.com/status-im/dotherside.git
synced 2025-02-11 20:16:47 +00:00
fix(@desktop/general): (windows) clicking push notification does expand the app but does not open correct channel/chat
Windows notifications added in a native way. This change is required as part of the fix for ticket 2996. Fixes: #2996
This commit is contained in:
parent
cafe9c6742
commit
5ff11d3eb3
@ -5,7 +5,7 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
#include "windows.h"
|
||||||
#elif defined Q_OS_MACOS
|
#elif defined Q_OS_MACOS
|
||||||
class NotificationHelper;
|
class NotificationHelper;
|
||||||
#endif
|
#endif
|
||||||
@ -25,6 +25,15 @@ signals:
|
|||||||
void notificationClicked(QString identifier);
|
void notificationClicked(QString identifier);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
public:
|
||||||
|
QHash<uint, QString> m_identifiers;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool initNotificationWin();
|
||||||
|
void stringToLimitedWCharArray(QString in, wchar_t* target, int maxLength);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HWND m_hwnd;
|
||||||
|
|
||||||
#elif defined Q_OS_MACOS
|
#elif defined Q_OS_MACOS
|
||||||
private:
|
private:
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
#include "DOtherSide/StatusNotification/StatusOSNotification.h"
|
#include "DOtherSide/StatusNotification/StatusOSNotification.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <winuser.h>
|
||||||
|
#include <comdef.h>
|
||||||
|
|
||||||
|
static const UINT NOTIFYICONID = 0;
|
||||||
|
|
||||||
|
static std::pair<HWND, StatusOSNotification *> HWND_INSTANCE_PAIR;
|
||||||
|
#endif
|
||||||
|
|
||||||
StatusOSNotification::StatusOSNotification(QObject *parent)
|
StatusOSNotification::StatusOSNotification(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
m_hwnd = nullptr;
|
||||||
|
initNotificationWin();
|
||||||
#elif defined Q_OS_MACOS
|
#elif defined Q_OS_MACOS
|
||||||
m_notificationHelper = nullptr;
|
m_notificationHelper = nullptr;
|
||||||
initNotificationMacOs();
|
initNotificationMacOs();
|
||||||
@ -21,10 +34,123 @@ StatusOSNotification::~StatusOSNotification()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
LRESULT CALLBACK StatusWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
const int msgInfo = LOWORD(lParam);
|
||||||
|
|
||||||
|
if (hwnd == HWND_INSTANCE_PAIR.first
|
||||||
|
&& HWND_INSTANCE_PAIR.second
|
||||||
|
&& HWND_INSTANCE_PAIR.second->m_identifiers.contains(uMsg)
|
||||||
|
&& msgInfo == NIN_BALLOONUSERCLICK)
|
||||||
|
{
|
||||||
|
HWND_INSTANCE_PAIR.second->notificationClicked(
|
||||||
|
HWND_INSTANCE_PAIR.second->m_identifiers[uMsg]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusOSNotification::stringToLimitedWCharArray(QString in, wchar_t* target,
|
||||||
|
int maxLength)
|
||||||
|
{
|
||||||
|
const int length = qMin(maxLength - 1, in.size());
|
||||||
|
if (length < in.size())
|
||||||
|
in.truncate(length);
|
||||||
|
in.toWCharArray(target);
|
||||||
|
target[length] = wchar_t(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StatusOSNotification::initNotificationWin()
|
||||||
|
{
|
||||||
|
// m_hwnd should be init only once, but that would be a case if we create system
|
||||||
|
// tray window from here. But since we already have system tray added in the
|
||||||
|
// app we're just refering to that already added window and listen for events
|
||||||
|
// on it. HWND of that window may be changed during the runtime and we don't
|
||||||
|
// have an option to be notified about that, that's why we're searching for
|
||||||
|
// appropriate HWND each time we need it, and that's why the following two
|
||||||
|
// lines are commented out.
|
||||||
|
//
|
||||||
|
// if (m_hwnd)
|
||||||
|
// return true;
|
||||||
|
|
||||||
|
const QString cName = "QTrayIconMessageWindowClass";
|
||||||
|
LPCSTR className = cName.toStdString().c_str();
|
||||||
|
const QString wName = "QTrayIconMessageWindow";
|
||||||
|
LPCSTR windowName = wName.toStdString().c_str();
|
||||||
|
|
||||||
|
const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));
|
||||||
|
|
||||||
|
WNDCLASSEX wc;
|
||||||
|
wc.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
wc.lpfnWndProc = StatusWndProc;
|
||||||
|
wc.cbClsExtra = 0;
|
||||||
|
wc.cbWndExtra = 0;
|
||||||
|
wc.hInstance = appInstance;
|
||||||
|
wc.hCursor = nullptr;
|
||||||
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
|
||||||
|
wc.hIcon = nullptr;
|
||||||
|
wc.hIconSm = nullptr;
|
||||||
|
wc.lpszMenuName = nullptr;
|
||||||
|
wc.lpszClassName = className;
|
||||||
|
|
||||||
|
ATOM atom = RegisterClassEx(&wc);
|
||||||
|
if (!atom)
|
||||||
|
printf("StatusOsNotification registering window class failed.\n");
|
||||||
|
|
||||||
|
m_hwnd = FindWindowExA(0, 0, className, windowName);
|
||||||
|
if(m_hwnd)
|
||||||
|
{
|
||||||
|
HWND_INSTANCE_PAIR = std::make_pair(m_hwnd, this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void StatusOSNotification::showNotification(const QString& title,
|
void StatusOSNotification::showNotification(const QString& title,
|
||||||
const QString& message, const QString& identifier)
|
const QString& message, const QString& identifier)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
if (!initNotificationWin())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NOTIFYICONDATA tnd;
|
||||||
|
memset(&tnd, 0, sizeof(NOTIFYICONDATA));
|
||||||
|
tnd.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
|
tnd.uVersion = NOTIFYICON_VERSION_4;
|
||||||
|
|
||||||
|
QString t = title;
|
||||||
|
wchar_t wcTitle[64];
|
||||||
|
stringToLimitedWCharArray(t, wcTitle, 64);
|
||||||
|
_bstr_t bT(wcTitle);
|
||||||
|
const char* cTitle = bT;
|
||||||
|
|
||||||
|
QString m = message;
|
||||||
|
wchar_t wcMessage[256];
|
||||||
|
stringToLimitedWCharArray(m, wcMessage, 256);
|
||||||
|
_bstr_t bM(wcMessage);
|
||||||
|
const char* cMessage = bM;
|
||||||
|
|
||||||
|
strncpy_s(tnd.szInfoTitle, sizeof(tnd.szInfoTitle), cTitle, strlen(cTitle));
|
||||||
|
strncpy_s(tnd.szInfo, sizeof(tnd.szInfo), cMessage, strlen(cMessage));
|
||||||
|
|
||||||
|
tnd.uID = NOTIFYICONID;
|
||||||
|
tnd.hWnd = m_hwnd;
|
||||||
|
tnd.dwInfoFlags = NIIF_INFO;
|
||||||
|
tnd.uTimeout = UINT(10000);
|
||||||
|
tnd.uFlags = NIF_MESSAGE | NIF_INFO | NIF_SHOWTIP;
|
||||||
|
|
||||||
|
uint id = WM_APP + 2 + m_identifiers.size();
|
||||||
|
m_identifiers.insert(id, identifier);
|
||||||
|
tnd.uCallbackMessage = id;
|
||||||
|
|
||||||
|
Shell_NotifyIcon(NIM_MODIFY, &tnd);
|
||||||
|
|
||||||
#elif defined Q_OS_MACOS
|
#elif defined Q_OS_MACOS
|
||||||
showNotificationMacOs(title, message, identifier);
|
showNotificationMacOs(title, message, identifier);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user