fix: completly exit on app close

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
2025-06-15 22:33:33 +05:00
parent 14687d12ca
commit 56b105d7b4
3 changed files with 67 additions and 7 deletions

View File

@ -36,7 +36,7 @@ def main():
# Обработка флага --fullscreen
if args.fullscreen:
logger.info("Запуск в полноэкранном режиме по флагу --fullscreen")
logger.info("Launching in fullscreen mode due to --fullscreen flag")
save_fullscreen_config(True)
window.showFullScreen()
@ -47,13 +47,28 @@ def main():
def recreate_tray():
nonlocal tray
tray.hide_tray()
if tray:
logger.debug("Recreating system tray")
tray.cleanup()
tray = None
current_theme = read_theme_from_config()
tray = SystemTray(app, current_theme)
tray.show_action.triggered.connect(window.show)
tray.hide_action.triggered.connect(window.hide)
def cleanup_on_exit():
nonlocal tray, window
app.aboutToQuit.disconnect() # Disconnect to prevent further calls
if tray:
tray.cleanup()
tray = None
if window:
window.close()
window = None
app.quit()
window.settings_saved.connect(recreate_tray)
app.aboutToQuit.connect(cleanup_on_exit)
window.show()

View File

@ -1852,14 +1852,46 @@ class MainWindow(QMainWindow):
self.checkProcessTimer.start(500)
def closeEvent(self, event):
"""Завершает все дочерние процессы и сохраняет настройки при закрытии окна."""
# Завершаем все игровые процессы
for proc in self.game_processes:
try:
parent = psutil.Process(proc.pid)
children = parent.children(recursive=True)
for child in children:
try:
logger.debug(f"Terminating child process {child.pid}")
child.terminate()
except psutil.NoSuchProcess:
logger.debug(f"Child process {child.pid} already terminated")
psutil.wait_procs(children, timeout=5)
for child in children:
if child.is_running():
logger.debug(f"Killing child process {child.pid}")
child.kill()
logger.debug(f"Terminating process group {proc.pid}")
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
except ProcessLookupError:
pass # процесс уже завершился
except (psutil.NoSuchProcess, ProcessLookupError) as e:
logger.debug(f"Process {proc.pid} already terminated: {e}")
self.game_processes = [] # Очищаем список процессов
# Сохраняем настройки окна
if not read_fullscreen_config():
logger.debug(f"Saving window geometry: {self.width()}x{self.height()}")
save_window_geometry(self.width(), self.height())
save_card_size(self.card_width)
# Очищаем таймеры и другие ресурсы
if hasattr(self, 'games_load_timer') and self.games_load_timer.isActive():
self.games_load_timer.stop()
if hasattr(self, 'settingsDebounceTimer') and self.settingsDebounceTimer.isActive():
self.settingsDebounceTimer.stop()
if hasattr(self, 'searchDebounceTimer') and self.searchDebounceTimer.isActive():
self.searchDebounceTimer.stop()
if hasattr(self, 'checkProcessTimer') and self.checkProcessTimer and self.checkProcessTimer.isActive():
self.checkProcessTimer.stop()
self.checkProcessTimer.deleteLater()
self.checkProcessTimer = None
event.accept()

View File

@ -7,12 +7,13 @@ from portprotonqt.config_utils import read_theme_from_config
class SystemTray:
def __init__(self, app, theme=None):
self.app = app
self.theme_manager = ThemeManager()
self.theme = theme if theme is not None else default_styles
self.current_theme_name = read_theme_from_config()
self.tray = QSystemTrayIcon()
self.tray.setIcon(cast(QIcon, self.theme_manager.get_icon("ppqt-tray", self.current_theme_name)))
self.tray.setToolTip("PortProton QT")
self.tray.setToolTip("PortProtonQt")
self.tray.setVisible(True)
# Создаём меню
@ -32,4 +33,16 @@ class SystemTray:
def hide_tray(self):
"""Скрыть иконку трея"""
self.tray.hide()
if self.tray:
self.tray.setVisible(False)
self.tray.setContextMenu(None)
def cleanup(self):
"""Очистка ресурсов трея"""
self.hide_tray()
if self.menu:
self.menu.deleteLater()
self.menu = None
if self.tray:
self.tray.deleteLater()
self.tray = None