diff --git a/portprotonqt/app.py b/portprotonqt/app.py index f4d0e8f..99bc797 100644 --- a/portprotonqt/app.py +++ b/portprotonqt/app.py @@ -10,7 +10,7 @@ from portprotonqt.main_window import MainWindow from portprotonqt.config_utils import ( save_fullscreen_config, read_fullscreen_config, - get_portproton_location, + get_portproton_start_command ) from portprotonqt.logger import get_logger, setup_logger from portprotonqt.cli import parse_args @@ -34,8 +34,9 @@ def main(): os.environ["PROCESS_LOG"] = "1" os.environ["START_FROM_STEAM"] = "1" - portproton_path, start_sh = get_portproton_location() - if portproton_path is None or start_sh is None: + start_sh = get_portproton_start_command() + + if start_sh is None: return subprocess.run(start_sh + ["cli", "--initial"]) diff --git a/portprotonqt/config_utils.py b/portprotonqt/config_utils.py index f922856..3d6204f 100644 --- a/portprotonqt/config_utils.py +++ b/portprotonqt/config_utils.py @@ -103,16 +103,11 @@ def read_file_content(file_path): return f.read().strip() def get_portproton_location(): - """Returns the path to the PortProton directory and start.sh command list. + """Возвращает путь к PortProton каталогу (строку) или None.""" + global _portproton_location - Checks the cached path first. If not set, reads from PORTPROTON_CONFIG_FILE. - If the path is invalid, uses the default flatpak directory. - If Flatpak package ru.linux_gaming.PortProton is installed, returns the Flatpak run command list. - """ - global _portproton_location, _portproton_start_sh - - if '_portproton_location' in globals() and _portproton_location is not None: - return _portproton_location, _portproton_start_sh + if _portproton_location is not None: + return _portproton_location location = None @@ -120,16 +115,28 @@ def get_portproton_location(): try: location = read_file_content(PORTPROTON_CONFIG_FILE).strip() if location and os.path.isdir(location): + _portproton_location = location logger.info(f"PortProton path from configuration: {location}") - else: - logger.warning(f"Invalid PortProton path in configuration: {location}, using defaults") - location = None + return _portproton_location + logger.warning(f"Invalid PortProton path in configuration: {location}, using defaults") except (OSError, PermissionError) as e: logger.warning(f"Failed to read PortProton configuration file: {e}") - location = None default_flatpak_dir = os.path.join(os.path.expanduser("~"), ".var", "app", "ru.linux_gaming.PortProton") - is_flatpak_installed = False + if os.path.isdir(default_flatpak_dir): + _portproton_location = default_flatpak_dir + logger.info(f"Using Flatpak PortProton directory: {default_flatpak_dir}") + return _portproton_location + + logger.warning("PortProton configuration and Flatpak directory not found") + return None + +def get_portproton_start_command(): + """Возвращает список команд для запуска PortProton (start.sh или flatpak run).""" + portproton_path = get_portproton_location() + if not portproton_path: + return None + try: result = subprocess.run( ["flatpak", "list"], @@ -138,30 +145,18 @@ def get_portproton_location(): check=False ) if "ru.linux_gaming.PortProton" in result.stdout: - is_flatpak_installed = True + logger.info("Detected Flatpak installation") + return ["flatpak", "run", "ru.linux_gaming.PortProton"] except Exception: pass - if is_flatpak_installed: - _portproton_location = default_flatpak_dir if os.path.isdir(default_flatpak_dir) else None - _portproton_start_sh = ["flatpak", "run", "ru.linux_gaming.PortProton"] - logger.info("Detected Flatpak installation: using 'flatpak run ru.linux_gaming.PortProton'") - elif location: - _portproton_location = location - start_sh_path = os.path.join(location, "data", "scripts", "start.sh") - _portproton_start_sh = [start_sh_path] if os.path.exists(start_sh_path) else None - logger.info(f"Using PortProton installation from config path: {_portproton_location}") - elif os.path.isdir(default_flatpak_dir): - _portproton_location = default_flatpak_dir - start_sh_path = os.path.join(default_flatpak_dir, "data", "scripts", "start.sh") - _portproton_start_sh = [start_sh_path] if os.path.exists(start_sh_path) else None - logger.info(f"Using Flatpak PortProton directory: {_portproton_location}") - else: - logger.warning("PortProton configuration and Flatpak directory not found") - _portproton_location = None - _portproton_start_sh = None + start_sh_path = os.path.join(portproton_path, "data", "scripts", "start.sh") + if os.path.exists(start_sh_path): + return [start_sh_path] + + logger.warning("Neither flatpak nor start.sh found for PortProton") + return None - return _portproton_location, _portproton_start_sh def parse_desktop_entry(file_path): """Reads and parses a .desktop file using configparser. diff --git a/portprotonqt/context_menu_manager.py b/portprotonqt/context_menu_manager.py index a381c34..4773d62 100644 --- a/portprotonqt/context_menu_manager.py +++ b/portprotonqt/context_menu_manager.py @@ -11,7 +11,7 @@ from PySide6.QtWidgets import QMessageBox, QDialog, QMenu, QLineEdit, QApplicati from PySide6.QtCore import QUrl, QPoint, QObject, Signal, Qt from PySide6.QtGui import QDesktopServices, QIcon, QKeySequence from portprotonqt.localization import _ -from portprotonqt.config_utils import parse_desktop_entry, read_favorites, save_favorites, read_favorite_folders, save_favorite_folders +from portprotonqt.config_utils import parse_desktop_entry, read_favorites, save_favorites, read_favorite_folders, save_favorite_folders, get_portproton_start_command from portprotonqt.steam_api import is_game_in_steam, add_to_steam, remove_from_steam from portprotonqt.egs_api import add_egs_to_steam, get_egs_executable, remove_egs_from_steam from portprotonqt.dialogs import AddGameDialog, FileExplorer, generate_thumbnail @@ -406,16 +406,7 @@ class ContextMenuManager: ) return # Construct EGS launch command - wrapper = "flatpak run ru.linux_gaming.PortProton" - start_sh_path = os.path.join(self.portproton_location, "data", "scripts", "start.sh") - if self.portproton_location and ".var" not in self.portproton_location: - wrapper = start_sh_path - if not os.path.exists(start_sh_path): - self.signals.show_warning_dialog.emit( - _("Error"), - _("start.sh not found at {path}").format(path=start_sh_path) - ) - return + wrapper = get_portproton_start_command() exec_line = f'"{self.legendary_path}" launch {game_card.appid} --no-wine --wrapper "env START_FROM_STEAM=1 {wrapper}"' else: exec_line = self._get_exec_line(game_card.name, game_card.exec_line) diff --git a/portprotonqt/egs_api.py b/portprotonqt/egs_api.py index 9ca38cd..af08561 100644 --- a/portprotonqt/egs_api.py +++ b/portprotonqt/egs_api.py @@ -13,7 +13,7 @@ from portprotonqt.localization import get_egs_language, _ from portprotonqt.logger import get_logger from portprotonqt.image_utils import load_pixmap_async from portprotonqt.time_utils import parse_playtime_file, format_playtime, get_last_launch, get_last_launch_timestamp -from portprotonqt.config_utils import get_portproton_location +from portprotonqt.config_utils import get_portproton_location, get_portproton_start_command from portprotonqt.steam_api import ( get_weanticheatyet_status_async, get_steam_apps_and_index_async, get_protondb_tier_async, search_app, get_steam_home, get_last_steam_user, convert_steam_id, generate_thumbnail, call_steam_api @@ -254,14 +254,7 @@ def add_egs_to_steam(app_name: str, game_title: str, legendary_path: str, callba return # Determine wrapper - wrapper = "flatpak run ru.linux_gaming.PortProton" - start_sh_path = os.path.join(portproton_dir, "data", "scripts", "start.sh") - if portproton_dir is not None and ".var" not in portproton_dir: - wrapper = start_sh_path - if not os.path.exists(start_sh_path): - logger.error(f"start.sh not found at {start_sh_path}") - callback((False, f"start.sh not found at {start_sh_path}")) - return + wrapper = get_portproton_start_command() # Create launch script steam_scripts_dir = os.path.join(portproton_dir, "steam_scripts") diff --git a/portprotonqt/main_window.py b/portprotonqt/main_window.py index ad9f6c4..667a41a 100644 --- a/portprotonqt/main_window.py +++ b/portprotonqt/main_window.py @@ -30,7 +30,7 @@ from portprotonqt.config_utils import ( save_display_filter, save_proxy_config, read_proxy_config, read_fullscreen_config, save_fullscreen_config, read_window_geometry, save_window_geometry, reset_config, clear_cache, read_auto_fullscreen_gamepad, save_auto_fullscreen_gamepad, read_rumble_config, save_rumble_config, read_gamepad_type, save_gamepad_type, read_minimize_to_tray, save_minimize_to_tray, - read_auto_card_size, save_auto_card_size + read_auto_card_size, save_auto_card_size, get_portproton_start_command ) from portprotonqt.localization import _, get_egs_language, read_metadata_translations from portprotonqt.howlongtobeat_api import HowLongToBeat @@ -73,7 +73,8 @@ class MainWindow(QMainWindow): self.game_processes = [] self.target_exe = None self.current_running_button = None - self.portproton_location, self.start_sh = get_portproton_location() + self.portproton_location = get_portproton_location() + self.start_sh = get_portproton_start_command() self.game_library_manager = GameLibraryManager(self, self.theme, None) diff --git a/portprotonqt/portproton_api.py b/portprotonqt/portproton_api.py index 8937302..efbb8da 100644 --- a/portprotonqt/portproton_api.py +++ b/portprotonqt/portproton_api.py @@ -58,7 +58,7 @@ class PortProtonAPI: self.xdg_data_home = os.getenv("XDG_DATA_HOME", os.path.join(os.path.expanduser("~"), ".local", "share")) self.custom_data_dir = os.path.join(self.xdg_data_home, "PortProtonQt", "custom_data") os.makedirs(self.custom_data_dir, exist_ok=True) - self.portproton_location, self.portproton_start_sh = get_portproton_location() + self.portproton_location = get_portproton_location() self.repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) self.builtin_custom_folder = os.path.join(self.repo_root, "custom_data") self._topics_data = None diff --git a/portprotonqt/steam_api.py b/portprotonqt/steam_api.py index ecda60c..555addf 100644 --- a/portprotonqt/steam_api.py +++ b/portprotonqt/steam_api.py @@ -13,7 +13,7 @@ from portprotonqt.logger import get_logger from portprotonqt.localization import get_steam_language from portprotonqt.downloader import Downloader from portprotonqt.dialogs import generate_thumbnail -from portprotonqt.config_utils import get_portproton_location +from portprotonqt.config_utils import get_portproton_location, get_portproton_start_command from collections.abc import Callable import re import shutil @@ -1004,7 +1004,8 @@ def add_to_steam(game_name: str, exec_line: str, cover_path: str) -> tuple[bool, return (False, f"Executable file not found: {exe_path}") portproton_dir = get_portproton_location() - if not portproton_dir: + start_sh = get_portproton_start_command() + if not portproton_dir or not start_sh: logger.error("PortProton directory not found") return (False, "PortProton directory not found") @@ -1013,17 +1014,12 @@ def add_to_steam(game_name: str, exec_line: str, cover_path: str) -> tuple[bool, safe_game_name = re.sub(r'[<>:"/\\|?*]', '_', game_name.strip()) script_path = os.path.join(steam_scripts_dir, f"{safe_game_name}.sh") - start_sh_path = os.path.join(portproton_dir, "data", "scripts", "start.sh") - - if not os.path.exists(start_sh_path): - logger.error(f"start.sh not found at {start_sh_path}") - return (False, f"start.sh not found at {start_sh_path}") if not os.path.exists(script_path): script_content = f"""#!/usr/bin/env bash export LD_PRELOAD= export START_FROM_STEAM=1 -"{start_sh_path}" "{exe_path}" "$@" +"{start_sh}" "{exe_path}" "$@" """ try: with open(script_path, "w", encoding="utf-8") as f: