diff --git a/client/platforms/linux/linuxsystemtraynotificationhandler.cpp b/client/platforms/linux/linuxsystemtraynotificationhandler.cpp index bc4fda36..1842156f 100644 --- a/client/platforms/linux/linuxsystemtraynotificationhandler.cpp +++ b/client/platforms/linux/linuxsystemtraynotificationhandler.cpp @@ -6,8 +6,10 @@ #include "constants.h" #include "leakdetector.h" #include "logger.h" +#include "defines.h" #include +#include constexpr const char* DBUS_ITEM = "org.freedesktop.Notifications"; constexpr const char* DBUS_PATH = "/org/freedesktop/Notifications"; @@ -38,11 +40,30 @@ bool LinuxSystemTrayNotificationHandler::requiredCustomImpl() { LinuxSystemTrayNotificationHandler::LinuxSystemTrayNotificationHandler( QObject* parent) : SystemTrayNotificationHandler(parent) { - MVPN_COUNT_CTOR(LinuxSystemTrayNotificationHandler); - QDBusConnection::sessionBus().connect(DBUS_ITEM, DBUS_PATH, DBUS_INTERFACE, - "ActionInvoked", this, - SLOT(actionInvoked(uint, QString))); + m_systemTrayIcon.show(); + connect(&m_systemTrayIcon, &QSystemTrayIcon::activated, this); + + + 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_menu.addAction(QIcon(":/images/tray/link.png"), tr("Visit Website"), [&](){ + QDesktopServices::openUrl(QUrl("https://amnezia.org")); + }); + + m_menu.addAction(QIcon(":/images/tray/cancel.png"), tr("Quit") + " " + APPLICATION_NAME, this, [&](){ + qApp->quit(); + }); + + m_systemTrayIcon.setContextMenu(&m_menu); + setTrayState(VpnProtocol::Disconnected); } LinuxSystemTrayNotificationHandler::~LinuxSystemTrayNotificationHandler() { @@ -53,50 +74,8 @@ void LinuxSystemTrayNotificationHandler::notify(Message type, const QString& title, const QString& message, int timerMsec) { - QString actionMessage; - switch (type) { - case None: - return SystemTrayNotificationHandler::notify(type, title, message, - timerMsec); - case UnsecuredNetwork: - actionMessage = qtTrId("vpn.toggle.on"); - break; - case CaptivePortalBlock: - actionMessage = qtTrId("vpn.toggle.off"); - break; - - case CaptivePortalUnblock: - actionMessage = qtTrId("vpn.toggle.on"); - break; - - default: - Q_ASSERT(false); - } - - m_lastMessage = type; - emit notificationShown(title, message); - - QDBusInterface n(DBUS_ITEM, DBUS_PATH, DBUS_INTERFACE, - QDBusConnection::sessionBus()); - if (!n.isValid()) { - qWarning("Failed to connect to the notification manager via system dbus"); - return; - } - - uint32_t replacesId = 0; // Don't replace. - const char* appIcon = MVPN_ICON_PATH; - QStringList actions{ACTION_ID, actionMessage}; - QMap hints; - - QDBusReply reply = n.call("Notify", "Mozilla VPN", replacesId, appIcon, - title, message, actions, hints, timerMsec); - if (!reply.isValid()) { - logger.warning() << "Failed to show the notification"; - } - - m_lastNotificationId = reply; } void LinuxSystemTrayNotificationHandler::actionInvoked(uint actionId, diff --git a/client/platforms/linux/linuxsystemtraynotificationhandler.h b/client/platforms/linux/linuxsystemtraynotificationhandler.h index 359d3512..d8484bf7 100644 --- a/client/platforms/linux/linuxsystemtraynotificationhandler.h +++ b/client/platforms/linux/linuxsystemtraynotificationhandler.h @@ -23,11 +23,25 @@ class LinuxSystemTrayNotificationHandler final private: void notify(Message type, const QString& title, const QString& message, int timerMsec) override; + void setTrayState(VpnProtocol::VpnConnectionState state); private slots: void actionInvoked(uint actionId, QString action); private: + QMenu m_menu; + QSystemTrayIcon m_systemTrayIcon; + + QAction* m_trayActionConnect = nullptr; + QAction* m_trayActionDisconnect = nullptr; + QAction* m_preferencesAction = nullptr; + QAction* m_statusLabel = nullptr; + QAction* m_separator = nullptr; + + const QString ConnectedTrayIconName = "active.png"; + const QString DisconnectedTrayIconName = "default.png"; + const QString ErrorTrayIconName = "error.png"; + uint m_lastNotificationId = 0; }; diff --git a/client/ui/notificationhandler.cpp b/client/ui/notificationhandler.cpp index 59054287..81f6430a 100644 --- a/client/ui/notificationhandler.cpp +++ b/client/ui/notificationhandler.cpp @@ -12,7 +12,7 @@ #else # if defined(Q_OS_LINUX) -# include "linuxsystemtraynotificationhandler.h" +# include "platforms/linux/linuxsystemtraynotificationhandler.h" # endif # include "systemtray_notificationhandler.h" @@ -27,7 +27,7 @@ NotificationHandler* NotificationHandler::create(QObject* parent) { #else # if defined(Q_OS_LINUX) - if (LinuxSystemTrayNotificationHandler::requiredCustomImpl() == true) { + if (LinuxSystemTrayNotificationHandler::requiredCustomImpl()) { return new LinuxSystemTrayNotificationHandler(parent); } # endif