Also consider sleep/standby as tolerable interruption

* Only supported when Logind is used
* Extension of b2325bf
* So notifications caused by Syncthing inavailability
  short after start or resume from standby can now be
  suppressed - at least when using Systemd/Logind
This commit is contained in:
Martchus 2017-01-15 17:32:20 +01:00
parent a414c1a43a
commit 71864376a9
6 changed files with 55 additions and 10 deletions

View File

@ -8,7 +8,7 @@ set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "Tray application for Syncthing")
set(META_APP_CATEGORIES "System;Utility;Network;FileTransfer")
set(META_VERSION_MAJOR 0)
set(META_VERSION_MINOR 3)
set(META_VERSION_MINOR 4)
set(META_VERSION_PATCH 0)
set(META_VERSION_EXACT_SONAME ON)

View File

@ -6,6 +6,7 @@
#include "unitinterface.h"
#include "serviceinterface.h"
#include "propertiesinterface.h"
#include "loginmanagerinterface.h"
#include <QDBusArgument>
#include <QDBusConnection>
@ -45,6 +46,9 @@ constexpr DateTime dateTimeFromSystemdTimeStamp(qulonglong timeStamp)
}
OrgFreedesktopSystemd1ManagerInterface *SyncthingService::s_manager = nullptr;
OrgFreedesktopLogin1ManagerInterface *SyncthingService::s_loginManager = nullptr;
DateTime SyncthingService::s_lastWakeUp = DateTime();
bool SyncthingService::s_fallingAsleep = false;
SyncthingService::SyncthingService(QObject *parent) :
QObject(parent),
@ -67,6 +71,14 @@ SyncthingService::SyncthingService(QObject *parent) :
// enable systemd to emit signals
s_manager->Subscribe();
}
if(!s_loginManager) {
s_loginManager = new OrgFreedesktopLogin1ManagerInterface(
QStringLiteral("org.freedesktop.login1"),
QStringLiteral("/org/freedesktop/login1"),
QDBusConnection::systemBus()
);
connect(s_loginManager, &OrgFreedesktopLogin1ManagerInterface::PrepareForSleep, &SyncthingService::handlePrepareForSleep);
}
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());
@ -99,6 +111,20 @@ bool SyncthingService::isUnitAvailable() const
return m_unit && m_unit->isValid();
}
bool SyncthingService::isActiveWithoutSleepFor(unsigned int atLeastSeconds) const
{
if(!atLeastSeconds) {
return true;
}
if(m_activeSince.isNull() || s_fallingAsleep) {
return false;
}
const DateTime now(DateTime::gmtNow());
return ((now - m_activeSince).totalSeconds() > atLeastSeconds)
&& (s_lastWakeUp.isNull() || ((now - s_lastWakeUp).totalSeconds() > atLeastSeconds));
}
void SyncthingService::setRunning(bool running)
{
m_manuallyStopped = !running;
@ -189,6 +215,13 @@ void SyncthingService::handleServiceRegisteredChanged(const QString &service)
}
}
void SyncthingService::handlePrepareForSleep(bool rightBefore)
{
if(!(s_fallingAsleep = rightBefore)) {
s_lastWakeUp = DateTime::gmtNow();
}
}
bool SyncthingService::handlePropertyChanged(QString &variable, void (SyncthingService::*signal)(const QString &), const QString &propertyName, const QVariantMap &changedProperties, const QStringList &invalidatedProperties)
{
const QVariant valueVariant(changedProperties[propertyName]);

View File

@ -16,6 +16,7 @@ class OrgFreedesktopSystemd1ManagerInterface;
class OrgFreedesktopSystemd1UnitInterface;
class OrgFreedesktopSystemd1ServiceInterface;
class OrgFreedesktopDBusPropertiesInterface;
class OrgFreedesktopLogin1ManagerInterface;
namespace Data {
@ -55,6 +56,8 @@ public:
const QString &subState() const;
ChronoUtilities::DateTime activeSince() const;
bool isActiveFor(unsigned int atLeastSeconds) const;
bool isActiveWithoutSleepFor(unsigned int atLeastSeconds) const;
static ChronoUtilities::DateTime lastWakeUp();
const QString &unitFileState() const;
const QString &description() const;
bool isRunning() const;
@ -89,6 +92,7 @@ private Q_SLOTS:
void handlePropertiesChanged(const QString &interface, const QVariantMap &changedProperties, const QStringList &invalidatedProperties);
void handleError(const char *error, QDBusPendingCallWatcher *watcher);
void handleServiceRegisteredChanged(const QString &service);
static void handlePrepareForSleep(bool rightBefore);
void setUnit(const QDBusObjectPath &objectPath);
void setProperties(const QString &activeState, const QString &subState, const QString &unitFileState, const QString &description);
@ -98,6 +102,9 @@ private:
void registerErrorHandler(const QDBusPendingCall &call, const char *context);
static OrgFreedesktopSystemd1ManagerInterface *s_manager;
static OrgFreedesktopLogin1ManagerInterface *s_loginManager;
static bool s_fallingAsleep;
static ChronoUtilities::DateTime s_lastWakeUp;
QString m_unitName;
QDBusServiceWatcher *m_serviceWatcher;
OrgFreedesktopSystemd1UnitInterface *m_unit;
@ -176,6 +183,11 @@ inline bool SyncthingService::isActiveFor(unsigned int atLeastSeconds) const
return !m_activeSince.isNull() && (ChronoUtilities::DateTime::gmtNow() - m_activeSince).totalSeconds() > atLeastSeconds;
}
inline ChronoUtilities::DateTime SyncthingService::lastWakeUp()
{
return s_lastWakeUp;
}
inline void SyncthingService::enable()
{
setEnabled(true);

View File

@ -163,22 +163,22 @@
<context>
<name>Data::SyncthingService</name>
<message>
<location filename="../syncthingservice.cpp" line="104"/>
<location filename="../syncthingservice.cpp" line="132"/>
<source>start unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="106"/>
<location filename="../syncthingservice.cpp" line="134"/>
<source>stop unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="113"/>
<location filename="../syncthingservice.cpp" line="141"/>
<source>enable unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="115"/>
<location filename="../syncthingservice.cpp" line="143"/>
<source>disable unit</source>
<translation type="unfinished"></translation>
</message>

View File

@ -163,22 +163,22 @@
<context>
<name>Data::SyncthingService</name>
<message>
<location filename="../syncthingservice.cpp" line="104"/>
<location filename="../syncthingservice.cpp" line="132"/>
<source>start unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="106"/>
<location filename="../syncthingservice.cpp" line="134"/>
<source>stop unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="113"/>
<location filename="../syncthingservice.cpp" line="141"/>
<source>enable unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="115"/>
<location filename="../syncthingservice.cpp" line="143"/>
<source>disable unit</source>
<translation type="unfinished"></translation>
</message>

View File

@ -144,7 +144,7 @@ void TrayIcon::showInternalError(const QString &errorMsg, SyncthingErrorCategory
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
&& (!settings.systemd.considerForReconnect || !serviceRelevant || !(networkError == QNetworkReply::RemoteHostClosedError && service.isManuallyStopped()))
&& (settings.ignoreInavailabilityAfterStart == 0
|| !(networkError == QNetworkReply::ConnectionRefusedError && service.isRunning() && !service.isActiveFor(settings.ignoreInavailabilityAfterStart)))
|| !(networkError == QNetworkReply::ConnectionRefusedError && service.isRunning() && !service.isActiveWithoutSleepFor(settings.ignoreInavailabilityAfterStart)))
#endif
) {
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS