Improve systemd integration
* Allow using systemd unit status to better handle reconnect attempts to local instance * Misc adjustments
This commit is contained in:
parent
1c2c77b4ec
commit
3cadd8cbcb
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ struct Launcher
|
|||
struct Systemd
|
||||
{
|
||||
QString syncthingUnit = QStringLiteral("syncthing.service");
|
||||
bool showButton = true;
|
||||
bool showButton = false;
|
||||
bool considerForReconnect = false;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,7 +15,23 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show start/stop button on tray for local instance when specified unit available</string>
|
||||
<string>Show start/stop button on tray for local instance when systemd is available</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="considerForReconnectCheckBox">
|
||||
<property name="text">
|
||||
<string>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</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -50,20 +66,7 @@
|
|||
<item row="0" column="1">
|
||||
<widget class="Widgets::ClearLineEdit" name="syncthingUnitLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Line" name="line1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="descriptionLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
|
@ -76,7 +79,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="descriptionHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="descriptionValueLabel">
|
||||
|
@ -99,7 +102,7 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
|
@ -112,7 +115,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="statusHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="statusIndicator" native="true">
|
||||
|
@ -176,7 +179,7 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="unitFileStateLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
|
@ -189,7 +192,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="unitFileStateHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="enabledIndicator" native="true">
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue