add new icons error & fix logic

This commit is contained in:
dranik
2026-06-05 16:13:06 +03:00
parent b21d77a911
commit 6f34f3509b
15 changed files with 122 additions and 22 deletions
@@ -93,11 +93,27 @@ void SystemTrayNotificationHandler::refreshTheme()
TrayIconVisual SystemTrayNotificationHandler::currentTrayVisual() const
{
TrayIconVisual visual;
visual.connectionState = m_trayState;
visual.connectionState = m_errorLatched ? Vpn::ConnectionState::Error : m_trayState;
visual.darkTheme = m_isDarkTheme;
return visual;
}
void SystemTrayNotificationHandler::setConnectionError()
{
m_errorLatched = true;
updateTrayIcon();
}
void SystemTrayNotificationHandler::clearConnectionError()
{
if (!m_errorLatched) {
return;
}
m_errorLatched = false;
updateTrayIcon();
}
void SystemTrayNotificationHandler::updateTrayIcon()
{
if (!m_trayIcon) {
@@ -118,6 +134,20 @@ void SystemTrayNotificationHandler::onTrayActivated(QSystemTrayIcon::ActivationR
void SystemTrayNotificationHandler::setTrayState(Vpn::ConnectionState state)
{
if (state == Vpn::ConnectionState::Error || state == Vpn::ConnectionState::Unknown) {
// Latch the error icon. Both Error and Unknown surface the error message
// in the UI. The connection is torn down to Disconnected right after, so
// treat the real state as Disconnected and let the latch keep the error
// icon visible until the error is acknowledged.
m_errorLatched = true;
state = Vpn::ConnectionState::Disconnected;
} else if (state != Vpn::ConnectionState::Disconnected) {
// A new (re)connecting/connected lifecycle clears a previous error.
// Plain Disconnected leaves the latch untouched so the auto-Disconnected
// that immediately follows an error does not drop the error icon.
m_errorLatched = false;
}
m_trayState = state;
switch (state) {
@@ -25,6 +25,8 @@ public:
public slots:
void updateWebsiteUrl(const QString &newWebsiteUrl);
void setConnectionError();
void clearConnectionError();
protected:
void notify(Message type, const QString& title,
@@ -51,6 +53,7 @@ private:
Vpn::ConnectionState m_trayState = Vpn::ConnectionState::Unknown;
bool m_isDarkTheme = false;
bool m_errorLatched = false;
QString websiteUrl = "https://amnezia.org";
};
+17 -4
View File
@@ -11,7 +11,7 @@ QString resourcePathForState(Vpn::ConnectionState state, bool darkTheme)
{
switch (state) {
case Vpn::ConnectionState::Error:
return QString::fromLatin1(kIconError);
return QString::fromLatin1(darkTheme ? kIconErrorWhite : kIconErrorBlack);
case Vpn::ConnectionState::Connected:
return QString::fromLatin1(darkTheme ? kIconOnWhite : kIconOnBlack);
case Vpn::ConnectionState::Disconnected:
@@ -25,6 +25,11 @@ QString resourcePathForState(Vpn::ConnectionState state, bool darkTheme)
}
}
bool isColoredState(Vpn::ConnectionState state)
{
return state == Vpn::ConnectionState::Error;
}
QPixmap renderIcon(const QString &resourcePath, int size)
{
QSvgRenderer renderer(resourcePath);
@@ -53,10 +58,8 @@ QIcon buildIcon(Vpn::ConnectionState state, bool darkTheme)
return icon;
}
QByteArray buildTemplatePng(Vpn::ConnectionState state)
QByteArray pixmapToPng(const QPixmap &pixmap)
{
const QPixmap pixmap = renderIcon(resourcePathForState(state, /*darkTheme*/ true), kDefaultTrayIconSize);
QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
@@ -64,4 +67,14 @@ QByteArray buildTemplatePng(Vpn::ConnectionState state)
return bytes;
}
QByteArray buildTemplatePng(Vpn::ConnectionState state)
{
return pixmapToPng(renderIcon(resourcePathForState(state, /*darkTheme*/ true), kDefaultTrayIconSize));
}
QByteArray buildColorPng(Vpn::ConnectionState state, bool darkTheme)
{
return pixmapToPng(renderIcon(resourcePathForState(state, darkTheme), kDefaultTrayIconSize));
}
} // namespace TrayIconCommon
+5 -1
View File
@@ -16,15 +16,19 @@ namespace TrayIconCommon
constexpr char kIconOffLight[] = ":/images/tray/off-light.svg";
constexpr char kIconOnBlack[] = ":/images/tray/on-black.svg";
constexpr char kIconOnWhite[] = ":/images/tray/on-white.svg";
constexpr char kIconError[] = ":/images/tray/error.svg";
constexpr char kIconErrorBlack[] = ":/images/tray/error-black.svg";
constexpr char kIconErrorWhite[] = ":/images/tray/error-white.svg";
QString resourcePathForState(Vpn::ConnectionState state, bool darkTheme);
bool isColoredState(Vpn::ConnectionState state);
QPixmap renderIcon(const QString &resourcePath, int size);
QPixmap buildPixmap(int size, Vpn::ConnectionState state, bool darkTheme);
QIcon buildIcon(Vpn::ConnectionState state, bool darkTheme);
QByteArray buildTemplatePng(Vpn::ConnectionState state);
QByteArray buildColorPng(Vpn::ConnectionState state, bool darkTheme);
} // namespace TrayIconCommon