From 26d7799fe90e621994503231ac917336f99b6145 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Wed, 21 Oct 2026 10:12:29 +0200 Subject: sbb-remote 0.10.0: config-get/config-set; GUI watches its config Keystone's settings pages edit both configs. config-get returns the VM config text, the defaults and the path; config-set validates new text with the same check() as load_config, keeps .bak and replaces the file atomically. Both run before load_config, so a broken config can still be read and fixed. The GUI reloads its config when the file changes, re-adding the watch after an atomic write replaces the inode. Co-Authored-By: Claude Opus 5.5 --- sb_builder/mainwindow.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sb_builder/mainwindow.py') diff --git a/sb_builder/mainwindow.py b/sb_builder/mainwindow.py index 5ebe869..4b0aca2 100644 --- a/sb_builder/mainwindow.py +++ b/sb_builder/mainwindow.py @@ -19,7 +19,7 @@ import os import time -from PyQt6.QtCore import QSettings, QMetaType, QObject, QSize, Qt, QTimer, pyqtSignal, pyqtSlot +from PyQt6.QtCore import QFileSystemWatcher, QSettings, QMetaType, QObject, QSize, Qt, QTimer, pyqtSignal, pyqtSlot from PyQt6.QtDBus import QDBusArgument, QDBusConnection, QDBusInterface, QDBusMessage from PyQt6.QtGui import QIcon, QKeySequence, QShortcut from PyQt6.QtWidgets import (QHeaderView, QLabel, QMainWindow, QMessageBox, QPushButton, QSplitter, @@ -90,6 +90,10 @@ class MainWindow(QMainWindow): self.state = QSettings(state or os.path.join(os.path.dirname(config.path()), "state.conf"), QSettings.Format.IniFormat) self.cfg, self.remote = cfg, remote + # Keystone's settings page saves here: apply it live (File > Reload config stays) + # ponytail: watches the file only, so one created after startup needs a reload by hand + self.config_watch = QFileSystemWatcher([config.path()], self) + self.config_watch.fileChanged.connect(self._config_changed) self.notifier = notifier or Notifier(self) self.notifier.clicked.connect(self.open_job) self.hint_dialogs = [] # open HintResultDialogs, kept alive while shown @@ -439,6 +443,11 @@ class MainWindow(QMainWindow): self.state.sync() super().closeEvent(event) + def _config_changed(self, path): + if os.path.exists(path): + self.config_watch.addPath(path) # an atomic write replaced the inode, dropping the watch + self.reload_config() + def reload_config(self): cfg, err = config.load() if err: -- cgit v1.2.3