diff --git a/portprotonqt/config_utils.py b/portprotonqt/config_utils.py index 453b192..3c9ca86 100644 --- a/portprotonqt/config_utils.py +++ b/portprotonqt/config_utils.py @@ -482,3 +482,38 @@ def clear_cache(): logger.info("Кэш PortProtonQT удалён: %s", cache_dir) except Exception as e: logger.error("Ошибка при удалении кэша: %s", e) + +def read_auto_fullscreen_gamepad(): + """ + Читает настройку автоматического полноэкранного режима при подключении геймпада из секции [Display]. + Если параметр отсутствует, сохраняет и возвращает False по умолчанию. + """ + cp = configparser.ConfigParser() + if os.path.exists(CONFIG_FILE): + try: + cp.read(CONFIG_FILE, encoding="utf-8") + except Exception as e: + logger.error("Ошибка чтения конфигурационного файла: %s", e) + save_auto_fullscreen_gamepad(False) + return False + if not cp.has_section("Display") or not cp.has_option("Display", "auto_fullscreen_gamepad"): + save_auto_fullscreen_gamepad(False) + return False + return cp.getboolean("Display", "auto_fullscreen_gamepad", fallback=False) + return False + +def save_auto_fullscreen_gamepad(auto_fullscreen): + """ + Сохраняет настройку автоматического полноэкранного режима при подключении геймпада в секцию [Display]. + """ + cp = configparser.ConfigParser() + if os.path.exists(CONFIG_FILE): + try: + cp.read(CONFIG_FILE, encoding="utf-8") + except (configparser.DuplicateSectionError, configparser.DuplicateOptionError) as e: + logger.error("Ошибка чтения конфигурационного файла: %s", e) + if "Display" not in cp: + cp["Display"] = {} + cp["Display"]["auto_fullscreen_gamepad"] = str(auto_fullscreen) + with open(CONFIG_FILE, "w", encoding="utf-8") as configfile: + cp.write(configfile) diff --git a/portprotonqt/input_manager.py b/portprotonqt/input_manager.py index 28becc8..daaafbc 100644 --- a/portprotonqt/input_manager.py +++ b/portprotonqt/input_manager.py @@ -10,7 +10,7 @@ from portprotonqt.logger import get_logger from portprotonqt.image_utils import FullscreenDialog from portprotonqt.custom_widgets import NavLabel from portprotonqt.game_card import GameCard -from portprotonqt.config_utils import read_fullscreen_config, read_window_geometry, save_window_geometry +from portprotonqt.config_utils import read_fullscreen_config, read_window_geometry, save_window_geometry, read_auto_fullscreen_gamepad logger = get_logger(__name__) @@ -41,7 +41,7 @@ BUTTONS = { 'next_tab': {ecodes.BTN_TR, ecodes.BTN_TRIGGER_HAPPY5}, 'confirm_stick': {ecodes.BTN_THUMBL, ecodes.BTN_THUMBR}, 'context_menu': {ecodes.BTN_START}, - 'menu': {ecodes.BTN_SELECT, ecodes.BTN_MODE}, + 'menu': {ecodes.BTN_SELECT}, } class InputManager(QObject): @@ -595,8 +595,11 @@ class InputManager(QObject): self.gamepad_thread.join() self.gamepad_thread = threading.Thread(target=self.monitor_gamepad, daemon=True) self.gamepad_thread.start() - # Signal to enter fullscreen mode - self.toggle_fullscreen.emit(True) + # Отправляем сигнал для полноэкранного режима только если: + # 1. auto_fullscreen_gamepad включено + # 2. fullscreen выключено (чтобы не конфликтовать с основной настройкой) + if read_auto_fullscreen_gamepad() and not read_fullscreen_config(): + self.toggle_fullscreen.emit(True) except Exception as e: logger.error(f"Error checking gamepad: {e}", exc_info=True) @@ -623,7 +626,12 @@ class InputManager(QObject): continue now = time.time() if event.type == ecodes.EV_KEY and event.value == 1: - self.button_pressed.emit(event.code) + # Обработка кнопки Select для переключения полноэкранного режима + if event.code in BUTTONS['menu']: + # Переключаем полноэкранный режим + self.toggle_fullscreen.emit(not self._is_fullscreen) + else: + self.button_pressed.emit(event.code) elif event.type == ecodes.EV_ABS: self.dpad_moved.emit(event.code, event.value, now) except OSError as e: diff --git a/portprotonqt/main_window.py b/portprotonqt/main_window.py index 964f5a3..b31f398 100644 --- a/portprotonqt/main_window.py +++ b/portprotonqt/main_window.py @@ -20,9 +20,12 @@ from portprotonqt.egs_api import load_egs_games_async from portprotonqt.theme_manager import ThemeManager, load_theme_screenshots, load_logo from portprotonqt.time_utils import save_last_launch, get_last_launch, parse_playtime_file, format_playtime, get_last_launch_timestamp, format_last_launch from portprotonqt.config_utils import ( - get_portproton_location, read_theme_from_config, save_theme_to_config, parse_desktop_entry, load_theme_metainfo, read_time_config, read_card_size, save_card_size, - read_sort_method, read_display_filter, read_favorites, save_favorites, save_time_config, save_sort_method, 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 + get_portproton_location, read_theme_from_config, save_theme_to_config, parse_desktop_entry, + load_theme_metainfo, read_time_config, read_card_size, save_card_size, read_sort_method, + read_display_filter, read_favorites, save_favorites, save_time_config, save_sort_method, + 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 ) from portprotonqt.localization import _ from portprotonqt.logger import get_logger @@ -976,7 +979,17 @@ class MainWindow(QMainWindow): self.fullscreenCheckBox.setChecked(current_fullscreen) formLayout.addRow(self.fullscreenTitle, self.fullscreenCheckBox) - # 6. Legendary Authentication + # 6. Automatic fullscreen on gamepad connection + self.autoFullscreenGamepadCheckBox = QCheckBox(_("Auto Fullscreen on Gamepad connected")) + self.autoFullscreenGamepadCheckBox.setFocusPolicy(Qt.FocusPolicy.StrongFocus) + self.autoFullscreenGamepadTitle = QLabel(_("Auto Fullscreen on Gamepad connected:")) + self.autoFullscreenGamepadTitle.setStyleSheet(self.theme.PARAMS_TITLE_STYLE) + self.autoFullscreenGamepadTitle.setFocusPolicy(Qt.FocusPolicy.NoFocus) + current_auto_fullscreen = read_auto_fullscreen_gamepad() + self.autoFullscreenGamepadCheckBox.setChecked(current_auto_fullscreen) + formLayout.addRow(self.autoFullscreenGamepadTitle, self.autoFullscreenGamepadCheckBox) + + # 7. Legendary Authentication self.legendaryAuthButton = AutoSizeButton( _("Open Legendary Login"), icon=self.theme_manager.get_icon("login") @@ -1155,6 +1168,9 @@ class MainWindow(QMainWindow): fullscreen = self.fullscreenCheckBox.isChecked() save_fullscreen_config(fullscreen) + auto_fullscreen_gamepad = self.autoFullscreenGamepadCheckBox.isChecked() + save_auto_fullscreen_gamepad(auto_fullscreen_gamepad) + for card in self.game_card_cache.values(): card.update_badge_visibility(filter_key) @@ -1170,18 +1186,14 @@ class MainWindow(QMainWindow): self.settings_saved.emit() - if fullscreen: + # Управление полноэкранным режимом + gamepad_connected = self.input_manager.find_gamepad() is not None + if fullscreen or (auto_fullscreen_gamepad and gamepad_connected): self.showFullScreen() else: - if self.isFullScreen(): - # Переходим в нормальный режим и восстанавливаем сохраненные размеры - width, height = read_window_geometry() - self.showNormal() - if width > 0 and height > 0: - self.resize(width, height) - # Сохраняем геометрию только если окно не в полноэкранном режиме - if not self.isFullScreen(): - save_window_geometry(self.width(), self.height()) + # Если обе галочки сняты и геймпад не подключен, возвращаем нормальное состояние + self.showNormal() + self.resize(*read_window_geometry()) # Восстанавливаем сохраненные размеры окна self.statusBar().showMessage(_("Settings saved"), 3000)