Browse Source

Merge pull request #15829 from Chocobo1/trayIcon

Simplify tray icon related code
adaptive-webui-19844
Chocobo1 3 years ago committed by GitHub
parent
commit
00f6bb7c82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/ci_windows.yaml
  2. 4
      src/base/preferences.cpp
  3. 4
      src/base/preferences.h
  4. 213
      src/gui/mainwindow.cpp
  5. 15
      src/gui/mainwindow.h
  6. 11
      src/gui/optionsdialog.cpp
  7. 2
      src/gui/optionsdialog.h
  8. 30
      src/gui/uithememanager.cpp
  9. 5
      src/gui/uithememanager.h

2
.github/workflows/ci_windows.yaml

@ -12,7 +12,7 @@ jobs: @@ -12,7 +12,7 @@ jobs:
libt_version: ["2.0.5", "1.2.15"]
env:
boost_path: "${{ github.workspace }}/boost"
boost_path: "${{ github.workspace }}/../boost"
libtorrent_path: "${{ github.workspace }}/libtorrent"
steps:

4
src/base/preferences.cpp

@ -210,12 +210,12 @@ void Preferences::setHideZeroComboValues(const int n) @@ -210,12 +210,12 @@ void Preferences::setHideZeroComboValues(const int n)
// In Mac OS X the dock is sufficient for our needs so we disable the sys tray functionality.
// See extensive discussion in https://github.com/qbittorrent/qBittorrent/pull/3018
#ifndef Q_OS_MACOS
bool Preferences::systrayIntegration() const
bool Preferences::systemTrayEnabled() const
{
return value("Preferences/General/SystrayEnabled", true);
}
void Preferences::setSystrayIntegration(const bool enabled)
void Preferences::setSystemTrayEnabled(const bool enabled)
{
setValue("Preferences/General/SystrayEnabled", enabled);
}

4
src/base/preferences.h

@ -315,8 +315,8 @@ public: @@ -315,8 +315,8 @@ public:
bool confirmRemoveAllTags() const;
void setConfirmRemoveAllTags(bool enabled);
#ifndef Q_OS_MACOS
bool systrayIntegration() const;
void setSystrayIntegration(bool enabled);
bool systemTrayEnabled() const;
void setSystemTrayEnabled(bool enabled);
bool minimizeToTrayNotified() const;
void setMinimizeToTrayNotified(bool b);
bool minimizeToTray() const;

213
src/gui/mainwindow.cpp

@ -177,8 +177,14 @@ MainWindow::MainWindow(QWidget *parent) @@ -177,8 +177,14 @@ MainWindow::MainWindow(QWidget *parent)
lockMenu->addAction(tr("&Set Password"), this, &MainWindow::defineUILockPassword);
lockMenu->addAction(tr("&Clear Password"), this, &MainWindow::clearUILockPassword);
m_ui->actionLock->setMenu(lockMenu);
connect(this, &MainWindow::systemTrayIconCreated, this, [this]()
{
m_ui->actionLock->setVisible(true);
});
// Creating Bittorrent session
updateAltSpeedsBtn(BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled());
connect(BitTorrent::Session::instance(), &BitTorrent::Session::fullDiskError, this, &MainWindow::fullDiskError);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::loadTorrentFailed, this, &MainWindow::addTorrentFailed);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentAdded,this, &MainWindow::torrentNew);
@ -319,7 +325,7 @@ MainWindow::MainWindow(QWidget *parent) @@ -319,7 +325,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(m_preventTimer, &QTimer::timeout, this, &MainWindow::updatePowerManagementState);
// Configure BT session according to options
loadPreferences(false);
loadPreferences();
connect(BitTorrent::Session::instance(), &BitTorrent::Session::statsUpdated, this, &MainWindow::reloadSessionStats);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentsUpdated, this, &MainWindow::reloadTorrentStats);
@ -380,7 +386,19 @@ MainWindow::MainWindow(QWidget *parent) @@ -380,7 +386,19 @@ MainWindow::MainWindow(QWidget *parent)
// Load Window state and sizes
readSettings();
#ifndef Q_OS_MACOS
#ifdef Q_OS_MACOS
// Make sure the Window is visible if we don't have a tray icon
if (pref->startMinimized())
{
showMinimized();
}
else
{
show();
activateWindow();
raise();
}
#else
if (m_systrayIcon)
{
if (!(pref->startMinimized() || m_uiLocked))
@ -405,7 +423,6 @@ MainWindow::MainWindow(QWidget *parent) @@ -405,7 +423,6 @@ MainWindow::MainWindow(QWidget *parent)
}
else
{
#endif
// Make sure the Window is visible if we don't have a tray icon
if (pref->startMinimized())
{
@ -417,7 +434,6 @@ MainWindow::MainWindow(QWidget *parent) @@ -417,7 +434,6 @@ MainWindow::MainWindow(QWidget *parent)
activateWindow();
raise();
}
#ifndef Q_OS_MACOS
}
#endif
@ -456,7 +472,8 @@ MainWindow::MainWindow(QWidget *parent) @@ -456,7 +472,8 @@ MainWindow::MainWindow(QWidget *parent)
#endif
#ifdef Q_OS_MACOS
setupDockClickHandler();
trayIconMenu()->setAsDockMenu();
createTrayIconMenu();
m_trayIconMenu->setAsDockMenu();
#endif
}
@ -785,10 +802,6 @@ void MainWindow::cleanup() @@ -785,10 +802,6 @@ void MainWindow::cleanup()
delete m_rssWidget;
delete m_executableWatcher;
#ifndef Q_OS_MACOS
if (m_systrayCreator)
m_systrayCreator->stop();
#endif
m_preventTimer->stop();
@ -1218,15 +1231,15 @@ void MainWindow::closeEvent(QCloseEvent *e) @@ -1218,15 +1231,15 @@ void MainWindow::closeEvent(QCloseEvent *e)
}
}
// abort search if any
delete m_searchWidget;
hide();
// Disable some UI to prevent user interactions
#ifndef Q_OS_MACOS
// Hide tray icon
if (m_systrayIcon)
m_systrayIcon->hide();
{
m_systrayIcon->setToolTip(tr("qBittorrent is shutting down..."));
m_trayIconMenu->setEnabled(false);
}
#endif
// Accept exit
e->accept();
qApp->exit();
@ -1469,50 +1482,32 @@ void MainWindow::showStatusBar(bool show) @@ -1469,50 +1482,32 @@ void MainWindow::showStatusBar(bool show)
}
}
void MainWindow::loadPreferences(const bool configureSession)
void MainWindow::loadPreferences()
{
const Preferences *const pref = Preferences::instance();
#ifdef Q_OS_MACOS
Q_UNUSED(configureSession);
#else
const bool newSystrayIntegration = pref->systrayIntegration();
m_ui->actionLock->setVisible(newSystrayIntegration);
if (newSystrayIntegration != (m_systrayIcon != nullptr))
const Preferences *pref = Preferences::instance();
#ifndef Q_OS_MACOS
// system tray icon
if (pref->systemTrayEnabled())
{
if (newSystrayIntegration)
if (m_systrayIcon)
{
// create the trayicon
if (!QSystemTrayIcon::isSystemTrayAvailable())
{
if (!configureSession)
{ // Program startup
m_systrayCreator = new QTimer(this);
connect(m_systrayCreator.data(), &QTimer::timeout, this, &MainWindow::createSystrayDelayed);
m_systrayCreator->setSingleShot(true);
m_systrayCreator->start(2000);
qDebug("Info: System tray is unavailable, trying again later.");
}
else
{
qDebug("Warning: System tray is unavailable.");
}
}
else
{
createTrayIcon();
}
// Reload systray icon
m_systrayIcon->setIcon(UIThemeManager::instance()->getSystrayIcon());
}
else
{
// Destroy trayicon
delete m_systrayIcon;
delete m_trayIconMenu;
createTrayIcon(20);
}
}
// Reload systray icon
if (newSystrayIntegration && m_systrayIcon)
m_systrayIcon->setIcon(getSystrayIcon());
else
{
delete m_systrayIcon;
delete m_trayIconMenu;
m_ui->actionLock->setVisible(false);
}
#endif
// General
if (pref->isToolbarDisplayed())
{
@ -1621,7 +1616,7 @@ void MainWindow::reloadSessionStats() @@ -1621,7 +1616,7 @@ void MainWindow::reloadSessionStats()
#else
if (m_systrayIcon)
{
const QString toolTip = QString::fromLatin1("%1\n%2").arg(
const auto toolTip = QString::fromLatin1("%1\n%2").arg(
tr("DL speed: %1", "e.g: Download speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadDownloadRate, true))
, tr("UP speed: %1", "e.g: Upload speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadUploadRate, true)));
m_systrayIcon->setToolTip(toolTip); // tray icon
@ -1705,86 +1700,82 @@ void MainWindow::downloadFromURLList(const QStringList &urlList) @@ -1705,86 +1700,82 @@ void MainWindow::downloadFromURLList(const QStringList &urlList)
*****************************************************/
#ifndef Q_OS_MACOS
void MainWindow::createSystrayDelayed()
void MainWindow::createTrayIcon(const int retries)
{
static int timeout = 20;
if (m_systrayIcon)
return;
if (QSystemTrayIcon::isSystemTrayAvailable())
{
// Ok, systray integration is now supported
// Create systray icon
createTrayIcon();
delete m_systrayCreator;
m_systrayIcon = new QSystemTrayIcon(UIThemeManager::instance()->getSystrayIcon(), this);
createTrayIconMenu();
m_systrayIcon->setContextMenu(m_trayIconMenu);
connect(m_systrayIcon, &QSystemTrayIcon::activated, this, &MainWindow::toggleVisibility);
connect(m_systrayIcon, &QSystemTrayIcon::messageClicked, this, &MainWindow::balloonClicked);
m_systrayIcon->show();
emit systemTrayIconCreated();
}
else
{
if (timeout)
if (retries > 0)
{
// Retry a bit later
m_systrayCreator->start(2000);
--timeout;
LogMsg("System tray icon is not available, retrying...", Log::WARNING);
QTimer::singleShot(std::chrono::seconds(2), this, [this, retries]()
{
if (Preferences::instance()->systemTrayEnabled())
createTrayIcon(retries - 1);
});
}
else
{
// Timed out, apparently system really does not
// support systray icon
delete m_systrayCreator;
// Disable it in program preferences to
// avoid trying at each startup
Preferences::instance()->setSystrayIntegration(false);
LogMsg("System tray icon is still not available after retries. Disabling it.", Log::WARNING);
Preferences::instance()->setSystemTrayEnabled(false);
}
}
}
void MainWindow::updateTrayIconMenu()
{
m_ui->actionToggleVisibility->setText(isVisible() ? tr("Hide") : tr("Show"));
}
void MainWindow::createTrayIcon()
{
// Tray icon
m_systrayIcon = new QSystemTrayIcon(getSystrayIcon(), this);
m_systrayIcon->setContextMenu(trayIconMenu());
connect(m_systrayIcon.data(), &QSystemTrayIcon::messageClicked, this, &MainWindow::balloonClicked);
// End of Icon Menu
connect(m_systrayIcon.data(), &QSystemTrayIcon::activated, this, &MainWindow::toggleVisibility);
m_systrayIcon->show();
}
#endif // Q_OS_MACOS
QMenu *MainWindow::trayIconMenu()
void MainWindow::createTrayIconMenu()
{
if (m_trayIconMenu) return m_trayIconMenu;
if (m_trayIconMenu)
return;
m_trayIconMenu = new QMenu(this);
#ifndef Q_OS_MACOS
connect(m_trayIconMenu.data(), &QMenu::aboutToShow, this, &MainWindow::updateTrayIconMenu);
connect(m_trayIconMenu, &QMenu::aboutToShow, this, [this]()
{
m_ui->actionToggleVisibility->setText(isVisible() ? tr("Hide") : tr("Show"));
});
m_trayIconMenu->addAction(m_ui->actionToggleVisibility);
m_trayIconMenu->addSeparator();
#endif
m_trayIconMenu->addAction(m_ui->actionOpen);
m_trayIconMenu->addAction(m_ui->actionDownloadFromURL);
m_trayIconMenu->addSeparator();
const bool isAltBWEnabled = BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled();
updateAltSpeedsBtn(isAltBWEnabled);
m_ui->actionUseAlternativeSpeedLimits->setChecked(isAltBWEnabled);
m_trayIconMenu->addAction(m_ui->actionUseAlternativeSpeedLimits);
m_trayIconMenu->addAction(m_ui->actionSetGlobalSpeedLimits);
m_trayIconMenu->addSeparator();
m_trayIconMenu->addAction(m_ui->actionStartAll);
m_trayIconMenu->addAction(m_ui->actionPauseAll);
#ifndef Q_OS_MACOS
m_trayIconMenu->addSeparator();
m_trayIconMenu->addAction(m_ui->actionExit);
#endif
if (m_uiLocked)
m_trayIconMenu->setEnabled(false);
return m_trayIconMenu;
}
void MainWindow::updateAltSpeedsBtn(bool alternative)
void MainWindow::updateAltSpeedsBtn(const bool alternative)
{
m_ui->actionUseAlternativeSpeedLimits->setChecked(alternative);
}
@ -2072,42 +2063,6 @@ void MainWindow::updatePowerManagementState() @@ -2072,42 +2063,6 @@ void MainWindow::updatePowerManagementState()
m_pwr->setActivityState(inhibitSuspend);
}
#ifndef Q_OS_MACOS
QIcon MainWindow::getSystrayIcon() const
{
const TrayIcon::Style style = Preferences::instance()->trayIconStyle();
// on Linux we use theme icons, and icons from resources everywhere else
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
switch (style)
{
case TrayIcon::Style::Normal:
return QIcon::fromTheme(QLatin1String("qbittorrent-tray"));
case TrayIcon::Style::MonoDark:
return QIcon::fromTheme(QLatin1String("qbittorrent-tray-dark"));
case TrayIcon::Style::MonoLight:
return QIcon::fromTheme(QLatin1String("qbittorrent-tray-light"));
default:
break;
}
#else
switch (style)
{
case TrayIcon::Style::Normal:
return UIThemeManager::instance()->getIcon(QLatin1String("qbittorrent-tray"));
case TrayIcon::Style::MonoDark:
return UIThemeManager::instance()->getIcon(QLatin1String("qbittorrent-tray-dark"));
case TrayIcon::Style::MonoLight:
return UIThemeManager::instance()->getIcon(QLatin1String("qbittorrent-tray-light"));
default:
break;
}
#endif
// As a failsafe in case the enum is invalid
return UIThemeManager::instance()->getIcon(QLatin1String("qbittorrent-tray"));
}
#endif // Q_OS_MACOS
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
void MainWindow::checkProgramUpdate(const bool invokedByUser)
{

15
src/gui/mainwindow.h

@ -82,7 +82,6 @@ public: @@ -82,7 +82,6 @@ public:
QWidget *currentTabWidget() const;
TransferListWidget *transferListWidget() const;
PropertiesWidget *propertiesWidget() const;
QMenu *trayIconMenu();
// ExecutionLog properties
bool isExecutionLogEnabled() const;
@ -109,6 +108,9 @@ public: @@ -109,6 +108,9 @@ public:
void showNotificationBalloon(const QString &title, const QString &msg) const;
signals:
void systemTrayIconCreated();
private slots:
void showFilterContextMenu(const QPoint &);
void balloonClicked();
@ -132,7 +134,7 @@ private slots: @@ -132,7 +134,7 @@ private slots:
void focusSearchFilter();
void reloadSessionStats();
void reloadTorrentStats(const QVector<BitTorrent::Torrent *> &torrents);
void loadPreferences(bool configureSession = true);
void loadPreferences();
void addTorrentFailed(const QString &error) const;
void torrentNew(BitTorrent::Torrent *const torrent) const;
void finishedTorrent(BitTorrent::Torrent *const torrent) const;
@ -189,16 +191,14 @@ private slots: @@ -189,16 +191,14 @@ private slots:
void on_actionCloseWindow_triggered();
#else
void toggleVisibility(const QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Trigger);
void createSystrayDelayed();
void updateTrayIconMenu();
#endif
private:
void createTrayIconMenu();
#ifdef Q_OS_MACOS
void setupDockClickHandler();
#else
void createTrayIcon();
QIcon getSystrayIcon() const;
void createTrayIcon(int retries);
#endif
#ifdef Q_OS_WIN
void installPython();
@ -227,11 +227,12 @@ private: @@ -227,11 +227,12 @@ private:
QPointer<StatsDialog> m_statsDlg;
QPointer<TorrentCreatorDialog> m_createTorrentDlg;
QPointer<DownloadFromURLDialog> m_downloadFromURLDialog;
#ifndef Q_OS_MACOS
QPointer<QSystemTrayIcon> m_systrayIcon;
QPointer<QTimer> m_systrayCreator;
#endif
QPointer<QMenu> m_trayIconMenu;
TransferListWidget *m_transferListWidget;
TransferListFiltersWidget *m_transferListFiltersWidget;
PropertiesWidget *m_propertiesWidget;

11
src/gui/optionsdialog.cpp

@ -677,7 +677,7 @@ void OptionsDialog::saveOptions() @@ -677,7 +677,7 @@ void OptionsDialog::saveOptions()
pref->setHideZeroValues(m_ui->checkHideZero->isChecked());
pref->setHideZeroComboValues(m_ui->comboHideZero->currentIndex());
#ifndef Q_OS_MACOS
pref->setSystrayIntegration(systrayIntegration());
pref->setSystemTrayEnabled(systemTrayEnabled());
pref->setTrayIconStyle(TrayIcon::Style(m_ui->comboTrayIcon->currentIndex()));
pref->setCloseToTray(closeToTray());
pref->setMinimizeToTray(minimizeToTray());
@ -936,7 +936,7 @@ void OptionsDialog::loadOptions() @@ -936,7 +936,7 @@ void OptionsDialog::loadOptions()
m_ui->checkProgramAutoExitConfirm->setChecked(!pref->dontConfirmAutoExit());
#ifndef Q_OS_MACOS
m_ui->checkShowSystray->setChecked(pref->systrayIntegration());
m_ui->checkShowSystray->setChecked(pref->systemTrayEnabled());
if (m_ui->checkShowSystray->isChecked())
{
m_ui->checkMinimizeToSysTray->setChecked(pref->minimizeToTray());
@ -1346,10 +1346,11 @@ bool OptionsDialog::startMinimized() const @@ -1346,10 +1346,11 @@ bool OptionsDialog::startMinimized() const
}
#ifndef Q_OS_MACOS
bool OptionsDialog::systrayIntegration() const
bool OptionsDialog::systemTrayEnabled() const
{
if (!QSystemTrayIcon::isSystemTrayAvailable()) return false;
return m_ui->checkShowSystray->isChecked();
return QSystemTrayIcon::isSystemTrayAvailable()
? m_ui->checkShowSystray->isChecked()
: false;
}
bool OptionsDialog::minimizeToTray() const

2
src/gui/optionsdialog.h

@ -122,7 +122,7 @@ private: @@ -122,7 +122,7 @@ private:
// General options
QString getLocale() const;
#ifndef Q_OS_MACOS
bool systrayIntegration() const;
bool systemTrayEnabled() const;
bool minimizeToTray() const;
bool closeToTray() const;
#endif

30
src/gui/uithememanager.cpp

@ -157,6 +157,36 @@ QColor UIThemeManager::getColor(const QString &id, const QColor &defaultColor) c @@ -157,6 +157,36 @@ QColor UIThemeManager::getColor(const QString &id, const QColor &defaultColor) c
return m_colors.value(id, defaultColor);
}
#ifndef Q_OS_MACOS
QIcon UIThemeManager::getSystrayIcon() const
{
const TrayIcon::Style style = Preferences::instance()->trayIconStyle();
switch (style)
{
#if defined(Q_OS_UNIX)
case TrayIcon::Style::Normal:
return QIcon::fromTheme(QLatin1String("qbittorrent-tray"));
case TrayIcon::Style::MonoDark:
return QIcon::fromTheme(QLatin1String("qbittorrent-tray-dark"));
case TrayIcon::Style::MonoLight:
return QIcon::fromTheme(QLatin1String("qbittorrent-tray-light"));
#else
case TrayIcon::Style::Normal:
return getIcon(QLatin1String("qbittorrent-tray"));
case TrayIcon::Style::MonoDark:
return getIcon(QLatin1String("qbittorrent-tray-dark"));
case TrayIcon::Style::MonoLight:
return getIcon(QLatin1String("qbittorrent-tray-light"));
#endif
default:
break;
}
// As a failsafe in case the enum is invalid
return getIcon(QLatin1String("qbittorrent-tray"));
}
#endif
QString UIThemeManager::getIconPath(const QString &iconId) const
{
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))

5
src/gui/uithememanager.h

@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
#pragma once
#include <QtGlobal>
#include <QColor>
#include <QHash>
#include <QIcon>
@ -51,6 +52,10 @@ public: @@ -51,6 +52,10 @@ public:
QColor getColor(const QString &id, const QColor &defaultColor) const;
#ifndef Q_OS_MACOS
QIcon getSystrayIcon() const;
#endif
private:
UIThemeManager(); // singleton class
QString getIconPathFromResources(const QString &iconId, const QString &fallback = {}) const;

Loading…
Cancel
Save