fix(@desktop/general): (macos) clicking push notification does expand the app but does not open correct channel/chat

MacOS notifications handled in a native way.
This change is required as part of the fix for ticket 2996.

Fixes: #2996
This commit is contained in:
Sale Djenic 2021-08-23 13:16:34 +02:00 committed by Michał
parent 8599442510
commit db826f58cf
6 changed files with 181 additions and 2 deletions

View File

@ -1002,6 +1002,12 @@ DOS_API DosStatusEventObject* dos_statusevent_create_showAppEvent(DosQQmlApplica
DOS_API DosStatusEventObject* dos_statusevent_create_osThemeEvent(DosQQmlApplicationEngine* vptr);
DOS_API void dos_statusevent_delete(DosStatusEventObject* vptr);
/// Status notification object
DOS_API DosStatusOSNotificationObject* dos_statusosnotification_create();
DOS_API void dos_statusosnotification_show_notification(DosStatusOSNotificationObject* vptr,
const char* title, const char* message, const char* identifier);
DOS_API void dos_statusosnotification_delete(DosStatusOSNotificationObject* vptr);
#ifdef __cplusplus
}
#endif

View File

@ -101,6 +101,9 @@ typedef void DosSingleInstance;
/// A pointer to a status event object which is actualy a QObject
typedef void DosStatusEventObject;
/// A pointer to a status os notification object which is actualy a QObject
typedef DosQObject DosStatusOSNotificationObject;
/// A pixmap callback to be supplied to an image provider
/// \param id Image source id
/// \param width pointer to the width of the image

View File

@ -0,0 +1,39 @@
#ifndef STATUS_OS_NOTIFICATION_H
#define STATUS_OS_NOTIFICATION_H
#include <QObject>
#include <QHash>
#ifdef Q_OS_WIN
#elif defined Q_OS_MACOS
class NotificationHelper;
#endif
class StatusOSNotification : public QObject
{
Q_OBJECT
public:
StatusOSNotification(QObject *parent = nullptr);
~StatusOSNotification();
void showNotification(const QString& title, const QString& message,
const QString& identifier);
signals:
void notificationClicked(QString identifier);
#ifdef Q_OS_WIN
#elif defined Q_OS_MACOS
private:
void initNotificationMacOs();
void showNotificationMacOs(QString title, QString message, QString identifier);
private:
NotificationHelper *m_notificationHelper;
#endif
};
#endif

View File

@ -64,6 +64,7 @@
#include "DOtherSide/StatusEvents/StatusDockShowAppEvent.h"
#include "DOtherSide/StatusEvents/StatusOSThemeEvent.h"
#include "DOtherSide/StatusNotification/StatusOSNotification.h"
namespace {
@ -143,7 +144,7 @@ void dos_qapplication_initialize_opengl()
void dos_qguiapplication_create()
{
static int argc = 1;
static char *argv[] = {"Status"};
static char *argv[] = {(char*)"Status"};
register_meta_types();
@ -209,7 +210,7 @@ void dos_qguiapplication_installEventFilter(::DosStatusEventObject* vptr)
void dos_qapplication_create()
{
static int argc = 1;
static char *argv[] = {"Status"};
static char *argv[] = {(char*)"Status"};
register_meta_types();
@ -1369,3 +1370,23 @@ void dos_statusevent_delete(DosStatusEventObject* vptr)
auto qobject = static_cast<QObject*>(vptr);
qobject->deleteLater();
}
::DosStatusOSNotificationObject* dos_statusosnotification_create()
{
return new StatusOSNotification();
}
void dos_statusosnotification_show_notification(DosStatusOSNotificationObject* vptr,
const char* title, const char* message, const char* identifier)
{
auto notificationObj = static_cast<StatusOSNotification*>(vptr);
if(notificationObj)
notificationObj->showNotification(title, message, identifier);
}
void dos_statusosnotification_delete(DosStatusOSNotificationObject* vptr)
{
auto qobject = static_cast<QObject*>(vptr);
if(qobject)
qobject->deleteLater();
}

View File

@ -0,0 +1,32 @@
#include "DOtherSide/StatusNotification/StatusOSNotification.h"
StatusOSNotification::StatusOSNotification(QObject *parent)
: QObject(parent)
{
#ifdef Q_OS_WIN
#elif defined Q_OS_MACOS
m_notificationHelper = nullptr;
initNotificationMacOs();
#endif
}
StatusOSNotification::~StatusOSNotification()
{
#ifdef Q_OS_MACOS
if(m_notificationHelper)
{
delete m_notificationHelper;
}
#endif
}
void StatusOSNotification::showNotification(const QString& title,
const QString& message, const QString& identifier)
{
#ifdef Q_OS_WIN
#elif defined Q_OS_MACOS
showNotificationMacOs(title, message, identifier);
#endif
}

View File

@ -0,0 +1,78 @@
#include "DOtherSide/StatusNotification/StatusOSNotification.h"
#ifdef Q_OS_MACOS
#import <AppKit/AppKit.h>
@interface NotificationDelegate : NSObject <NSUserNotificationCenterDelegate>
- (instancetype)initStatusOSNotification:(StatusOSNotification*) instance;
@end
class NotificationHelper
{
public:
NotificationHelper(StatusOSNotification* instance) {
delegate = [[NotificationDelegate alloc] initStatusOSNotification:instance];
NSUserNotificationCenter.defaultUserNotificationCenter.delegate = delegate;
}
~NotificationHelper() {
NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
if (center.delegate == delegate)
center.delegate = nil;
[delegate release];
}
NotificationDelegate* delegate;
};
void StatusOSNotification::initNotificationMacOs()
{
if (!m_notificationHelper)
{
m_notificationHelper = new NotificationHelper(this);
}
}
void StatusOSNotification::showNotificationMacOs(QString title, QString message,
QString identifier)
{
if (!m_notificationHelper)
return;
NSUserNotification* notification = [[NSUserNotification alloc] init];
notification.title = title.toNSString();
notification.informativeText = message.toNSString();
notification.soundName = NSUserNotificationDefaultSoundName;
notification.hasActionButton = false;
notification.identifier = identifier.toNSString();
NSUserNotificationCenter* center = NSUserNotificationCenter.defaultUserNotificationCenter;
center.delegate = m_notificationHelper->delegate;
[center deliverNotification:notification];
[notification release];
}
@implementation NotificationDelegate {
StatusOSNotification* instance;
}
- (instancetype)initStatusOSNotification:(StatusOSNotification*)ins
{
self = [super init];
if (self) {
instance = ins;
}
return self;
}
- (void) userNotificationCenter:(NSUserNotificationCenter*)center didActivateNotification:(NSUserNotification*)notification
{
const char* identifier = [notification.identifier UTF8String];
[center removeDeliveredNotification:notification];
instance->notificationClicked(identifier);
}
@end
#endif