diff --git a/connector/syncthingservice.cpp b/connector/syncthingservice.cpp
index 23a9ef5..a73e3e0 100644
--- a/connector/syncthingservice.cpp
+++ b/connector/syncthingservice.cpp
@@ -61,6 +61,8 @@ SyncthingService::SyncthingService(QObject *parent) :
connect(s_manager, &OrgFreedesktopSystemd1ManagerInterface::UnitNew, this, &SyncthingService::handleUnitAdded);
connect(s_manager, &OrgFreedesktopSystemd1ManagerInterface::UnitRemoved, this, &SyncthingService::handleUnitRemoved);
m_serviceWatcher = new QDBusServiceWatcher(s_manager->service(), s_manager->connection());
+ connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &SyncthingService::handleServiceRegisteredChanged);
+ connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &SyncthingService::handleServiceRegisteredChanged);
}
void SyncthingService::setUnitName(const QString &unitName)
@@ -91,18 +93,18 @@ bool SyncthingService::isUnitAvailable() const
void SyncthingService::setRunning(bool running)
{
if(running) {
- registerErrorHandler(s_manager->StartUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("starting unit"));
+ registerErrorHandler(s_manager->StartUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("start unit"));
} else {
- registerErrorHandler(s_manager->StopUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("stopping unit"));
+ registerErrorHandler(s_manager->StopUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("stop unit"));
}
}
void SyncthingService::setEnabled(bool enabled)
{
if(enabled) {
- registerErrorHandler(s_manager->EnableUnitFiles(QStringList(m_unitName), false, true), QT_TR_NOOP_UTF8("enabling unit"));
+ registerErrorHandler(s_manager->EnableUnitFiles(QStringList(m_unitName), false, true), QT_TR_NOOP_UTF8("enable unit"));
} else {
- registerErrorHandler(s_manager->DisableUnitFiles(QStringList(m_unitName), false), QT_TR_NOOP_UTF8("disabling unit"));
+ registerErrorHandler(s_manager->DisableUnitFiles(QStringList(m_unitName), false), QT_TR_NOOP_UTF8("disable unit"));
}
}
@@ -164,6 +166,13 @@ void SyncthingService::handleError(const char *context, QDBusPendingCallWatcher
}
}
+void SyncthingService::handleServiceRegisteredChanged(const QString &service)
+{
+ if(service == s_manager->service()) {
+ emit systemdAvailableChanged(s_manager->isValid());
+ }
+}
+
bool SyncthingService::handlePropertyChanged(QString &variable, void (SyncthingService::*signal)(const QString &), const QString &propertyName, const QVariantMap &changedProperties, const QStringList &invalidatedProperties)
{
const QVariant valueVariant(changedProperties[propertyName]);
diff --git a/connector/syncthingservice.h b/connector/syncthingservice.h
index bc42fed..0657376 100644
--- a/connector/syncthingservice.h
+++ b/connector/syncthingservice.h
@@ -81,6 +81,7 @@ private Q_SLOTS:
void handleUnitGet(QDBusPendingCallWatcher *watcher);
void handlePropertiesChanged(const QString &interface, const QVariantMap &changedProperties, const QStringList &invalidatedProperties);
void handleError(const char *error, QDBusPendingCallWatcher *watcher);
+ void handleServiceRegisteredChanged(const QString &service);
void setUnit(const QDBusObjectPath &objectPath);
void setProperties(const QString &activeState, const QString &subState, const QString &unitFileState, const QString &description);
diff --git a/tray/application/main.cpp b/tray/application/main.cpp
index f952570..4c8cb9f 100644
--- a/tray/application/main.cpp
+++ b/tray/application/main.cpp
@@ -38,7 +38,7 @@ void handleSystemdServiceError(const QString &context, const QString &name, cons
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(QCoreApplication::translate("main", "Unable to ") + context);
- msgBox.setInformativeText(name % QStringLiteral(": ") % message);
+ msgBox.setInformativeText(name % QStringLiteral(":\n") % message);
msgBox.exec();
}
#endif
diff --git a/tray/application/settings.cpp b/tray/application/settings.cpp
index b932833..77dcc44 100644
--- a/tray/application/settings.cpp
+++ b/tray/application/settings.cpp
@@ -100,6 +100,7 @@ void restore()
auto &systemd = v.systemd;
systemd.syncthingUnit = settings.value(QStringLiteral("syncthingUnit"), systemd.syncthingUnit).toString();
systemd.showButton = settings.value(QStringLiteral("showButton"), systemd.showButton).toBool();
+ systemd.considerForReconnect = settings.value(QStringLiteral("considerForReconnect"), systemd.considerForReconnect).toBool();
#endif
settings.endGroup();
@@ -167,6 +168,7 @@ void save()
const auto &systemd = v.systemd;
settings.setValue(QStringLiteral("syncthingUnit"), systemd.syncthingUnit);
settings.setValue(QStringLiteral("showButton"), systemd.showButton);
+ settings.setValue(QStringLiteral("considerForReconnect"), systemd.considerForReconnect);
#endif
settings.endGroup();
diff --git a/tray/application/settings.h b/tray/application/settings.h
index 819a395..7aeb6ff 100644
--- a/tray/application/settings.h
+++ b/tray/application/settings.h
@@ -66,7 +66,8 @@ struct Launcher
struct Systemd
{
QString syncthingUnit = QStringLiteral("syncthing.service");
- bool showButton = true;
+ bool showButton = false;
+ bool considerForReconnect = false;
};
#endif
diff --git a/tray/gui/settingsdialog.cpp b/tray/gui/settingsdialog.cpp
index 20b593b..c308156 100644
--- a/tray/gui/settingsdialog.cpp
+++ b/tray/gui/settingsdialog.cpp
@@ -596,6 +596,7 @@ bool SystemdOptionPage::apply()
auto &settings = values().systemd;
settings.syncthingUnit = ui()->syncthingUnitLineEdit->text();
settings.showButton = ui()->showButtonCheckBox->isChecked();
+ settings.considerForReconnect = ui()->considerForReconnectCheckBox->isChecked();
}
return true;
}
@@ -606,6 +607,7 @@ void SystemdOptionPage::reset()
const auto &settings = values().systemd;
ui()->syncthingUnitLineEdit->setText(settings.syncthingUnit);
ui()->showButtonCheckBox->setChecked(settings.showButton);
+ ui()->considerForReconnectCheckBox->setChecked(settings.considerForReconnect);
handleDescriptionChanged(m_service.description());
handleStatusChanged(m_service.activeState(), m_service.subState());
handleEnabledChanged(m_service.unitFileState());
@@ -614,7 +616,7 @@ void SystemdOptionPage::reset()
void SystemdOptionPage::handleDescriptionChanged(const QString &description)
{
- ui()->descriptionValueLabel->setText(description.isEmpty() ? QCoreApplication::translate("QtGui::SystemdOptionPage", "specified unit is unknown") : description);
+ ui()->descriptionValueLabel->setText(description.isEmpty() ? QCoreApplication::translate("QtGui::SystemdOptionPage", "specified unit is either inactive or doesn't exist") : description);
}
void setIndicatorColor(QWidget *indicator, const QColor &color)
@@ -642,7 +644,7 @@ void SystemdOptionPage::handleStatusChanged(const QString &activeState, const QS
? Colors::green(values().appearance.brightTextColors)
: Colors::red(values().appearance.brightTextColors))
);
- ui()->startPushButton->setVisible(!status.isEmpty() && !isRunning);
+ ui()->startPushButton->setVisible(!isRunning);
ui()->stopPushButton->setVisible(!status.isEmpty() && isRunning);
}
@@ -653,7 +655,7 @@ void SystemdOptionPage::handleEnabledChanged(const QString &unitFileState)
setIndicatorColor(ui()->enabledIndicator, isEnabled
? Colors::green(values().appearance.brightTextColors)
: Colors::gray(values().appearance.brightTextColors));
- ui()->enablePushButton->setVisible(!unitFileState.isEmpty() && !isEnabled);
+ ui()->enablePushButton->setVisible(!isEnabled);
ui()->disablePushButton->setVisible(!unitFileState.isEmpty() && isEnabled);
}
#endif
diff --git a/tray/gui/systemdoptionpage.ui b/tray/gui/systemdoptionpage.ui
index 6ac091e..0d5f419 100644
--- a/tray/gui/systemdoptionpage.ui
+++ b/tray/gui/systemdoptionpage.ui
@@ -15,7 +15,23 @@
- Show start/stop button on tray for local instance when specified unit available
+ Show start/stop button on tray for local instance when systemd is available
+
+
+
+ -
+
+
+ Consider systemd unit status for reconnect attempts to local instance
+ • Don't reconnect when unit not active/running
+ • Try to reconnect when unit becomes active/running
+
+
+
+ -
+
+
+ Qt::Horizontal
@@ -50,20 +66,7 @@
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::Horizontal
-
-
-
- -
+
-
@@ -76,7 +79,7 @@
- -
+
-
-
@@ -99,7 +102,7 @@
- -
+
-
@@ -112,7 +115,7 @@
- -
+
-
-
@@ -176,7 +179,7 @@
- -
+
-
@@ -189,7 +192,7 @@
- -
+
-
-
diff --git a/tray/gui/traywidget.cpp b/tray/gui/traywidget.cpp
index efed67a..4ba9edf 100644
--- a/tray/gui/traywidget.cpp
+++ b/tray/gui/traywidget.cpp
@@ -146,7 +146,8 @@ TrayWidget::TrayWidget(TrayMenu *parent) :
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
const SyncthingService &service = syncthingService();
connect(m_ui->startStopPushButton, &QPushButton::clicked, &service, &SyncthingService::toggleRunning);
- connect(&service, &SyncthingService::stateChanged, this, &TrayWidget::updateStartStopButton);
+ connect(&service, &SyncthingService::systemdAvailableChanged, this, &TrayWidget::handleSystemdStatusChanged);
+ connect(&service, &SyncthingService::stateChanged, this, &TrayWidget::handleSystemdStatusChanged);
#endif
}
@@ -385,7 +386,7 @@ void TrayWidget::applySettings()
// systemd
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
- instance->updateStartStopButton();
+ instance->handleSystemdStatusChanged();
#endif
// update visual appearance
@@ -493,25 +494,54 @@ void TrayWidget::updateTraffic()
}
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
-void TrayWidget::updateStartStopButton()
+void TrayWidget::handleSystemdStatusChanged()
{
const SyncthingService &service = syncthingService();
const Settings::Systemd &settings = Settings::values().systemd;
+ const bool serviceRelevant = service.isSystemdAvailable() && isLocal(QUrl(m_connection.syncthingUrl()));
- if(settings.showButton && service.isUnitAvailable() && m_selectedConnection && isLocal(QUrl(m_selectedConnection->syncthingUrl))) {
- m_ui->startStopPushButton->setVisible(true);
- if(service.isRunning()) {
- m_ui->startStopPushButton->setText(tr("Stop"));
- m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user stop ") + service.unitName());
- m_ui->startStopPushButton->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/process-stop.svg"))));
- } else {
- m_ui->startStopPushButton->setText(tr("Start"));
- m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user start ") + service.unitName());
- m_ui->startStopPushButton->setIcon(QIcon::fromTheme(QStringLiteral("system-run"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/system-run.svg"))));
+ if(serviceRelevant) {
+ const bool isRunning = service.isRunning();
+ if(settings.showButton) {
+ m_ui->startStopPushButton->setVisible(true);
+ if(isRunning) {
+ m_ui->startStopPushButton->setText(tr("Stop"));
+ m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user stop ") + service.unitName());
+ m_ui->startStopPushButton->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/process-stop.svg"))));
+ } else {
+ m_ui->startStopPushButton->setText(tr("Start"));
+ m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user start ") + service.unitName());
+ m_ui->startStopPushButton->setIcon(QIcon::fromTheme(QStringLiteral("system-run"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/system-run.svg"))));
+ }
}
- } else {
+ if(settings.considerForReconnect) {
+ if(isRunning && m_selectedConnection) {
+ // auto-reconnect might have been disabled when unit was inactive before, so re-enable it according current connection settings
+ m_connection.setAutoReconnectInterval(m_selectedConnection->reconnectInterval);
+ // and reconnect in 5 seconds (Syncthing needs a few seconds till the API becomes available)
+ QTimer::singleShot(5000, Qt::VeryCoarseTimer, this, &TrayWidget::connectIfServiceRunning);
+ } else {
+ // disable auto-reconnect if unit isn't running
+ m_connection.setAutoReconnectInterval(0);
+ }
+ }
+ }
+
+ if(!settings.showButton || !serviceRelevant) {
m_ui->startStopPushButton->setVisible(false);
}
+ if((!settings.considerForReconnect || !serviceRelevant) && m_selectedConnection) {
+ m_connection.setAutoReconnectInterval(m_selectedConnection->reconnectInterval);
+ }
+}
+
+void TrayWidget::connectIfServiceRunning()
+{
+ if(Settings::values().systemd.considerForReconnect
+ && isLocal(QUrl(m_connection.syncthingUrl()))
+ && syncthingService().isRunning()) {
+ m_connection.connect();
+ }
}
#endif
@@ -538,7 +568,7 @@ void TrayWidget::handleConnectionSelected(QAction *connectionAction)
m_ui->connectionsPushButton->setText(m_selectedConnection->label);
m_connection.reconnect(*m_selectedConnection);
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
- updateStartStopButton();
+ handleSystemdStatusChanged();
#endif
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
if(m_webViewDlg) {
diff --git a/tray/gui/traywidget.h b/tray/gui/traywidget.h
index 5cdea8c..4427a9d 100644
--- a/tray/gui/traywidget.h
+++ b/tray/gui/traywidget.h
@@ -72,7 +72,8 @@ private slots:
void changeStatus();
void updateTraffic();
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
- void updateStartStopButton();
+ void handleSystemdStatusChanged();
+ void connectIfServiceRunning();
#endif
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
void handleWebViewDeleted();