fix compilation for MacOS/Linux

This commit is contained in:
gaelle.braud 2026-04-02 10:04:14 +02:00 committed by gaelle
parent aabf6f40a7
commit be6211778f
9 changed files with 109 additions and 116 deletions

View file

@ -124,6 +124,8 @@
#if defined(Q_OS_WIN)
#include "core/notifier/WindowsNotificationBackend.hpp"
#else
#include "core/notifier/SysTrayNotificationBackend.hpp"
#endif
DEFINE_ABSTRACT_OBJECT(App)

View file

@ -135,6 +135,9 @@ if(WIN32)
core/notifier/NotificationActivator.cpp
core/notifier/DesktopNotificationManagerCompat.cpp
core/notifier/WindowsNotificationBackend.cpp)
else()
list(APPEND _LINPHONEAPP_SOURCES
core/notifier/SysTrayNotificationBackend.cpp)
endif()
if(APPLE)
list(APPEND _LINPHONEAPP_SOURCES core/event-count-notifier/EventCountNotifierMacOs.m)

View file

@ -43,10 +43,6 @@ public:
};
protected:
virtual void sendNotification(const QString &title = QString(),
const QString &message = QString(),
const QList<ToastButton> &actions = {}) = 0;
virtual void sendNotification(NotificationType type, QVariantMap data) = 0;
static const QHash<int, Notification> Notifications;

View file

@ -0,0 +1,47 @@
#include "tool/Utils.hpp"
// #include "NotificationActivator.hpp"
#include "WindowsNotificationBackend.hpp"
#include "core/App.hpp"
#include "core/call/CallGui.hpp"
#include "core/chat/ChatGui.hpp"
#include "core/event-filter/LockEventFilter.hpp"
#include "tool/Utils.hpp"
#include <QDebug>
NotificationBackend::NotificationBackend(QObject *parent) : AbstractNotificationBackend(parent) {
// connect(App::getInstance(), &App::sessionLockedChanged, this, [this] {
// if (!App::getInstance()->getSessionLocked()) {
// qDebug() << "Session unlocked, flush pending notifications";
// flushPendingNotifications();
// }
// });
}
void NotificationBackend::flushPendingNotifications() {
for (const auto &notif : mPendingNotifications) {
sendNotification(notif.type, notif.data);
}
mPendingNotifications.clear();
}
void NotificationBackend::sendMessageNotification(QVariantMap data) {
}
void NotificationBackend::sendCallNotification(QVariantMap data) {
}
void NotificationBackend::sendNotification(NotificationType type, QVariantMap data) {
// if (App::getInstance()->getSessionLocked()) {
// mPendingNotifications.append({type, data});
// return;
// }
switch (type) {
case NotificationType::ReceivedCall:
sendCallNotification(data);
break;
case NotificationType::ReceivedMessage:
sendMessageNotification(data);
break;
}
}

View file

@ -0,0 +1,37 @@
#ifndef SYSTRAYNOTIFICATIONBACKEND_HPP
#define SYSTRAYNOTIFICATIONBACKEND_HPP
#include "AbstractNotificationBackend.hpp"
#include <QDebug>
#include <QLocalServer>
#include <QLocalSocket>
#include <QString>
class NotificationBackend : public AbstractNotificationBackend {
Q_OBJECT
public:
struct PendingNotification {
NotificationType type;
QVariantMap data;
};
NotificationBackend(QObject *parent = nullptr);
~NotificationBackend() = default;
void sendCallNotification(QVariantMap data);
void sendMessageNotification(QVariantMap data);
void sendNotification(NotificationType type, QVariantMap data) override;
void flushPendingNotifications();
signals:
void toastButtonTriggered(const QString &arg);
void sessionLockedChanged(bool locked);
private:
QList<PendingNotification> mPendingNotifications;
};
#endif // SYSTRAYNOTIFICATIONBACKEND_HPP

View file

