mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
fixed icon conn/disc macos
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
#include "platformTheme.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QStyleHints>
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
# include "platforms/macos/macosutils.h"
|
||||
#elif defined(Q_OS_WIN)
|
||||
# include "platforms/windows/windowsutils.h"
|
||||
#endif
|
||||
|
||||
bool platformIsDarkTheme()
|
||||
{
|
||||
#if defined(Q_OS_MAC)
|
||||
return MacOSUtils::isDarkTheme();
|
||||
#elif defined(Q_OS_WIN)
|
||||
return WindowsUtils::isDarkTheme();
|
||||
#else
|
||||
if (QStyleHints *styleHints = QGuiApplication::styleHints()) {
|
||||
return styleHints->colorScheme() == Qt::ColorScheme::Dark;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef PLATFORMTHEME_H
|
||||
#define PLATFORMTHEME_H
|
||||
|
||||
bool platformIsDarkTheme();
|
||||
|
||||
#endif // PLATFORMTHEME_H
|
||||
@@ -5,14 +5,23 @@
|
||||
#include <QDebug>
|
||||
#include "systemTrayNotificationHandler.h"
|
||||
|
||||
#include "platformTheme.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QBuffer>
|
||||
#include <QColor>
|
||||
#include <QDesktopServices>
|
||||
#include <QGuiApplication>
|
||||
#include <QIcon>
|
||||
#include <QPainter>
|
||||
#include <QStyleHints>
|
||||
#include <QSvgRenderer>
|
||||
#include <QWindow>
|
||||
#include <QEvent>
|
||||
#include <functional>
|
||||
|
||||
#if defined(Q_OS_MAC) && !defined(MACOS_NE)
|
||||
# include "platforms/macos/macosstatusicon.h"
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
|
||||
@@ -21,6 +30,30 @@ namespace {
|
||||
constexpr int kTrayIconSize = 128;
|
||||
constexpr char kTrayTemplateIconPath[] = ":/images/tray/icon.svg";
|
||||
|
||||
class TrayThemeChangeFilter final : public QObject {
|
||||
public:
|
||||
explicit TrayThemeChangeFilter(std::function<void()> onThemeChanged, QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
, m_onThemeChanged(std::move(onThemeChanged))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event) override
|
||||
{
|
||||
Q_UNUSED(watched);
|
||||
if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange) {
|
||||
if (m_onThemeChanged) {
|
||||
m_onThemeChanged();
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> m_onThemeChanged;
|
||||
};
|
||||
|
||||
QPixmap renderTrayTemplate(const QString &resourcePath, qreal opacity)
|
||||
{
|
||||
QSvgRenderer renderer(resourcePath);
|
||||
@@ -38,6 +71,17 @@ QPixmap renderTrayTemplate(const QString &resourcePath, qreal opacity)
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QByteArray renderTrayTemplatePng(qreal opacity)
|
||||
{
|
||||
const QPixmap pixmap = renderTrayTemplate(QString::fromLatin1(kTrayTemplateIconPath), opacity);
|
||||
|
||||
QByteArray bytes;
|
||||
QBuffer buffer(&bytes);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
pixmap.save(&buffer, "PNG");
|
||||
return bytes;
|
||||
}
|
||||
|
||||
QIcon buildTrayIcon(qreal opacity)
|
||||
{
|
||||
const QPixmap pixmap = renderTrayTemplate(QString::fromLatin1(kTrayTemplateIconPath), opacity);
|
||||
@@ -51,12 +95,21 @@ QIcon buildTrayIcon(qreal opacity)
|
||||
} // namespace
|
||||
|
||||
SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject* parent) :
|
||||
NotificationHandler(parent),
|
||||
m_systemTrayIcon(parent)
|
||||
|
||||
NotificationHandler(parent)
|
||||
#if !defined(Q_OS_MAC) || defined(MACOS_NE)
|
||||
, m_systemTrayIcon(parent)
|
||||
#endif
|
||||
{
|
||||
#if defined(Q_OS_MAC) && !defined(MACOS_NE)
|
||||
m_macStatusIcon = new MacOSStatusIcon(this);
|
||||
m_macStatusIcon->setMenu(&m_menu);
|
||||
m_macStatusIcon->setToolTip(APPLICATION_NAME);
|
||||
// Template NSStatusItem icons follow the menu bar appearance automatically.
|
||||
#else
|
||||
m_systemTrayIcon.show();
|
||||
connect(&m_systemTrayIcon, &QSystemTrayIcon::activated, this, &SystemTrayNotificationHandler::onTrayActivated);
|
||||
m_systemTrayIcon.setContextMenu(&m_menu);
|
||||
#endif
|
||||
|
||||
m_trayActionShow = m_menu.addAction(tr("Show") + " " + APPLICATION_NAME, this, [this](){
|
||||
emit raiseRequested();
|
||||
@@ -75,14 +128,19 @@ SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject* parent) :
|
||||
this,
|
||||
[&](){ qApp->quit(); });
|
||||
|
||||
m_systemTrayIcon.setContextMenu(&m_menu);
|
||||
|
||||
#if !defined(Q_OS_MAC) || defined(MACOS_NE)
|
||||
if (QStyleHints *styleHints = QGuiApplication::styleHints()) {
|
||||
connect(styleHints, &QStyleHints::colorSchemeChanged, this, [this]() {
|
||||
updateTrayIcon();
|
||||
refreshTheme();
|
||||
});
|
||||
}
|
||||
|
||||
qApp->installEventFilter(new TrayThemeChangeFilter([this]() {
|
||||
refreshTheme();
|
||||
}, this));
|
||||
#endif
|
||||
|
||||
refreshTheme();
|
||||
setTrayState(Vpn::ConnectionState::Disconnected);
|
||||
}
|
||||
|
||||
@@ -102,6 +160,12 @@ void SystemTrayNotificationHandler::onTranslationsUpdated()
|
||||
m_trayActionDisconnect->setText(tr("Disconnect"));
|
||||
m_trayActionVisitWebSite->setText(tr("Visit Website"));
|
||||
m_trayActionQuit->setText(tr("Quit")+ " " + APPLICATION_NAME);
|
||||
|
||||
#if defined(Q_OS_MAC) && !defined(MACOS_NE)
|
||||
if (m_macStatusIcon) {
|
||||
m_macStatusIcon->rebuildNativeMenu();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemTrayNotificationHandler::updateWebsiteUrl(const QString &newWebsiteUrl) {
|
||||
@@ -109,6 +173,15 @@ void SystemTrayNotificationHandler::updateWebsiteUrl(const QString &newWebsiteUr
|
||||
websiteUrl = newWebsiteUrl;
|
||||
}
|
||||
|
||||
void SystemTrayNotificationHandler::refreshTheme()
|
||||
{
|
||||
m_isDarkTheme = platformIsDarkTheme();
|
||||
|
||||
#if !defined(Q_OS_MAC) || defined(MACOS_NE)
|
||||
updateTrayIcon();
|
||||
#endif
|
||||
}
|
||||
|
||||
qreal SystemTrayNotificationHandler::trayIconOpacityForState(Vpn::ConnectionState state) const
|
||||
{
|
||||
switch (state) {
|
||||
@@ -126,10 +199,29 @@ qreal SystemTrayNotificationHandler::trayIconOpacityForState(Vpn::ConnectionStat
|
||||
}
|
||||
}
|
||||
|
||||
QColor SystemTrayNotificationHandler::trayIndicatorColorForState(Vpn::ConnectionState state) const
|
||||
{
|
||||
switch (state) {
|
||||
case Vpn::ConnectionState::Connected:
|
||||
return QColor(52, 199, 89);
|
||||
case Vpn::ConnectionState::Error:
|
||||
return QColor(235, 87, 87);
|
||||
default:
|
||||
return QColor();
|
||||
}
|
||||
}
|
||||
|
||||
void SystemTrayNotificationHandler::updateTrayIcon()
|
||||
{
|
||||
const qreal opacity = trayIconOpacityForState(m_trayState);
|
||||
|
||||
#if defined(Q_OS_MAC) && !defined(MACOS_NE)
|
||||
Q_ASSERT(m_macStatusIcon);
|
||||
m_macStatusIcon->setIconFromData(renderTrayTemplatePng(opacity));
|
||||
m_macStatusIcon->setIndicatorColor(trayIndicatorColorForState(m_trayState));
|
||||
#else
|
||||
m_systemTrayIcon.setIcon(buildTrayIcon(opacity));
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemTrayNotificationHandler::onTrayActivated(QSystemTrayIcon::ActivationReason reason)
|
||||
@@ -182,8 +274,13 @@ void SystemTrayNotificationHandler::setTrayState(Vpn::ConnectionState state)
|
||||
}
|
||||
|
||||
updateTrayIcon();
|
||||
}
|
||||
|
||||
#if defined(Q_OS_MAC) && !defined(MACOS_NE)
|
||||
if (m_macStatusIcon) {
|
||||
m_macStatusIcon->rebuildNativeMenu();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemTrayNotificationHandler::notify(NotificationHandler::Message type,
|
||||
const QString& title,
|
||||
@@ -191,7 +288,12 @@ void SystemTrayNotificationHandler::notify(NotificationHandler::Message type,
|
||||
int timerMsec) {
|
||||
Q_UNUSED(type);
|
||||
|
||||
#if defined(Q_OS_MAC) && !defined(MACOS_NE)
|
||||
Q_ASSERT(m_macStatusIcon);
|
||||
m_macStatusIcon->showMessage(title, message);
|
||||
#else
|
||||
m_systemTrayIcon.showMessage(title, message, buildTrayIcon(kConnectedTrayOpacity), timerMsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemTrayNotificationHandler::showHideWindow() {
|
||||
|
||||
@@ -7,9 +7,14 @@
|
||||
|
||||
#include "notificationHandler.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QMenu>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
#if defined(Q_OS_MAC) && !defined(MACOS_NE)
|
||||
class MacOSStatusIcon;
|
||||
#endif
|
||||
|
||||
class SystemTrayNotificationHandler : public NotificationHandler {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -34,12 +39,19 @@ private:
|
||||
void setTrayState(Vpn::ConnectionState state);
|
||||
void onTrayActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
void refreshTheme();
|
||||
void updateTrayIcon();
|
||||
qreal trayIconOpacityForState(Vpn::ConnectionState state) const;
|
||||
QColor trayIndicatorColorForState(Vpn::ConnectionState state) const;
|
||||
|
||||
private:
|
||||
QMenu m_menu;
|
||||
|
||||
#if defined(Q_OS_MAC) && !defined(MACOS_NE)
|
||||
MacOSStatusIcon *m_macStatusIcon = nullptr;
|
||||
#else
|
||||
QSystemTrayIcon m_systemTrayIcon;
|
||||
#endif
|
||||
|
||||
QAction* m_trayActionShow = nullptr;
|
||||
QAction* m_trayActionConnect = nullptr;
|
||||
@@ -50,6 +62,7 @@ private:
|
||||
QAction* m_separator = nullptr;
|
||||
|
||||
Vpn::ConnectionState m_trayState = Vpn::ConnectionState::Unknown;
|
||||
bool m_isDarkTheme = false;
|
||||
|
||||
static constexpr qreal kDisconnectedTrayOpacity = 0.5;
|
||||
static constexpr qreal kConnectedTrayOpacity = 1.0;
|
||||
|
||||
Reference in New Issue
Block a user