e3b20089f0
release / release (push) Successful in 14s
- feat(alerts): desktop notifications (notify-send) for overheat (GPU/CPU past a configurable threshold), GPU-lost, and a new-version-available alert (once per version). Edge-triggered with cooldown so it doesn't spam (core/alerts.py) - feat(gui): Notifications page to configure alerts (enable, GPU/CPU thresholds, Send test); changes apply live and persist via config.save_config/update_config - feat(gui): ship a RigDoctor icon; the GUI self-registers the icon + .desktop on launch and sets the Wayland app-id, so the dock shows it after an update + relaunch (no installer re-run); installer/uninstaller updated to manage the icon - config: alerts_enabled, gpu_temp_alert, cpu_temp_alert; flat-TOML writer - tests for the alert monitor and config round-trip Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
109 lines
3.3 KiB
Python
109 lines
3.3 KiB
Python
"""Notifications page (M8 config): user-configurable alert settings."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from PySide6.QtCore import Qt, Signal
|
|
from PySide6.QtWidgets import (
|
|
QCheckBox,
|
|
QDoubleSpinBox,
|
|
QFrame,
|
|
QGridLayout,
|
|
QHBoxLayout,
|
|
QLabel,
|
|
QPushButton,
|
|
QVBoxLayout,
|
|
QWidget,
|
|
)
|
|
|
|
from ..config import load_config, update_config
|
|
from ..core import alerts
|
|
|
|
|
|
class NotificationsPage(QWidget):
|
|
changed = Signal() # settings saved — main window re-applies them live
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.setObjectName("Page")
|
|
root = QVBoxLayout(self)
|
|
root.setContentsMargins(20, 18, 20, 18)
|
|
root.setSpacing(16)
|
|
|
|
title = QLabel("Notifications")
|
|
title.setObjectName("PageTitle")
|
|
root.addWidget(title)
|
|
|
|
card = QFrame()
|
|
card.setObjectName("Card")
|
|
v = QVBoxLayout(card)
|
|
v.setContentsMargins(16, 14, 16, 14)
|
|
v.setSpacing(10)
|
|
head = QLabel("Alerts")
|
|
head.setStyleSheet("font-weight: 700; background: transparent;")
|
|
v.addWidget(head)
|
|
|
|
self._enabled = QCheckBox("Enable desktop notifications")
|
|
v.addWidget(self._enabled)
|
|
|
|
grid = QGridLayout()
|
|
grid.setHorizontalSpacing(12)
|
|
grid.setColumnStretch(2, 1)
|
|
self._gpu = self._spin()
|
|
self._cpu = self._spin()
|
|
grid.addWidget(QLabel("GPU temperature alert"), 0, 0)
|
|
grid.addWidget(self._gpu, 0, 1)
|
|
grid.addWidget(QLabel("CPU temperature alert"), 1, 0)
|
|
grid.addWidget(self._cpu, 1, 1)
|
|
v.addLayout(grid)
|
|
|
|
note = QLabel("GPU-lost and new-version alerts are included whenever notifications are enabled.")
|
|
note.setObjectName("Muted")
|
|
note.setWordWrap(True)
|
|
v.addWidget(note)
|
|
|
|
buttons = QHBoxLayout()
|
|
save = QPushButton("Save")
|
|
save.setObjectName("PrimaryButton")
|
|
save.clicked.connect(self._save)
|
|
test = QPushButton("Send test")
|
|
test.clicked.connect(self._test)
|
|
buttons.addWidget(save)
|
|
buttons.addWidget(test)
|
|
buttons.addStretch(1)
|
|
v.addLayout(buttons)
|
|
self._status = QLabel("")
|
|
self._status.setObjectName("Muted")
|
|
v.addWidget(self._status)
|
|
|
|
root.addWidget(card)
|
|
root.addStretch(1)
|
|
self._load()
|
|
|
|
@staticmethod
|
|
def _spin() -> QDoubleSpinBox:
|
|
spin = QDoubleSpinBox()
|
|
spin.setRange(40, 110)
|
|
spin.setDecimals(0)
|
|
spin.setSingleStep(1)
|
|
spin.setSuffix(" °C")
|
|
return spin
|
|
|
|
def _load(self) -> None:
|
|
cfg = load_config()
|
|
self._enabled.setChecked(bool(cfg.get("alerts_enabled", True)))
|
|
self._gpu.setValue(float(cfg.get("gpu_temp_alert", 90.0)))
|
|
self._cpu.setValue(float(cfg.get("cpu_temp_alert", 95.0)))
|
|
|
|
def _save(self) -> None:
|
|
update_config(
|
|
alerts_enabled=self._enabled.isChecked(),
|
|
gpu_temp_alert=self._gpu.value(),
|
|
cpu_temp_alert=self._cpu.value(),
|
|
)
|
|
self.changed.emit()
|
|
self._status.setText("Saved.")
|
|
|
|
def _test(self) -> None:
|
|
ok = alerts.notify("RigDoctor", "Test notification — alerts are working.")
|
|
self._status.setText("Test notification sent." if ok else "notify-send not found — install libnotify-bin (Setup).")
|