From 667f3b37797bf2ed430c0258ae33eef5883bc23e Mon Sep 17 00:00:00 2001 From: fixmeee <92666524+fixmeee@users.noreply.github.com> Date: Fri, 16 Dec 2022 11:10:40 +0100 Subject: [PATCH] Restart timers after hibernation/sleep (#1511) Schedules get missed, if system has been in hibernation/sleep state as described in https://github.com/borgbase/vorta/issues/1214 Although, timers should be refreshed every 15min, it seems that all timers get deranged by sleep state and schedules is still missed in most cases. This seems to be a general issue with the underlying QTimer implementation. This fix doesn't distinguish host OS and has only by tested on Linux. If 'org.freedesktop.login1.Manager' is not available, Vorta simple doesn't get notified if system awakes again. No no impact on other OS is expected Co-authored-by: yfprojects <62463991+real-yfprojects@users.noreply.github.com> --- src/vorta/scheduler.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/vorta/scheduler.py b/src/vorta/scheduler.py index dee52808..4cace732 100644 --- a/src/vorta/scheduler.py +++ b/src/vorta/scheduler.py @@ -4,7 +4,7 @@ import threading from datetime import datetime as dt from datetime import timedelta from typing import Dict, NamedTuple, Optional, Tuple, Union -from PyQt5 import QtCore +from PyQt5 import QtCore, QtDBus from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QApplication from vorta import application @@ -58,6 +58,25 @@ class VortaScheduler(QtCore.QObject): # connect signals self.app.backup_finished_event.connect(lambda res: self.set_timer_for_profile(res['params']['profile_id'])) + # connect to `systemd-logind` to receive sleep/resume events + # The signal `PrepareForSleep` will be emitted before and after hibernation. + service = "org.freedesktop.login1" + path = "/org/freedesktop/login1" + interface = "org.freedesktop.login1.Manager" + name = "PrepareForSleep" + bus = QtDBus.QDBusConnection.systemBus() + if bus.isConnected() and bus.interface().isServiceRegistered(service).value(): + self.bus = bus + self.bus.connect(service, path, interface, name, "b", self.loginSuspendNotify) + else: + logger.warn('Failed to connect to DBUS interface to detect sleep/resume events') + + @QtCore.pyqtSlot(bool) + def loginSuspendNotify(self, suspend: bool): + if not suspend: + logger.debug("Got login suspend/resume notification") + self.reload_all_timers() + def tr(self, *args, **kwargs): scope = self.__class__.__name__ return translate(scope, *args, **kwargs)