-
Notifications
You must be signed in to change notification settings - Fork 994
Expand file tree
/
Copy pathsystemTrayNotificationHandler.cpp
More file actions
191 lines (167 loc) · 6.75 KB
/
Copy pathsystemTrayNotificationHandler.cpp
File metadata and controls
191 lines (167 loc) · 6.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/* 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 "systemTrayNotificationHandler.h"
#ifdef Q_OS_MAC
# include "platforms/macos/macosstatusicon.h"
#endif
#include <QApplication>
#include <QDesktopServices>
#include <QIcon>
#include <QWindow>
#include "version.h"
SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject* parent) :
NotificationHandler(parent)
#ifndef Q_OS_MAC
, m_systemTrayIcon(parent)
#endif
{
m_trayActionShow = m_menu.addAction(QIcon(":/images/tray/application.png"), tr("Show") + " " + APPLICATION_NAME, this, [this](){
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(); });
m_menu.addSeparator();
m_trayActionVisitWebSite = m_menu.addAction(QIcon(":/images/tray/link.png"), tr("Visit Website"), [&](){
QDesktopServices::openUrl(QUrl(websiteUrl));
});
// 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(); });
#ifdef Q_OS_MAC
// QSystemTrayIcon::setContextMenu crashes on macOS 14+: its menu-tracking
// observer reads -[NSEvent clickCount] off a non-mouse event. Own the
// NSStatusItem and attach the native NSMenu instead.
m_statusIcon = new MacOSStatusIcon(this);
m_statusIcon->setMenu(&m_menu);
#else
m_systemTrayIcon.show();
connect(&m_systemTrayIcon, &QSystemTrayIcon::activated, this,
&SystemTrayNotificationHandler::onTrayActivated);
m_systemTrayIcon.setContextMenu(&m_menu);
#endif
setTrayState(Vpn::ConnectionState::Disconnected);
}
SystemTrayNotificationHandler::~SystemTrayNotificationHandler() {
#ifdef Q_OS_MAC
delete m_statusIcon; // before m_menu: the status item references its NSMenu
m_statusIcon = nullptr;
#endif
}
void SystemTrayNotificationHandler::setConnectionState(Vpn::ConnectionState state)
{
setTrayState(state);
NotificationHandler::setConnectionState(state);
}
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);
}
void SystemTrayNotificationHandler::updateWebsiteUrl(const QString &newWebsiteUrl) {
qDebug() << "Updated website URL:" << newWebsiteUrl;
websiteUrl = newWebsiteUrl;
}
void SystemTrayNotificationHandler::setTrayIcon(const QString &iconPath)
{
#ifdef Q_OS_MAC
m_statusIcon->setIcon(iconPath);
#else
QIcon trayIconMask(QPixmap(iconPath).scaled(128,128));
trayIconMask.setIsMask(true);
m_systemTrayIcon.setIcon(trayIconMask);
#endif
}
void SystemTrayNotificationHandler::onTrayActivated(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::DoubleClick || reason == QSystemTrayIcon::Trigger) {
emit raiseRequested();
}
}
void SystemTrayNotificationHandler::setTrayState(Vpn::ConnectionState state)
{
QString resourcesPath = ":/images/tray/%1";
switch (state) {
case Vpn::ConnectionState::Disconnected:
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
m_trayActionConnect->setEnabled(true);
m_trayActionDisconnect->setEnabled(false);
break;
case Vpn::ConnectionState::Preparing:
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
m_trayActionConnect->setEnabled(false);
m_trayActionDisconnect->setEnabled(true);
break;
case Vpn::ConnectionState::Connecting:
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
m_trayActionConnect->setEnabled(false);
m_trayActionDisconnect->setEnabled(true);
break;
case Vpn::ConnectionState::Connected:
setTrayIcon(QString(resourcesPath).arg(ConnectedTrayIconName));
m_trayActionConnect->setEnabled(false);
m_trayActionDisconnect->setEnabled(true);
break;
case Vpn::ConnectionState::Disconnecting:
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
m_trayActionConnect->setEnabled(false);
m_trayActionDisconnect->setEnabled(true);
break;
case Vpn::ConnectionState::Reconnecting:
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
m_trayActionConnect->setEnabled(false);
m_trayActionDisconnect->setEnabled(true);
break;
case Vpn::ConnectionState::Error:
setTrayIcon(QString(resourcesPath).arg(ErrorTrayIconName));
m_trayActionConnect->setEnabled(true);
m_trayActionDisconnect->setEnabled(false);
break;
case Vpn::ConnectionState::Unknown:
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
}
void SystemTrayNotificationHandler::notify(NotificationHandler::Message type,
const QString& title,
const QString& message,
int timerMsec) {
Q_UNUSED(type);
#ifdef Q_OS_MAC
Q_UNUSED(timerMsec);
m_statusIcon->showMessage(title, message);
#else
QIcon icon(ConnectedTrayIconName);
m_systemTrayIcon.showMessage(title, message, icon, timerMsec);
#endif
}
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
// }
}