disallow to disable guard during focus
docker / image (push) Failing after 24s
lint / ruff (push) Failing after 28s
tests / backend (push) Successful in 37s
tests / desktop (push) Successful in 22s
tests / android-core (push) Successful in 49s
tests / web (push) Successful in 1m20s
android / apk (push) Successful in 8m49s

This commit is contained in:
timka123 committed 2026-10-28 09:50:58 +03:00
1 parent 157a113c39
commit d280101bce
21 files changed
+481 -43

No files matched your search

+31
View File
@@ -37,6 +37,14 @@ log = logging.getLogger(__name__)
KIND_LABELS = {"work": "Focus", "short_break": "Short break", "long_break": "Long break"}
#: The local switches that stop this machine enforcing. While the server reports
#: the guard locked, these only go one way — on. Turning enforcement off is what a
#: focus guard exists to make inconvenient, and this app is the thing enforcing.
_ENFORCEMENT_KEYS = ("enforce_blocking", "block_hosts_file", "block_apps")
#: Said when the policy has not been polled yet, so there is no server sentence.
_GUARD_LOCK_FALLBACK = "Finish or drop the interval to switch the focus guard off."
def clock(seconds: int) -> str:
seconds = max(0, int(seconds))
@@ -252,6 +260,20 @@ class Controller(QObject):
def blockerReason(self) -> str:
return str(self._policy.get("reason", ""))
@pyqtProperty(bool, notify=blockerChanged)
def blockerLocked(self) -> bool:
"""The server will not let the guard be switched off right now.
Not the same as [blockerActive]: in scheduled mode outside every window
nothing is being blocked and the guard is still locked on, because an
interval is running or paused.
"""
return bool(self._policy.get("locked"))
@pyqtProperty(str, notify=blockerChanged)
def blockerLockNote(self) -> str:
return str(self._policy.get("lock_reason", ""))
@pyqtProperty("QVariantList", notify=blockerChanged)
def blockedDomains(self) -> list[str]:
"""Every hostname the policy wants blocked, server-expanded.
@@ -447,6 +469,15 @@ class Controller(QObject):
@pyqtSlot(str, "QVariant")
def setConfig(self, key: str, value: Any) -> None:
"""Change a desktop-local setting and apply it immediately."""
if key in _ENFORCEMENT_KEYS and not value and self.blockerLocked:
# This machine is the one that actually enforces, so switching
# enforcement off here is the real escape hatch — the server's
# `blocker.enabled` is untouchable from this app anyway. The greyed
# switch in the dialog is not the enforcement: the policy poll can be
# seconds stale, and the tray and D-Bus come through here too.
self.toast.emit(self.blockerLockNote or _GUARD_LOCK_FALLBACK)
self.configChanged.emit() # snap the switch back to the stored value
return
if key == "autostart":
autostart.set_autostart(bool(value), minimized=self._config.start_minimized)
elif key == "service_enabled":