UI: TrayIcon: Improve mouse click handling.

This commit is contained in:
Nodir Temirkhodjaev 2021-05-26 16:05:04 +03:00
parent 05b64f0bea
commit af26a802e3
4 changed files with 73 additions and 52 deletions

View File

@ -53,10 +53,17 @@ QAction *addAction(QWidget *widget, const QIcon &icon, const QString &text,
}
TrayIcon::TrayIcon(FortManager *fortManager, QObject *parent) :
QSystemTrayIcon(parent), m_ctrl(new TrayController(fortManager, this))
QSystemTrayIcon(parent), m_trayTriggered(false), m_ctrl(new TrayController(fortManager, this))
{
setupUi();
setupController();
connect(this, &QSystemTrayIcon::activated, this, &TrayIcon::onTrayActivated);
}
TrayIcon::~TrayIcon()
{
delete m_menu;
}
FortManager *TrayIcon::fortManager() const
@ -94,6 +101,37 @@ HotKeyManager *TrayIcon::hotKeyManager() const
return ctrl()->hotKeyManager();
}
void TrayIcon::onTrayActivated(int reason)
{
switch (reason) {
case QSystemTrayIcon::Trigger:
m_trayTriggered = true;
QTimer::singleShot(QApplication::doubleClickInterval(), this, [&] {
if (m_trayTriggered) {
m_trayTriggered = false;
emit mouseClicked();
}
});
break;
case QSystemTrayIcon::DoubleClick:
if (m_trayTriggered) {
m_trayTriggered = false;
emit mouseDoubleClicked();
}
break;
case QSystemTrayIcon::MiddleClick:
emit mouseMiddleClicked();
break;
case QSystemTrayIcon::Context:
if (!m_trayTriggered) {
m_menu->popup(QCursor::pos());
}
break;
default:
break;
}
}
void TrayIcon::updateTrayIcon(bool alerted)
{
const auto icon = alerted
@ -105,11 +143,10 @@ void TrayIcon::updateTrayIcon(bool alerted)
void TrayIcon::showTrayMenu(QMouseEvent *event)
{
QMenu *menu = this->contextMenu();
if (!menu)
if (!m_menu)
return;
menu->popup(mouseEventGlobalPos(event));
m_menu->popup(mouseEventGlobalPos(event));
}
void TrayIcon::updateTrayMenu(bool onlyFlags)
@ -163,47 +200,48 @@ void TrayIcon::setupUi()
void TrayIcon::setupTrayMenu()
{
QMenu *menu = new QMenu(fortManager()->mainWindow());
m_menu = new QMenu(fortManager()->mainWindow());
m_programsAction = addAction(menu, IconCache::icon(":/icons/window.png"), QString(),
m_programsAction = addAction(m_menu, IconCache::icon(":/icons/window.png"), QString(),
fortManager(), SLOT(showProgramsWindow()));
addHotKey(m_programsAction, iniUser()->hotKeyPrograms());
m_optionsAction = addAction(menu, IconCache::icon(":/icons/cog.png"), QString(), fortManager(),
SLOT(showOptionsWindow()));
m_optionsAction = addAction(m_menu, IconCache::icon(":/icons/cog.png"), QString(),
fortManager(), SLOT(showOptionsWindow()));
addHotKey(m_optionsAction, iniUser()->hotKeyOptions());
m_statisticsAction = addAction(menu, IconCache::icon(":/icons/chart-bar.png"), QString(),
m_statisticsAction = addAction(m_menu, IconCache::icon(":/icons/chart-bar.png"), QString(),
fortManager(), SLOT(showStatisticsWindow()));
addHotKey(m_statisticsAction, iniUser()->hotKeyStatistics());
m_graphAction = addAction(menu, IconCache::icon(":/icons/line-graph.png"), QString(),
m_graphAction = addAction(m_menu, IconCache::icon(":/icons/line-graph.png"), QString(),
fortManager(), SLOT(switchGraphWindow()), true, !!fortManager()->graphWindow());
addHotKey(m_graphAction, iniUser()->hotKeyGraph());
m_zonesAction = addAction(menu, IconCache::icon(":/icons/map-map-marker.png"), QString(),
m_zonesAction = addAction(m_menu, IconCache::icon(":/icons/map-map-marker.png"), QString(),
fortManager(), SLOT(showZonesWindow()));
addHotKey(m_zonesAction, iniUser()->hotKeyZones());
menu->addSeparator();
m_menu->addSeparator();
m_filterEnabledAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
m_filterEnabledAction =
addAction(m_menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
addHotKey(m_filterEnabledAction, iniUser()->hotKeyFilter());
m_stopTrafficAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
m_stopTrafficAction = addAction(m_menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
addHotKey(m_stopTrafficAction, iniUser()->hotKeyStopTraffic());
m_stopInetTrafficAction =
addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
addAction(m_menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
addHotKey(m_stopInetTrafficAction, iniUser()->hotKeyStopInetTraffic());
m_allowAllNewAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
m_allowAllNewAction = addAction(m_menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
addHotKey(m_allowAllNewAction, iniUser()->hotKeyAllowAllNew());
menu->addSeparator();
m_menu->addSeparator();
for (int i = 0; i < MAX_APP_GROUP_COUNT; ++i) {
QAction *a = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
QAction *a = addAction(m_menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true);
if (i < 12) {
const QString shortcutText =
@ -215,11 +253,10 @@ void TrayIcon::setupTrayMenu()
m_appGroupActions.append(a);
}
menu->addSeparator();
m_quitAction = addAction(menu, QIcon(), tr("Quit"), fortManager(), SLOT(quitByCheckPassword()));
m_menu->addSeparator();
m_quitAction =
addAction(m_menu, QIcon(), tr("Quit"), fortManager(), SLOT(quitByCheckPassword()));
addHotKey(m_quitAction, iniUser()->hotKeyQuit());
this->setContextMenu(menu);
}
void TrayIcon::updateTrayMenuFlags()

View File

@ -21,6 +21,7 @@ class TrayIcon : public QSystemTrayIcon
public:
explicit TrayIcon(FortManager *fortManager, QObject *parent = nullptr);
~TrayIcon() override;
TrayController *ctrl() const { return m_ctrl; }
FortManager *fortManager() const;
@ -31,6 +32,11 @@ public:
IniUser *iniUser() const;
HotKeyManager *hotKeyManager() const;
signals:
void mouseClicked();
void mouseDoubleClicked();
void mouseMiddleClicked();
public slots:
void updateTrayIcon(bool alerted = false);
@ -38,6 +44,8 @@ public slots:
void updateTrayMenu(bool onlyFlags = false);
protected slots:
void onTrayActivated(int reason);
void saveTrayFlags();
private:
@ -56,6 +64,9 @@ private:
void removeHotKeys();
private:
bool m_trayTriggered : 1;
QMenu *m_menu = nullptr;
QAction *m_programsAction = nullptr;
QAction *m_optionsAction = nullptr;
QAction *m_statisticsAction = nullptr;

View File

@ -65,7 +65,6 @@ FortManager::FortManager(FortSettings *settings, EnvManager *envManager,
ControlManager *controlManager, QObject *parent) :
QObject(parent),
m_initialized(false),
m_trayTriggered(false),
m_settings(settings),
m_envManager(envManager),
m_controlManager(controlManager)
@ -400,7 +399,9 @@ void FortManager::setupTrayIcon()
{
m_trayIcon = new TrayIcon(this);
connect(m_trayIcon, &QSystemTrayIcon::activated, this, &FortManager::onTrayActivated);
connect(m_trayIcon, &TrayIcon::mouseClicked, this, &FortManager::showProgramsWindow);
connect(m_trayIcon, &TrayIcon::mouseDoubleClicked, this, &FortManager::showOptionsWindow);
connect(m_trayIcon, &TrayIcon::mouseMiddleClicked, this, &FortManager::showStatisticsWindow);
connect(m_trayIcon, &QSystemTrayIcon::messageClicked, this, &FortManager::onTrayMessageClicked);
connect(confManager(), &ConfManager::confChanged, m_trayIcon, &TrayIcon::updateTrayMenu);
@ -790,32 +791,6 @@ void FortManager::updateStatManager(FirewallConf *conf)
statManager()->setConf(conf);
}
void FortManager::onTrayActivated(int reason)
{
switch (reason) {
case QSystemTrayIcon::Trigger:
m_trayTriggered = false;
QTimer::singleShot(QApplication::doubleClickInterval(), this, [this] {
if (!m_trayTriggered) {
m_trayTriggered = true;
showProgramsWindow();
}
});
break;
case QSystemTrayIcon::DoubleClick:
if (!m_trayTriggered) {
m_trayTriggered = true;
showOptionsWindow();
}
break;
case QSystemTrayIcon::MiddleClick:
showStatisticsWindow();
break;
default:
break;
}
}
void FortManager::onTrayMessageClicked()
{
switch (m_lastMessageType) {

View File

@ -189,7 +189,6 @@ private:
void updateLogManager(bool active);
void updateStatManager(FirewallConf *conf);
void onTrayActivated(int reason);
void onTrayMessageClicked();
QWidget *focusWidget() const;
@ -197,7 +196,6 @@ private:
private:
bool m_initialized : 1;
bool m_trayTriggered : 1;
TrayMessageType m_lastMessageType = MessageOptions;