2021-11-26 17:43:02 +03:00
/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
# include <QDebug>
# include "systemtray_notificationhandler.h"
2023-07-15 14:19:48 -07:00
# ifdef Q_OS_MAC
2021-11-26 17:43:02 +03:00
# include "platforms / macos / macosutils.h"
# endif
2021-11-28 17:28:25 +03:00
# include <QApplication>
# include <QDesktopServices>
2021-11-26 17:43:02 +03:00
# include <QIcon>
# include <QWindow>
2023-05-16 07:34:06 +07:00
# include "version.h"
2021-11-26 17:43:02 +03:00
2021-11-28 17:28:25 +03:00
SystemTrayNotificationHandler : : SystemTrayNotificationHandler ( QObject * parent ) :
NotificationHandler ( parent ) ,
m_systemTrayIcon ( parent )
2021-11-26 17:43:02 +03:00
2021-11-28 17:28:25 +03:00
{
m_systemTrayIcon . show ( ) ;
connect ( & m_systemTrayIcon , & QSystemTrayIcon : : activated , this , & SystemTrayNotificationHandler : : onTrayActivated ) ;
2021-11-26 17:43:02 +03:00
2023-10-06 13:43:32 +08:00
m_trayActionShow = m_menu . addAction ( QIcon ( " :/images/tray/application.png " ) , tr ( " Show " ) + " " + APPLICATION_NAME , this , [ this ] ( ) {
2021-11-28 17:28:25 +03:00
emit raiseRequested ( ) ;
} ) ;
m_menu . addSeparator ( ) ;
m_trayActionConnect = m_menu . addAction ( tr ( " Connect " ) , this , [ this ] ( ) { emit connectRequested ( ) ; } ) ;
m_trayActionDisconnect = m_menu . addAction ( tr ( " Disconnect " ) , this , [ this ] ( ) { emit disconnectRequested ( ) ; } ) ;
2021-11-26 17:43:02 +03:00
2021-11-28 17:28:25 +03:00
m_menu . addSeparator ( ) ;
2021-11-26 17:43:02 +03:00
2023-10-06 13:43:32 +08:00
m_trayActionVisitWebSite = m_menu . addAction ( QIcon ( " :/images/tray/link.png " ) , tr ( " Visit Website " ) , [ & ] ( ) {
2025-08-01 07:50:31 +04:00
QDesktopServices : : openUrl ( QUrl ( websiteUrl ) ) ;
2021-11-28 17:28:25 +03:00
} ) ;
2021-11-26 17:43:02 +03:00
2025-08-10 06:12:19 +03:00
// Quit action: disconnect VPN first on macOS NE, else quit directly
m_trayActionQuit = m_menu . addAction ( QIcon ( " :/images/tray/cancel.png " ) ,
tr ( " Quit " ) + " " + APPLICATION_NAME ,
this ,
[ & ] ( ) { qApp - > quit ( ) ; } ) ;
2021-11-26 17:43:02 +03:00
2021-11-28 17:28:25 +03:00
m_systemTrayIcon . setContextMenu ( & m_menu ) ;
2023-05-14 21:11:19 +08:00
setTrayState ( Vpn : : ConnectionState : : Disconnected ) ;
2021-11-26 17:43:02 +03:00
}
SystemTrayNotificationHandler : : ~ SystemTrayNotificationHandler ( ) {
}
2023-05-14 21:11:19 +08:00
void SystemTrayNotificationHandler : : setConnectionState ( Vpn : : ConnectionState state )
2021-11-28 17:28:25 +03:00
{
setTrayState ( state ) ;
NotificationHandler : : setConnectionState ( state ) ;
}
2023-10-06 13:43:32 +08:00
void SystemTrayNotificationHandler : : onTranslationsUpdated ( )
{
m_trayActionShow - > setText ( tr ( " Show " ) + " " + APPLICATION_NAME ) ;
m_trayActionConnect - > setText ( tr ( " Connect " ) ) ;
m_trayActionDisconnect - > setText ( tr ( " Disconnect " ) ) ;
m_trayActionVisitWebSite - > setText ( tr ( " Visit Website " ) ) ;
m_trayActionQuit - > setText ( tr ( " Quit " ) + " " + APPLICATION_NAME ) ;
}
2025-08-01 07:50:31 +04:00
void SystemTrayNotificationHandler : : updateWebsiteUrl ( const QString & newWebsiteUrl ) {
qDebug ( ) < < " Updated website URL: " < < newWebsiteUrl ;
websiteUrl = newWebsiteUrl ;
}
2021-11-28 17:28:25 +03:00
void SystemTrayNotificationHandler : : setTrayIcon ( const QString & iconPath )
{
QIcon trayIconMask ( QPixmap ( iconPath ) . scaled ( 128 , 128 ) ) ;
2024-04-03 22:31:48 +03:00
# ifndef Q_OS_MAC
2021-11-28 17:28:25 +03:00
trayIconMask . setIsMask ( true ) ;
2024-04-03 22:31:48 +03:00
# endif
2021-11-28 17:28:25 +03:00
m_systemTrayIcon . setIcon ( trayIconMask ) ;
}
void SystemTrayNotificationHandler : : onTrayActivated ( QSystemTrayIcon : : ActivationReason reason )
{
# ifndef Q_OS_MAC
if ( reason = = QSystemTrayIcon : : DoubleClick | | reason = = QSystemTrayIcon : : Trigger ) {
emit raiseRequested ( ) ;
}
# endif
}
2023-05-14 21:11:19 +08:00
void SystemTrayNotificationHandler : : setTrayState ( Vpn : : ConnectionState state )
2021-11-28 17:28:25 +03:00
{
QString resourcesPath = " :/images/tray/%1 " ;
switch ( state ) {
2023-05-14 21:11:19 +08:00
case Vpn : : ConnectionState : : Disconnected :
2021-11-28 17:28:25 +03:00
setTrayIcon ( QString ( resourcesPath ) . arg ( DisconnectedTrayIconName ) ) ;
m_trayActionConnect - > setEnabled ( true ) ;
m_trayActionDisconnect - > setEnabled ( false ) ;
break ;
2023-05-14 21:11:19 +08:00
case Vpn : : ConnectionState : : Preparing :
2021-11-28 17:28:25 +03:00
setTrayIcon ( QString ( resourcesPath ) . arg ( DisconnectedTrayIconName ) ) ;
m_trayActionConnect - > setEnabled ( false ) ;
m_trayActionDisconnect - > setEnabled ( true ) ;
break ;
2023-05-14 21:11:19 +08:00
case Vpn : : ConnectionState : : Connecting :
2021-11-28 17:28:25 +03:00
setTrayIcon ( QString ( resourcesPath ) . arg ( DisconnectedTrayIconName ) ) ;
m_trayActionConnect - > setEnabled ( false ) ;
m_trayActionDisconnect - > setEnabled ( true ) ;
break ;
2023-05-14 21:11:19 +08:00
case Vpn : : ConnectionState : : Connected :
2021-11-28 17:28:25 +03:00
setTrayIcon ( QString ( resourcesPath ) . arg ( ConnectedTrayIconName ) ) ;
m_trayActionConnect - > setEnabled ( false ) ;
m_trayActionDisconnect - > setEnabled ( true ) ;
break ;
2023-05-14 21:11:19 +08:00
case Vpn : : ConnectionState : : Disconnecting :
2021-11-28 17:28:25 +03:00
setTrayIcon ( QString ( resourcesPath ) . arg ( DisconnectedTrayIconName ) ) ;
m_trayActionConnect - > setEnabled ( false ) ;
m_trayActionDisconnect - > setEnabled ( true ) ;
break ;
2023-05-14 21:11:19 +08:00
case Vpn : : ConnectionState : : Reconnecting :
2021-11-28 17:28:25 +03:00
setTrayIcon ( QString ( resourcesPath ) . arg ( DisconnectedTrayIconName ) ) ;
m_trayActionConnect - > setEnabled ( false ) ;
m_trayActionDisconnect - > setEnabled ( true ) ;
break ;
2023-05-14 21:11:19 +08:00
case Vpn : : ConnectionState : : Error :
2021-11-28 17:28:25 +03:00
setTrayIcon ( QString ( resourcesPath ) . arg ( ErrorTrayIconName ) ) ;
m_trayActionConnect - > setEnabled ( true ) ;
m_trayActionDisconnect - > setEnabled ( false ) ;
break ;
2023-05-14 21:11:19 +08:00
case Vpn : : ConnectionState : : Unknown :
2021-11-28 17:28:25 +03:00
default :
m_trayActionConnect - > setEnabled ( false ) ;
m_trayActionDisconnect - > setEnabled ( true ) ;
setTrayIcon ( QString ( resourcesPath ) . arg ( DisconnectedTrayIconName ) ) ;
}
//#ifdef Q_OS_MAC
// // Get theme from current user (note, this app can be launched as root application and in this case this theme can be different from theme of real current user )
// bool darkTaskBar = MacOSFunctions::instance().isMenuBarUseDarkTheme();
// darkTaskBar = forceUseBrightIcons ? true : darkTaskBar;
// resourcesPath = ":/images_mac/tray_icon/%1";
// useIconName = useIconName.replace(".png", darkTaskBar ? "@2x.png" : " dark@2x.png");
//#endif
}
2021-11-26 17:43:02 +03:00
void SystemTrayNotificationHandler : : notify ( NotificationHandler : : Message type ,
const QString & title ,
const QString & message ,
int timerMsec ) {
Q_UNUSED ( type ) ;
2021-11-28 17:28:25 +03:00
QIcon icon ( ConnectedTrayIconName ) ;
m_systemTrayIcon . showMessage ( title , message , icon , timerMsec ) ;
2021-11-26 17:43:02 +03:00
}
void SystemTrayNotificationHandler : : showHideWindow ( ) {
// QmlEngineHolder* engine = QmlEngineHolder::instance();
// if (engine->window()->isVisible()) {
// engine->hideWindow();
//#ifdef MVPN_MACOS
// MacOSUtils::hideDockIcon();
//#endif
// } else {
// engine->showWindow();
//#ifdef MVPN_MACOS
// MacOSUtils::showDockIcon();
//#endif
// }
}