From 4e05453ddb96db78f1b326b86baa0b6111729218 Mon Sep 17 00:00:00 2001 From: startx2017 Date: Sat, 6 Jul 2019 09:11:41 -0400 Subject: [PATCH] add tools to systray menu #37 --- src/fstats/fstats.qrc | 1 + src/fstats/main.cpp | 33 ++++++++++++++------ src/fstats/resources/fstats-minimal.png | Bin 0 -> 5061 bytes src/fstats/stats_dialog.cpp | 39 ++++++++++++++++++++++++ src/fstats/stats_dialog.h | 11 +++++++ 5 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 src/fstats/resources/fstats-minimal.png diff --git a/src/fstats/fstats.qrc b/src/fstats/fstats.qrc index e297cb4..c51eca1 100644 --- a/src/fstats/fstats.qrc +++ b/src/fstats/fstats.qrc @@ -1,5 +1,6 @@ resources/fstats.png + resources/fstats-minimal.png diff --git a/src/fstats/main.cpp b/src/fstats/main.cpp index a1a55cb..6355d40 100644 --- a/src/fstats/main.cpp +++ b/src/fstats/main.cpp @@ -56,11 +56,11 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Error: invalid option\n"); usage(); return 1; - } + } } #if QT_VERSION >= 0x050000 - struct stat s; + struct stat s; // test run time dependencies - print warning and continue program QString ppath = QLibraryInfo::location(QLibraryInfo::PluginsPath); ppath += "/imageformats/libqsvg.so"; @@ -69,22 +69,37 @@ int main(int argc, char *argv[]) { svg_not_found = 1; } #endif - + // test run time dependencies - exit if (!which("firejail")) { fprintf(stderr, "Error: firejail package not found, please install it!\n"); exit(1); } - + // create firetools config directory if it doesn't exist create_config_directory(); - + // initialize resources Q_INIT_RESOURCE(fstats); QApplication app(argc, argv); StatsDialog sd; - + sd.show(); + + // Configure system tray + QSystemTrayIcon icon(QIcon(":resources/fstats-minimal.png")); + icon.show(); + icon.setToolTip("Firetools (click to open)"); + QMenu *trayIconMenu = new QMenu(&sd); + trayIconMenu->addAction(sd.minimizeAction); + trayIconMenu->addAction(sd.restoreAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(sd.quitAction); + icon.setContextMenu(trayIconMenu); + icon.connect(&icon, SIGNAL(activated(QSystemTrayIcon: :ActivationReason)), &sd, SLOT(trayActivated(QSystemTrayIcon: :ActivationReason))); + + + // direct all errror to /dev/null to work around this qt bug: // https://bugreports.qt.io/browse/QTBUG-43270 FILE *rv = NULL; @@ -92,11 +107,11 @@ int main(int argc, char *argv[]) { rv = freopen( "/dev/null", "w", stderr ); (void) rv; } - + // start application - int tmp = sd.exec(); + int tmp = app.exec(); (void) tmp; - + if (rv) fclose(rv); } diff --git a/src/fstats/resources/fstats-minimal.png b/src/fstats/resources/fstats-minimal.png new file mode 100644 index 0000000000000000000000000000000000000000..e053b365ce526bb51ed038f6eaa6a4cad5f45422 GIT binary patch literal 5061 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 +} + +void StatsDialog::trayActivated(QSystemTrayIcon::ActivationReason reason) { + if (reason == QSystemTrayIcon::Context) + return; + if (reason == QSystemTrayIcon::DoubleClick) + return; + if (reason == QSystemTrayIcon::MiddleClick) + return; + + if (isVisible()) { + hide(); +// stats_->hide(); + } + else { + show(); +// stats_->hide(); + } +} + +void StatsDialog::createTrayActions() { + minimizeAction = new QAction(tr("Mi&nimize"), this); + connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide())); +// connect(minimizeAction, SIGNAL(triggered()), stats_, SLOT(hide())); + + restoreAction = new QAction(tr("&Restore"), this); + connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal())); +// connect(restoreAction, SIGNAL(triggered()), stats_, SLOT(show())); + + quitAction = new QAction(tr("&Quit"), this); + connect(quitAction, SIGNAL(triggered()), this, SLOT(main_quit())); +} + QString StatsDialog::header() { QString msg; if (mode_ == MODE_TOP) { diff --git a/src/fstats/stats_dialog.h b/src/fstats/stats_dialog.h index c9c2e88..fe57020 100644 --- a/src/fstats/stats_dialog.h +++ b/src/fstats/stats_dialog.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "fstats.h" class QTextBrowser; @@ -37,9 +39,13 @@ Q_OBJECT StatsDialog(); ~StatsDialog(); +private slots: + void main_quit(); + public slots: void cycleReady(); void anchorClicked(const QUrl & link); + void trayActivated(QSystemTrayIcon::ActivationReason); private: QString header(); @@ -52,6 +58,7 @@ public slots: void updateCaps(); void updateFirewall(); void cleanStorage(); + void createTrayActions(); private: QTextBrowser *procView_; @@ -94,6 +101,10 @@ public slots: QString storage_seccomp_; QString storage_intro_; QString storage_network_; +public: + QAction *minimizeAction; + QAction *restoreAction; + QAction *quitAction; };