diff --git a/src/onedrive_gui/gui_settings_window.py b/src/onedrive_gui/gui_settings_window.py index 8a6e52a..9984040 100644 --- a/src/onedrive_gui/gui_settings_window.py +++ b/src/onedrive_gui/gui_settings_window.py @@ -31,6 +31,9 @@ class GuiSettingsWindow(QWidget, Ui_gui_settings_window): self.checkBox_autostart_enabled.setChecked(self.get_check_box_state("autostart_enabled")) self.checkBox_autostart_enabled.stateChanged.connect(self.handle_autostart_change) + self.checkBox_stop_clients_on_exit.setChecked(self.get_check_box_state("stop_clients_on_exit")) + self.checkBox_stop_clients_on_exit.stateChanged.connect(self.set_check_box_state) + self.lineEdit_client_bin_path.setText(gui_settings.get("client_bin_path")) self.lineEdit_client_bin_path.textChanged.connect(self.set_client_bin_path) self.pushButton_client_bin_path.clicked.connect(self.get_bin_path) diff --git a/src/onedrive_gui/main_window.py b/src/onedrive_gui/main_window.py index 8546dda..9198e18 100644 --- a/src/onedrive_gui/main_window.py +++ b/src/onedrive_gui/main_window.py @@ -25,6 +25,7 @@ from .ui.ui_external_login import Ui_ExternalLoginWindow import re import os +import signal import sys import requests @@ -215,8 +216,16 @@ class MainWindow(QMainWindow, Ui_MainWindow): # Stop the clients and their worker threads before the application is torn # down; destroying a QThread that is still running aborts the process. + # Whether the clients are stopped (or left running in the background) is + # controlled by the 'stop_clients_on_exit' setting. QApplication.instance().aboutToQuit.connect(self.stop_all_workers) + # End-of-session signals: the desktop environment sends SIGTERM/SIGHUP to + # the session processes on logout. The Python handler only schedules the + # shutdown; the actual work happens in the event loop. + for termination_signal in (signal.SIGTERM, signal.SIGHUP): + signal.signal(termination_signal, lambda *_: QTimer.singleShot(0, self.shutdown_from_signal)) + self.refresh_process_status = QTimer() self.refresh_process_status.setSingleShot(False) self.refresh_process_status.timeout.connect(self.onedrive_process_status) @@ -299,16 +308,33 @@ class MainWindow(QMainWindow, Ui_MainWindow): if close_question == QMessageBox.Yes: logging.info("Quitting OneDriveGUI") - self.stop_all_workers() + self.stop_all_workers(force=True) QApplication.instance().quit() elif close_question == QMessageBox.No: logging.info("[GUI] Keeping OneDriveGUI running.") - def stop_all_workers(self): + def stop_all_workers(self, force=False): + """ + Stop every running worker and its OneDrive client. + + Unless `force` is set, the 'stop_clients_on_exit' setting decides whether + the clients are stopped or left running in the background for the next + OneDriveGUI start to reconnect to. + """ + if not force and gui_settings.get("stop_clients_on_exit") == "False": + logging.info("[GUI] Leaving the OneDrive clients running (stop on exit disabled)") + return + for profile_name in list(workers): workers[profile_name].stop_worker() + def shutdown_from_signal(self): + """Shut down without asking: the session is ending (SIGTERM/SIGHUP).""" + logging.info("[GUI] Termination signal received - shutting down") + self.stop_all_workers() + QApplication.instance().quit() + def stop_onedrive_monitor(self, profile_name): if profile_name in workers: workers[profile_name].stop_worker() diff --git a/src/onedrive_gui/settings/gui_settings.py b/src/onedrive_gui/settings/gui_settings.py index 56f26b0..8e324fa 100644 --- a/src/onedrive_gui/settings/gui_settings.py +++ b/src/onedrive_gui/settings/gui_settings.py @@ -17,6 +17,7 @@ class GuiSettings: "debug_level": "DEBUG", "client_bin_path": "onedrive", "QWebEngine_login": "False", + "stop_clients_on_exit": "True", "autostart_enabled": "False", } } diff --git a/src/onedrive_gui/ui/gui_settings_window.ui b/src/onedrive_gui/ui/gui_settings_window.ui index d33b182..102a5fb 100644 --- a/src/onedrive_gui/ui/gui_settings_window.ui +++ b/src/onedrive_gui/ui/gui_settings_window.ui @@ -37,6 +37,17 @@ + + + + Stop the OneDrive client of every profile when OneDriveGUI exits or the session logs out. The client finishes in-flight transfers before it exits.<br/>When disabled, the clients keep running in the background; OneDriveGUI offers to reconnect to them on the next start. + + + Stop OneDrive clients when OneDriveGUI exits + + + + diff --git a/src/onedrive_gui/ui/ui_gui_settings_window.py b/src/onedrive_gui/ui/ui_gui_settings_window.py index 3b80462..809d0bc 100644 --- a/src/onedrive_gui/ui/ui_gui_settings_window.py +++ b/src/onedrive_gui/ui/ui_gui_settings_window.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'gui_settings_window.ui' ## -## Created by: Qt User Interface Compiler version 6.10.0 +## Created by: Qt User Interface Compiler version 6.11.1 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -41,6 +41,11 @@ class Ui_gui_settings_window(object): self.verticalLayout_3.setObjectName(u"verticalLayout_3") self.formLayout = QFormLayout() self.formLayout.setObjectName(u"formLayout") + self.checkBox_stop_clients_on_exit = QCheckBox(self.groupBox) + self.checkBox_stop_clients_on_exit.setObjectName(u"checkBox_stop_clients_on_exit") + + self.formLayout.setWidget(2, QFormLayout.ItemRole.LabelRole, self.checkBox_stop_clients_on_exit) + self.checkBox_start_minimized = QCheckBox(self.groupBox) self.checkBox_start_minimized.setObjectName(u"checkBox_start_minimized") @@ -232,6 +237,10 @@ class Ui_gui_settings_window(object): def retranslateUi(self, gui_settings_window): gui_settings_window.setWindowTitle(QCoreApplication.translate("gui_settings_window", u"OneDriveGUI - Settings", None)) self.groupBox.setTitle(QCoreApplication.translate("gui_settings_window", u"OneDriveGUI behaviour", None)) +#if QT_CONFIG(tooltip) + self.checkBox_stop_clients_on_exit.setToolTip(QCoreApplication.translate("gui_settings_window", u"Stop the OneDrive client of every profile when OneDriveGUI exits or the session logs out. The client finishes in-flight transfers before it exits.
When disabled, the clients keep running in the background; OneDriveGUI offers to reconnect to them on the next start.", None)) +#endif // QT_CONFIG(tooltip) + self.checkBox_stop_clients_on_exit.setText(QCoreApplication.translate("gui_settings_window", u"Stop OneDrive clients when OneDriveGUI exits", None)) self.checkBox_start_minimized.setText(QCoreApplication.translate("gui_settings_window", u"Start OneDriveGUI minimized", None)) self.checkBox_autostart_enabled.setText(QCoreApplication.translate("gui_settings_window", u"Start OneDriveGUI automatically on login", None)) self.groupBox_4.setTitle(QCoreApplication.translate("gui_settings_window", u"OneDrive client options", None))