Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
62b8da2dc4
|
|||
b77609cb5f
|
|||
56b105d7b4
|
|||
14687d12ca
|
@ -145,13 +145,20 @@ jobs:
|
||||
- name: Install required dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y original-awk
|
||||
sudo apt install -y original-awk unzip
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: https://gitea.com/actions/download-artifact@v3
|
||||
with:
|
||||
path: release/
|
||||
|
||||
- name: Extract downloaded artifacts
|
||||
run: |
|
||||
mkdir -p extracted
|
||||
find release/ -name '*.zip' -exec unzip -o {} -d extracted/ \;
|
||||
find extracted/ -type f -exec mv {} release/ \;
|
||||
rm -rf extracted/
|
||||
|
||||
- name: Extract changelog for version
|
||||
id: changelog
|
||||
run: |
|
||||
@ -163,7 +170,7 @@ jobs:
|
||||
with:
|
||||
body_path: changelog.txt
|
||||
token: ${{ env.GITEA_TOKEN }}
|
||||
tag_name: ${{ env.VERSION }}
|
||||
tag_name: v${{ env.VERSION }}
|
||||
prerelease: true
|
||||
files: release/**/*
|
||||
sha256sum: true
|
||||
|
@ -62,6 +62,7 @@
|
||||
- Исправлены ошибки при подключении геймпада
|
||||
- Предотвращено многократное открытие диалога добавления игры через геймпад
|
||||
- Корректная обработка событий геймпада во время игры
|
||||
- Убийсво всех процессов "зомби" при закрытии программы
|
||||
|
||||
---
|
||||
|
||||
|
@ -29,14 +29,12 @@ def main():
|
||||
else:
|
||||
logger.error(f"Qt translations for {system_locale.name()} not found in {translations_path}")
|
||||
|
||||
# Парсинг аргументов командной строки
|
||||
args = parse_args()
|
||||
|
||||
window = MainWindow()
|
||||
|
||||
# Обработка флага --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 +45,29 @@ 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)
|
||||
# Ensure window is not None before connecting signals
|
||||
if window:
|
||||
tray.show_action.triggered.connect(window.show)
|
||||
tray.hide_action.triggered.connect(window.hide)
|
||||
|
||||
def cleanup_on_exit():
|
||||
nonlocal tray, window
|
||||
app.aboutToQuit.disconnect()
|
||||
if tray:
|
||||
tray.cleanup()
|
||||
tray = None
|
||||
if window:
|
||||
window.close()
|
||||
app.quit()
|
||||
|
||||
window.settings_saved.connect(recreate_tray)
|
||||
app.aboutToQuit.connect(cleanup_on_exit)
|
||||
|
||||
window.show()
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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,17 @@ class SystemTray:
|
||||
|
||||
def hide_tray(self):
|
||||
"""Скрыть иконку трея"""
|
||||
self.tray.hide()
|
||||
if self.tray:
|
||||
self.tray.setVisible(False)
|
||||
if self.menu:
|
||||
self.menu.deleteLater()
|
||||
self.menu = None
|
||||
|
||||
def cleanup(self):
|
||||
"""Очистка ресурсов трея"""
|
||||
if self.tray:
|
||||
self.tray.setVisible(False)
|
||||
self.tray = None
|
||||
if self.menu:
|
||||
self.menu.deleteLater()
|
||||
self.menu = None
|
||||
|
Reference in New Issue
Block a user