@ -37,98 +37,6 @@ void NotificationBackend::flushPendingNotifications() {
mPendingNotifications.clear();
}
void NotificationBackend::sendNotification(const QString &title,
const QString &message,
const QList<ToastButton> &actions) {
IToastNotifier *notifier = nullptr;
HRESULT hr = DesktopNotificationManagerCompat::CreateToastNotifier(&notifier);
if (FAILED(hr) || !notifier) {
lWarning() << "CreateToastNotifier failed:" << Qt::hex << hr;
return;
}
std::wstring wTitle = title.toStdWString();
std::wstring wMessage = message.toStdWString();
std::wstring wActions;
if (!actions.isEmpty()) {
wActions += L"<actions>";
for (const auto &action : actions) {
std::wstring wLabel = action.label.toStdWString();
std::wstring wArg = action.argument.toStdWString();
wActions += L"<action content=\"" + wLabel + L"\" arguments=\"" + wArg + L"\"/>";
}
wActions += L"</actions>";
}
std::wstring xml = L"<toast>"
L" <visual>"
L" <binding template=\"ToastGeneric\">"
L" <text>" +
wTitle +
L"</text>"
L" <text>" +
wMessage +
L"</text>"
L" </binding>"
L" </visual>" +
wActions + L"</toast>";
ABI::Windows::Data::Xml::Dom::IXmlDocument *doc = nullptr;
hr = DesktopNotificationManagerCompat::CreateXmlDocumentFromString(xml.c_str(), &doc);
if (FAILED(hr) || !doc) {
lWarning() << "CreateXmlDocumentFromString failed:" << Qt::hex << hr;
notifier->Release();
return;
}
IToastNotification *toast = nullptr;
hr = DesktopNotificationManagerCompat::CreateToastNotification(doc, &toast);
if (FAILED(hr) || !toast) {
qWarning() << "CreateToastNotification failed:" << Qt::hex << hr;
doc->Release();
notifier->Release();
return;
}
EventRegistrationToken token;
toast->add_Activated(Microsoft::WRL::Callback<ITypedEventHandler<ToastNotification *, IInspectable *>>(
[this](IToastNotification *sender, IInspectable *args) -> HRESULT {
qInfo() << "Toast clicked!";
// Cast args en IToastActivatedEventArgs
Microsoft::WRL::ComPtr<IToastActivatedEventArgs> activatedArgs;
HRESULT hr = args->QueryInterface(IID_PPV_ARGS(&activatedArgs));
if (SUCCEEDED(hr)) {
HSTRING argumentsHString;
activatedArgs->get_Arguments(&argumentsHString);
// Convertir HSTRING en wstring
UINT32 length;
const wchar_t *rawStr = WindowsGetStringRawBuffer(argumentsHString, &length);
std::wstring arguments(rawStr, length);
qInfo() << "Toast activated with args:" << QString::fromStdWString(arguments);
emit toastActivated(QString::fromStdWString(arguments));
WindowsDeleteString(argumentsHString);
}
return S_OK;
})
.Get(),
&token);
hr = notifier->Show(toast);
lInfo() << "Show toast:" << Qt::hex << hr;
if (FAILED(hr)) {
qWarning() << "Toast Show failed:" << Qt::hex << hr;
}
toast->Release();
doc->Release();
notifier->Release();
}
void NotificationBackend::sendMessageNotification(QVariantMap data) {
IToastNotifier *notifier = nullptr;

View file

@ -18,9 +18,6 @@ public:
NotificationBackend(QObject *parent = nullptr);
~NotificationBackend() = default;
void sendNotification(const QString &title = QString(),
const QString &message = QString(),
const QList<ToastButton> &actions = {}) override;
void sendCallNotification(QVariantMap data);
void sendMessageNotification(QVariantMap data);

View file

@ -2,21 +2,21 @@
#ifdef _WIN32
#include <Windows.h>
#include <shlguid.h> // CLSID_ShellLink
#include <shobjidl.h> // IShellLinkW, IPropertyStore
FILE *gStream = NULL;
#include "core/notifier/DesktopNotificationManagerCompat.hpp"
#include "core/notifier/NotificationActivator.hpp"
#include <objbase.h> // StringFromCLSID, CoTaskMemFree
#include <propkey.h> // PKEY_AppUserModel_ID, PKEY_AppUserModel_ToastActivatorCLSID
#include <propvarutil.h> // InitPropVariantFromString, PropVariantClear
#include <shlguid.h> // CLSID_ShellLink
#include <shobjidl.h> // IShellLinkW, IPropertyStore
#endif
#include "core/App.hpp"
#include "core/logger/QtLogger.hpp"
#include "core/path/Paths.hpp"
#include "core/notifier/DesktopNotificationManagerCompat.hpp"
#include "core/notifier/NotificationActivator.hpp"
#include <QApplication>
#include <QLocale>
#include <QQmlApplicationEngine>
@ -59,6 +59,7 @@ int main(int argc, char *argv[]) {
// HRESULT hrCom = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
// qInfo() << "CoInitializeEx result:" << Qt::hex << hrCom;
#if defined _WIN32
qInfo() << "Thread ID:" << GetCurrentThreadId();
APTTYPE aptBefore;
APTTYPEQUALIFIER qualBefore;
@ -68,6 +69,18 @@ int main(int argc, char *argv[]) {
HRESULT hrCom = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
qInfo() << "CoInitializeEx STA result:" << Qt::hex << hrCom;
auto hr = DesktopNotificationManagerCompat::CreateStartMenuShortcut(mAumid, __uuidof(NotificationActivator));
if (FAILED(hr)) {
qWarning() << "CreateStartMenuShortcut failed:" << Qt::hex << hr;
}
// Register AUMID and COM server (for a packaged app, this is a no-operation)
hr = DesktopNotificationManagerCompat::RegisterAumidAndComServer(L"Linphone", __uuidof(NotificationActivator));
if (FAILED(hr)) {
qWarning() << "RegisterAumidAndComServer failed:" << Qt::hex << hr;
}
#endif
// Useful to share camera on Fullscreen (other context) or multiscreens
lDebug() << "[Main] Setting ShareOpenGLContexts";
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
@ -83,23 +96,14 @@ int main(int argc, char *argv[]) {
setlocale(LC_CTYPE, ".UTF8");
lDebug() << "[Main] Creating application";
auto hr = DesktopNotificationManagerCompat::CreateStartMenuShortcut(mAumid, __uuidof(NotificationActivator));
if (FAILED(hr)) {
qWarning() << "CreateStartMenuShortcut failed:" << Qt::hex << hr;
}
// Register AUMID and COM server (for a packaged app, this is a no-operation)
hr = DesktopNotificationManagerCompat::RegisterAumidAndComServer(L"Linphone", __uuidof(NotificationActivator));
if (FAILED(hr)) {
qWarning() << "RegisterAumidAndComServer failed:" << Qt::hex << hr;
}
auto app = QSharedPointer<App>::create(argc, argv);
#if defined _WIN32
hr = DesktopNotificationManagerCompat::RegisterActivator();
if (FAILED(hr)) {
qWarning() << "RegisterActivator failed:" << Qt::hex << hr;
}
#endif
#ifdef ACCESSBILITY_WORKAROUND
QAccessible::installUpdateHandler(DummyUpdateHandler);

View file

@ -154,7 +154,6 @@ public:
}
bool tryLock() {
if (!this) return false;
mLocker.lock();
auto coreLocked = mCore.lock();
auto modelLocked = mModel.lock();