diff --git a/README.md b/README.md index f97199b..daf6cf8 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,12 @@ Queue / retry: - Run `ytpl-sync.exe` (GUI). ## Tray - + - The app supports minimizing to tray on close if the OS provides a system tray; use the tray icon menu to quit. - Tray behavior settings (Settings page): - `close_to_tray`: close hides to tray (keeps running). - `minimize_to_tray`: minimize hides to tray. + - `start_minimized_to_tray`: start hidden in tray. ## Data & Layout diff --git a/config/yt-playlist-config.example.json b/config/yt-playlist-config.example.json index 9dae509..4a6f0f9 100644 --- a/config/yt-playlist-config.example.json +++ b/config/yt-playlist-config.example.json @@ -6,7 +6,8 @@ "ui": { "tray": { "close_to_tray": true, - "minimize_to_tray": false + "minimize_to_tray": false, + "start_minimized_to_tray": false } }, "playlists": [ diff --git a/src/app/gui/main.py b/src/app/gui/main.py index 60bcaa3..16b754a 100644 --- a/src/app/gui/main.py +++ b/src/app/gui/main.py @@ -115,6 +115,12 @@ class MainWindow(QtWidgets.QMainWindow): def _minimize_to_tray_enabled(self) -> bool: return bool(self._tray_config().get("minimize_to_tray", False)) + def _start_minimized_to_tray_enabled(self) -> bool: + return bool(self._tray_config().get("start_minimized_to_tray", False)) + + def should_start_minimized_to_tray(self) -> bool: + return self._tray is not None and self._start_minimized_to_tray_enabled() + def _init_tray(self) -> None: # Tray support is optional and platform-dependent (e.g., some Linux DEs). try: @@ -388,7 +394,10 @@ def main() -> int: app.setFont(f) w = MainWindow() - w.show() + if w.should_start_minimized_to_tray(): + w.hide() + else: + w.show() return app.exec() diff --git a/src/app/gui/pages/settings.py b/src/app/gui/pages/settings.py index df7fc9e..894610f 100644 --- a/src/app/gui/pages/settings.py +++ b/src/app/gui/pages/settings.py @@ -58,6 +58,10 @@ class SettingsPage(QtWidgets.QWidget): self._minimize_to_tray.setChecked(False) tray_form.addRow("minimize_to_tray", self._minimize_to_tray) + self._start_minimized_to_tray = QtWidgets.QCheckBox() + self._start_minimized_to_tray.setChecked(False) + tray_form.addRow("start_minimized_to_tray", self._start_minimized_to_tray) + tray_box = QtWidgets.QGroupBox("Tray behavior") tray_box.setLayout(tray_form) layout.addWidget(tray_box) @@ -90,6 +94,7 @@ class SettingsPage(QtWidgets.QWidget): self._download_delay.valueChanged.connect(lambda _v: self._schedule_autosave()) self._close_to_tray.stateChanged.connect(lambda _v: self._schedule_autosave()) self._minimize_to_tray.stateChanged.connect(lambda _v: self._schedule_autosave()) + self._start_minimized_to_tray.stateChanged.connect(lambda _v: self._schedule_autosave()) def set_config_path(self, path: Path) -> None: self._config_path = path @@ -117,6 +122,7 @@ class SettingsPage(QtWidgets.QWidget): tray = tray if isinstance(tray, dict) else {} self._close_to_tray.setChecked(bool(tray.get("close_to_tray", True))) self._minimize_to_tray.setChecked(bool(tray.get("minimize_to_tray", False))) + self._start_minimized_to_tray.setChecked(bool(tray.get("start_minimized_to_tray", False))) self._status.setText(f"Loaded settings from {self._config_path}.") except Exception as exc: @@ -148,6 +154,7 @@ class SettingsPage(QtWidgets.QWidget): tray = tray if isinstance(tray, dict) else {} tray["close_to_tray"] = bool(self._close_to_tray.isChecked()) tray["minimize_to_tray"] = bool(self._minimize_to_tray.isChecked()) + tray["start_minimized_to_tray"] = bool(self._start_minimized_to_tray.isChecked()) ui["tray"] = tray data["ui"] = ui