Ubuntu Tray Icon at Start Up (#6889)
* refactored and setup retries * undoing suggested change, due to older qt on CI * ensuring a fresh connection for checking tray icon * cleaning debug messages * Update ChangeLog * removed <iostream> unneeded include * incorporating suggestions * incorporated SonarCloud suggestions, changed timer * additional suggestion -applied on legacy base * added a const version of appConfig
This commit is contained in:
parent
30b2fdc4e3
commit
c06cdda15f
6 changed files with 97 additions and 45 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
v1.13.1-snapshot
|
v1.13.1-snapshot
|
||||||
===========
|
===========
|
||||||
|
- #6889 Systray Icon on Ubuntu Auto Start (take 2)
|
||||||
===========
|
===========
|
||||||
|
|
||||||
v1.13.0-stable
|
v1.13.0-stable
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#define DOWNLOAD_URL "http://symless.com/?source=gui"
|
#define DOWNLOAD_URL "http://symless.com/?source=gui"
|
||||||
#define HELP_URL "http://symless.com/help?source=gui"
|
#define HELP_URL "http://symless.com/help?source=gui"
|
||||||
|
|
||||||
#include <iostream>
|
#include <array>
|
||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
|
||||||
|
|
@ -112,8 +112,6 @@ MainWindow::MainWindow (AppConfig& appConfig,
|
||||||
m_pSynergy(NULL),
|
m_pSynergy(NULL),
|
||||||
m_SynergyState(synergyDisconnected),
|
m_SynergyState(synergyDisconnected),
|
||||||
m_ServerConfig(5, 3, m_AppConfig->screenName(), this),
|
m_ServerConfig(5, 3, m_AppConfig->screenName(), this),
|
||||||
m_pTrayIcon(NULL),
|
|
||||||
m_pTrayIconMenu(NULL),
|
|
||||||
m_AlreadyHidden(false),
|
m_AlreadyHidden(false),
|
||||||
m_pMenuBar(NULL),
|
m_pMenuBar(NULL),
|
||||||
m_pMenuFile(NULL),
|
m_pMenuFile(NULL),
|
||||||
|
|
@ -228,7 +226,20 @@ MainWindow::~MainWindow()
|
||||||
|
|
||||||
void MainWindow::open()
|
void MainWindow::open()
|
||||||
{
|
{
|
||||||
createTrayIcon();
|
std::array<QAction *, 7> trayMenu = {
|
||||||
|
m_pActionStartSynergy,
|
||||||
|
m_pActionStopSynergy,
|
||||||
|
nullptr,
|
||||||
|
m_pActionMinimize,
|
||||||
|
m_pActionRestore,
|
||||||
|
nullptr,
|
||||||
|
m_pActionQuit
|
||||||
|
};
|
||||||
|
|
||||||
|
m_trayIcon.create(trayMenu, [this](QObject const *o, const char *s) {
|
||||||
|
connect(o, s, this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
|
||||||
|
setIcon(synergyDisconnected);
|
||||||
|
});
|
||||||
|
|
||||||
if (appConfig().getAutoHide()) {
|
if (appConfig().getAutoHide()) {
|
||||||
hide();
|
hide();
|
||||||
|
|
@ -251,31 +262,6 @@ void MainWindow::setStatus(const QString &status)
|
||||||
m_pStatusLabel->setText(status);
|
m_pStatusLabel->setText(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::createTrayIcon()
|
|
||||||
{
|
|
||||||
m_pTrayIconMenu = new QMenu(this);
|
|
||||||
|
|
||||||
m_pTrayIconMenu->addAction(m_pActionStartSynergy);
|
|
||||||
m_pTrayIconMenu->addAction(m_pActionStopSynergy);
|
|
||||||
m_pTrayIconMenu->addSeparator();
|
|
||||||
|
|
||||||
m_pTrayIconMenu->addAction(m_pActionMinimize);
|
|
||||||
m_pTrayIconMenu->addAction(m_pActionRestore);
|
|
||||||
m_pTrayIconMenu->addSeparator();
|
|
||||||
m_pTrayIconMenu->addAction(m_pActionQuit);
|
|
||||||
|
|
||||||
m_pTrayIcon = new QSystemTrayIcon(this);
|
|
||||||
m_pTrayIcon->setContextMenu(m_pTrayIconMenu);
|
|
||||||
m_pTrayIcon->setToolTip("Synergy");
|
|
||||||
|
|
||||||
connect(m_pTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
|
||||||
this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
|
|
||||||
|
|
||||||
setIcon(synergyDisconnected);
|
|
||||||
|
|
||||||
m_pTrayIcon->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::retranslateMenuBar()
|
void MainWindow::retranslateMenuBar()
|
||||||
{
|
{
|
||||||
m_pMenuFile->setTitle(tr("&File"));
|
m_pMenuFile->setTitle(tr("&File"));
|
||||||
|
|
@ -366,7 +352,8 @@ void MainWindow::zeroConfToggled() {
|
||||||
updateAutoConfigWidgets();
|
updateAutoConfigWidgets();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void MainWindow::setIcon(qSynergyState state)
|
|
||||||
|
void MainWindow::setIcon(qSynergyState state) const
|
||||||
{
|
{
|
||||||
QIcon icon;
|
QIcon icon;
|
||||||
|
|
||||||
|
|
@ -379,8 +366,7 @@ void MainWindow::setIcon(qSynergyState state)
|
||||||
icon.addFile(synergyDefaultIconFiles[state]);
|
icon.addFile(synergyDefaultIconFiles[state]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_pTrayIcon)
|
m_trayIcon.set(icon);
|
||||||
m_pTrayIcon->setIcon(icon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason)
|
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason)
|
||||||
|
|
@ -847,7 +833,7 @@ QString MainWindow::configFilename()
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainWindow::address()
|
QString MainWindow::address() const
|
||||||
{
|
{
|
||||||
QString i = appConfig().networkInterface();
|
QString i = appConfig().networkInterface();
|
||||||
return (!i.isEmpty() ? i : "") + ":" + QString::number(appConfig().port());
|
return (!i.isEmpty() ? i : "") + ":" + QString::number(appConfig().port());
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
#include "ui_MainWindowBase.h"
|
#include "ui_MainWindowBase.h"
|
||||||
|
|
||||||
|
|
@ -34,7 +35,7 @@
|
||||||
#include "ActivationDialog.h"
|
#include "ActivationDialog.h"
|
||||||
#include "ConfigWriter.h"
|
#include "ConfigWriter.h"
|
||||||
|
|
||||||
#include <QMutex>
|
#include "TrayIcon.h"
|
||||||
|
|
||||||
class QAction;
|
class QAction;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
|
|
@ -108,7 +109,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
int synergyState() const { return m_SynergyState; }
|
int synergyState() const { return m_SynergyState; }
|
||||||
QString hostname() const { return m_pLineEditHostname->text(); }
|
QString hostname() const { return m_pLineEditHostname->text(); }
|
||||||
QString configFilename();
|
QString configFilename();
|
||||||
QString address();
|
QString address() const;
|
||||||
QString appPath(const QString& name);
|
QString appPath(const QString& name);
|
||||||
void open();
|
void open();
|
||||||
void clearLog();
|
void clearLog();
|
||||||
|
|
@ -166,6 +167,7 @@ public slots:
|
||||||
// TODO This should be properly using the ConfigWriter system.
|
// TODO This should be properly using the ConfigWriter system.
|
||||||
QSettings& settings() { return GUI::Config::ConfigWriter::make()->settings(); }
|
QSettings& settings() { return GUI::Config::ConfigWriter::make()->settings(); }
|
||||||
AppConfig& appConfig() { return *m_AppConfig; }
|
AppConfig& appConfig() { return *m_AppConfig; }
|
||||||
|
AppConfig const& appConfig() const { return *m_AppConfig; }
|
||||||
QProcess* synergyProcess() { return m_pSynergy; }
|
QProcess* synergyProcess() { return m_pSynergy; }
|
||||||
void setSynergyProcess(QProcess* p) { m_pSynergy = p; }
|
void setSynergyProcess(QProcess* p) { m_pSynergy = p; }
|
||||||
void initConnections();
|
void initConnections();
|
||||||
|
|
@ -173,7 +175,7 @@ public slots:
|
||||||
void createStatusBar();
|
void createStatusBar();
|
||||||
void createTrayIcon();
|
void createTrayIcon();
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void setIcon(qSynergyState state);
|
void setIcon(qSynergyState state) const;
|
||||||
void setSynergyState(qSynergyState state);
|
void setSynergyState(qSynergyState state);
|
||||||
bool checkForApp(int which, QString& app);
|
bool checkForApp(int which, QString& app);
|
||||||
bool clientArgs(QStringList& args, QString& app);
|
bool clientArgs(QStringList& args, QString& app);
|
||||||
|
|
@ -221,8 +223,6 @@ public slots:
|
||||||
QProcess* m_pSynergy;
|
QProcess* m_pSynergy;
|
||||||
int m_SynergyState;
|
int m_SynergyState;
|
||||||
ServerConfig m_ServerConfig;
|
ServerConfig m_ServerConfig;
|
||||||
QSystemTrayIcon* m_pTrayIcon;
|
|
||||||
QMenu* m_pTrayIconMenu;
|
|
||||||
bool m_AlreadyHidden;
|
bool m_AlreadyHidden;
|
||||||
VersionChecker m_VersionChecker;
|
VersionChecker m_VersionChecker;
|
||||||
IpcClient m_IpcClient;
|
IpcClient m_IpcClient;
|
||||||
|
|
@ -232,6 +232,7 @@ public slots:
|
||||||
QMenu* m_pMenuWindow;
|
QMenu* m_pMenuWindow;
|
||||||
QMenu* m_pMenuHelp;
|
QMenu* m_pMenuHelp;
|
||||||
QAbstractButton* m_pCancelButton;
|
QAbstractButton* m_pCancelButton;
|
||||||
|
TrayIcon m_trayIcon;
|
||||||
qRuningState m_ExpectedRunningState;
|
qRuningState m_ExpectedRunningState;
|
||||||
QMutex m_StopDesktopMutex;
|
QMutex m_StopDesktopMutex;
|
||||||
SslCertificate* m_pSslCertificate;
|
SslCertificate* m_pSslCertificate;
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,14 @@ class ScreenSetupView : public QTableView
|
||||||
ScreenSetupModel* model() const;
|
ScreenSetupModel* model() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mouseDoubleClickEvent(QMouseEvent*);
|
void mouseDoubleClickEvent(QMouseEvent*) override;
|
||||||
void setTableSize();
|
void setTableSize();
|
||||||
void resizeEvent(QResizeEvent*);
|
void resizeEvent(QResizeEvent*) override;
|
||||||
void dragEnterEvent(QDragEnterEvent* event);
|
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||||
void dragMoveEvent(QDragMoveEvent* event);
|
void dragMoveEvent(QDragMoveEvent* event) override;
|
||||||
void startDrag(Qt::DropActions supportedActions);
|
void startDrag(Qt::DropActions supportedActions) override;
|
||||||
QStyleOptionViewItem viewOptions() const;
|
QStyleOptionViewItem viewOptions() const override;
|
||||||
void scrollTo(const QModelIndex&, ScrollHint) {}
|
void scrollTo(const QModelIndex&, ScrollHint) override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
19
src/gui/src/TrayIcon.cpp
Normal file
19
src/gui/src/TrayIcon.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "TrayIcon.h"
|
||||||
|
|
||||||
|
void TrayIcon::tryCreate() const
|
||||||
|
{
|
||||||
|
QSystemTrayIcon trayIcon; // by creating a new tray icon, we actually make the DBus implementation refresh the connection (DBus)
|
||||||
|
trayIcon.hide(); // we ony hide it in order for the compiler to not optimise-out the object (make some use of it)
|
||||||
|
if (QSystemTrayIcon::isSystemTrayAvailable()) { // this ends up calling the underlying DBus connection (on DBus)
|
||||||
|
m_pTrayIcon->show();
|
||||||
|
m_connector(m_pTrayIcon.get(), SIGNAL(activated(QSystemTrayIcon::ActivationReason)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QTimer::singleShot(2500, this, &TrayIcon::tryCreate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrayIcon::set(const QIcon& icon) const
|
||||||
|
{
|
||||||
|
m_pTrayIcon->setIcon(icon);
|
||||||
|
}
|
||||||
45
src/gui/src/TrayIcon.h
Normal file
45
src/gui/src/TrayIcon.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#pragma once
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QSystemTrayIcon>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class TrayIcon : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
using TConnector = std::function<void(QObject const *, const char *)>;
|
||||||
|
|
||||||
|
template<typename TActionContainer>
|
||||||
|
void create(TActionContainer const &actionContainer, TConnector const &connector)
|
||||||
|
{
|
||||||
|
m_connector = connector;
|
||||||
|
m_pTrayIconMenu = std::make_unique<QMenu>();
|
||||||
|
|
||||||
|
for (auto action: actionContainer) {
|
||||||
|
if (action) {
|
||||||
|
m_pTrayIconMenu->addAction(action);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_pTrayIconMenu->addSeparator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pTrayIcon = std::make_unique<QSystemTrayIcon>();
|
||||||
|
m_pTrayIcon->setContextMenu(m_pTrayIconMenu.get());
|
||||||
|
m_pTrayIcon->setToolTip("Synergy");
|
||||||
|
|
||||||
|
tryCreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tryCreate() const;
|
||||||
|
|
||||||
|
void set(const QIcon& icon) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<QSystemTrayIcon> m_pTrayIcon {};
|
||||||
|
std::unique_ptr<QMenu> m_pTrayIconMenu {};
|
||||||
|
TConnector m_connector;
|
||||||
|
};
|
||||||
Loading…
Reference in a new issue