From 4f2d9b4fa9b8539f2d45f2a2f86b0e71edd8095c Mon Sep 17 00:00:00 2001 From: Yaroslav Yashin Date: Tue, 27 May 2025 22:19:12 +0300 Subject: [PATCH] feat: add macOS notification handler and install event filter on main window --- client/amnezia_application.cpp | 21 ++++++++++++----- client/cmake/macos_ne.cmake | 10 ++++++--- client/ui/ne_notificationhandler.h | 36 ++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 client/ui/ne_notificationhandler.h diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 44afa713..dbd0d010 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -21,6 +21,8 @@ #include "platforms/ios/QRCodeReaderBase.h" #include "protocols/qml_register_protocols.h" +#include // for QQuickWindow +#include // for qobject_cast AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_CLASS(argc, argv) { @@ -63,12 +65,19 @@ void AmneziaApplication::init() const QUrl url(QStringLiteral("qrc:/ui/qml/main2.qml")); QObject::connect( - m_engine, &QQmlApplicationEngine::objectCreated, this, - [url](QObject *obj, const QUrl &objUrl) { - if (!obj && url == objUrl) - QCoreApplication::exit(-1); - }, - Qt::QueuedConnection); + m_engine, &QQmlApplicationEngine::objectCreated, this, + [this, url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) { + QCoreApplication::exit(-1); + return; + } + // install filter on main window + if (auto win = qobject_cast(obj)) { + win->installEventFilter(this); + win->show(); + } + }, + Qt::QueuedConnection); m_engine->rootContext()->setContextProperty("Debug", &Logger::Instance()); diff --git a/client/cmake/macos_ne.cmake b/client/cmake/macos_ne.cmake index 63bab94c..7ca76bcb 100644 --- a/client/cmake/macos_ne.cmake +++ b/client/cmake/macos_ne.cmake @@ -8,8 +8,9 @@ set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION enable_language(OBJC) enable_language(Swift) -find_package(Qt6 REQUIRED COMPONENTS ShaderTools) -set(LIBS ${LIBS} Qt6::ShaderTools) +find_package(Qt6 REQUIRED COMPONENTS ShaderTools Widgets) +# Link Qt Widgets for QWidget, QMenu, QAction etc. +set(LIBS ${LIBS} Qt6::ShaderTools Qt6::Widgets) find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices) find_library(FW_AVFOUNDATION AVFoundation) @@ -55,7 +56,10 @@ set_source_files_properties(${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Reso set(SOURCES ${SOURCES} ${ICON_FILE}) -target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS}) +target_include_directories(${PROJECT} PRIVATE + ${Qt6Gui_PRIVATE_INCLUDE_DIRS} + ${Qt6Widgets_PRIVATE_INCLUDE_DIRS} +) set_target_properties(${PROJECT} PROPERTIES diff --git a/client/ui/ne_notificationhandler.h b/client/ui/ne_notificationhandler.h new file mode 100644 index 00000000..e84d8068 --- /dev/null +++ b/client/ui/ne_notificationhandler.h @@ -0,0 +1,36 @@ +#ifndef NE_NOTIFICATION_HANDLER_H +#define NE_NOTIFICATION_HANDLER_H + +#include "notificationhandler.h" +#include +#include + +class MacOSStatusIcon; + +class NEStatusBarNotificationHandler : public NotificationHandler { + Q_OBJECT +public: + explicit NEStatusBarNotificationHandler(QObject* parent); + ~NEStatusBarNotificationHandler() override; + + void setConnectionState(Vpn::ConnectionState state) override; + void onTranslationsUpdated() override; + +protected: + void notify(Message type, const QString& title, + const QString& message, int timerMsec) override; + +private: + void buildMenu(); + + QMenu m_menu; + MacOSStatusIcon* m_statusIcon; + + QAction* m_actionShow; + QAction* m_actionConnect; + QAction* m_actionDisconnect; + QAction* m_actionVisitWebsite; + QAction* m_actionQuit; +}; + +#endif // NE_NOTIFICATION_HANDLER_H