forked from Boria138/PortProtonQt
feat(settings): Added Gamepad type settings
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
@@ -259,6 +259,25 @@ def save_rumble_config(rumble_enabled):
|
||||
with open(CONFIG_FILE, "w", encoding="utf-8") as configfile:
|
||||
cp.write(configfile)
|
||||
|
||||
def read_gamepad_type():
|
||||
"""Reads the gamepad type from the [Gamepad] section.
|
||||
Returns 'xbox' if the parameter is missing.
|
||||
"""
|
||||
cp = read_config_safely(CONFIG_FILE)
|
||||
if cp is None or not cp.has_section("Gamepad") or not cp.has_option("Gamepad", "type"):
|
||||
save_gamepad_type("xbox")
|
||||
return "xbox"
|
||||
return cp.get("Gamepad", "type", fallback="xbox").lower()
|
||||
|
||||
def save_gamepad_type(gpad_type):
|
||||
"""Saves the gamepad type to the [Gamepad] section."""
|
||||
cp = read_config_safely(CONFIG_FILE) or configparser.ConfigParser()
|
||||
if "Gamepad" not in cp:
|
||||
cp["Gamepad"] = {}
|
||||
cp["Gamepad"]["type"] = gpad_type
|
||||
with open(CONFIG_FILE, "w", encoding="utf-8") as configfile:
|
||||
cp.write(configfile)
|
||||
|
||||
def ensure_default_proxy_config():
|
||||
"""Ensures the [Proxy] section exists in the configuration file.
|
||||
Creates it with empty values if missing.
|
||||
|
@@ -12,7 +12,7 @@ from portprotonqt.logger import get_logger
|
||||
from portprotonqt.image_utils import FullscreenDialog
|
||||
from portprotonqt.custom_widgets import NavLabel, AutoSizeButton
|
||||
from portprotonqt.game_card import GameCard
|
||||
from portprotonqt.config_utils import read_fullscreen_config, read_window_geometry, save_window_geometry, read_auto_fullscreen_gamepad, read_rumble_config
|
||||
from portprotonqt.config_utils import read_fullscreen_config, read_window_geometry, save_window_geometry, read_auto_fullscreen_gamepad, read_rumble_config, read_gamepad_type
|
||||
from portprotonqt.dialogs import AddGameDialog, WinetricksDialog
|
||||
from portprotonqt.virtual_keyboard import VirtualKeyboard
|
||||
|
||||
@@ -87,8 +87,13 @@ class InputManager(QObject):
|
||||
super().__init__(cast(QObject, main_window))
|
||||
self._parent = main_window
|
||||
self._gamepad_handling_enabled = True
|
||||
self.gamepad_type = GamepadType.UNKNOWN
|
||||
# Ensure attributes exist on main_window
|
||||
type_str = read_gamepad_type()
|
||||
if type_str == "playstation":
|
||||
self.gamepad_type = GamepadType.PLAYSTATION
|
||||
elif type_str == "xbox":
|
||||
self.gamepad_type = GamepadType.XBOX
|
||||
else:
|
||||
self.gamepad_type = GamepadType.UNKNOWN
|
||||
self._parent.currentDetailPage = getattr(self._parent, 'currentDetailPage', None)
|
||||
self._parent.current_exec_line = getattr(self._parent, 'current_exec_line', None)
|
||||
self._parent.current_add_game_dialog = getattr(self._parent, 'current_add_game_dialog', None)
|
||||
@@ -271,38 +276,6 @@ class InputManager(QObject):
|
||||
elif current_row_idx == 0:
|
||||
self._parent.tabButtons[tab_index].setFocus(Qt.FocusReason.OtherFocusReason)
|
||||
|
||||
def detect_gamepad_type(self, device: InputDevice) -> GamepadType:
|
||||
"""
|
||||
Определяет тип геймпада по capabilities
|
||||
"""
|
||||
caps = device.capabilities()
|
||||
keys = set(caps.get(ecodes.EV_KEY, []))
|
||||
|
||||
# Для EV_ABS вытаскиваем только коды (первый элемент кортежа)
|
||||
abs_axes = {a if isinstance(a, int) else a[0] for a in caps.get(ecodes.EV_ABS, [])}
|
||||
|
||||
# Xbox layout
|
||||
if {ecodes.BTN_SOUTH, ecodes.BTN_EAST, ecodes.BTN_NORTH, ecodes.BTN_WEST}.issubset(keys):
|
||||
if {ecodes.ABS_X, ecodes.ABS_Y, ecodes.ABS_RX, ecodes.ABS_RY}.issubset(abs_axes):
|
||||
self.gamepad_type = GamepadType.XBOX
|
||||
return GamepadType.XBOX
|
||||
|
||||
# PlayStation layout
|
||||
if ecodes.BTN_TOUCH in keys or (ecodes.BTN_DPAD_UP in keys and ecodes.BTN_EAST in keys):
|
||||
self.gamepad_type = GamepadType.PLAYSTATION
|
||||
logger.info(f"Detected {self.gamepad_type.value} controller: {device.name}")
|
||||
return GamepadType.PLAYSTATION
|
||||
|
||||
# Steam Controller / Deck (трекпады)
|
||||
if any(a for a in abs_axes if a >= ecodes.ABS_MT_SLOT):
|
||||
self.gamepad_type = GamepadType.XBOX
|
||||
logger.info(f"Detected {self.gamepad_type.value} controller: {device.name}")
|
||||
return GamepadType.XBOX
|
||||
|
||||
# Fallback
|
||||
self.gamepad_type = GamepadType.XBOX
|
||||
return GamepadType.XBOX
|
||||
|
||||
def enable_file_explorer_mode(self, file_explorer):
|
||||
"""Настройка обработки геймпада для FileExplorer"""
|
||||
try:
|
||||
@@ -1369,8 +1342,6 @@ class InputManager(QObject):
|
||||
new_gamepad = self.find_gamepad()
|
||||
if new_gamepad and new_gamepad != self.gamepad:
|
||||
logger.info(f"Gamepad connected: {new_gamepad.name}")
|
||||
self.detect_gamepad_type(new_gamepad)
|
||||
logger.info(f"Detected gamepad type: {self.gamepad_type.value}")
|
||||
self.stop_rumble()
|
||||
self.gamepad = new_gamepad
|
||||
if self.gamepad_thread:
|
||||
|
@@ -29,7 +29,7 @@ from portprotonqt.config_utils import (
|
||||
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, read_rumble_config, save_rumble_config
|
||||
clear_cache, read_auto_fullscreen_gamepad, save_auto_fullscreen_gamepad, read_rumble_config, save_rumble_config, read_gamepad_type, save_gamepad_type
|
||||
)
|
||||
from portprotonqt.localization import _, get_egs_language, read_metadata_translations
|
||||
from portprotonqt.howlongtobeat_api import HowLongToBeat
|
||||
@@ -1784,7 +1784,22 @@ class MainWindow(QMainWindow):
|
||||
self.gamesDisplayCombo.setCurrentIndex(idx)
|
||||
formLayout.addRow(self.gamesDisplayTitle, self.gamesDisplayCombo)
|
||||
|
||||
# 4. Proxy settings
|
||||
# 4 Gamepad Type
|
||||
self.gamepadTypeCombo = QComboBox()
|
||||
self.gamepadTypeCombo.addItems(["Xbox", "PlayStation"])
|
||||
self.gamepadTypeCombo.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||
self.gamepadTypeCombo.setStyleSheet(self.theme.SETTINGS_COMBO_STYLE)
|
||||
self.gamepadTypeTitle = QLabel(_("Gamepad Type:"))
|
||||
self.gamepadTypeTitle.setStyleSheet(self.theme.PARAMS_TITLE_STYLE)
|
||||
self.gamepadTypeTitle.setFocusPolicy(Qt.FocusPolicy.NoFocus)
|
||||
current_type_str = read_gamepad_type()
|
||||
if current_type_str == "playstation":
|
||||
self.gamepadTypeCombo.setCurrentText("PlayStation")
|
||||
else:
|
||||
self.gamepadTypeCombo.setCurrentText("Xbox")
|
||||
formLayout.addRow(self.gamepadTypeTitle, self.gamepadTypeCombo)
|
||||
|
||||
# 5. Proxy settings
|
||||
self.proxyUrlEdit = CustomLineEdit(self, theme=self.theme)
|
||||
self.proxyUrlEdit.setPlaceholderText(_("Proxy URL"))
|
||||
self.proxyUrlEdit.setStyleSheet(self.theme.PROXY_INPUT_STYLE)
|
||||
@@ -1816,7 +1831,7 @@ class MainWindow(QMainWindow):
|
||||
self.proxyPasswordTitle.setFocusPolicy(Qt.FocusPolicy.NoFocus)
|
||||
formLayout.addRow(self.proxyPasswordTitle, self.proxyPasswordEdit)
|
||||
|
||||
# 5. Fullscreen setting for application
|
||||
# 6. Fullscreen setting for application
|
||||
self.fullscreenCheckBox = QCheckBox(_("Launch Application in Fullscreen"))
|
||||
self.fullscreenCheckBox.setStyleSheet(self.theme.SETTINGS_CHECKBOX_STYLE)
|
||||
self.fullscreenCheckBox.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||
@@ -1827,7 +1842,7 @@ class MainWindow(QMainWindow):
|
||||
self.fullscreenCheckBox.setChecked(current_fullscreen)
|
||||
formLayout.addRow(self.fullscreenTitle, self.fullscreenCheckBox)
|
||||
|
||||
# 6. Automatic fullscreen on gamepad connection
|
||||
# 7. Automatic fullscreen on gamepad connection
|
||||
self.autoFullscreenGamepadCheckBox = QCheckBox(_("Auto Fullscreen on Gamepad connected"))
|
||||
self.autoFullscreenGamepadCheckBox.setStyleSheet(self.theme.SETTINGS_CHECKBOX_STYLE)
|
||||
self.autoFullscreenGamepadCheckBox.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||
@@ -1839,7 +1854,7 @@ class MainWindow(QMainWindow):
|
||||
self.autoFullscreenGamepadCheckBox.setChecked(current_auto_fullscreen)
|
||||
formLayout.addRow(self.autoFullscreenGamepadTitle, self.autoFullscreenGamepadCheckBox)
|
||||
|
||||
# 7. Gamepad haptic feedback config
|
||||
# 8. Gamepad haptic feedback config
|
||||
self.gamepadRumbleCheckBox = QCheckBox(_("Gamepad haptic feedback"))
|
||||
self.gamepadRumbleCheckBox.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||
self.gamepadRumbleCheckBox.setStyleSheet(self.theme.SETTINGS_CHECKBOX_STYLE)
|
||||
@@ -1850,7 +1865,7 @@ class MainWindow(QMainWindow):
|
||||
self.gamepadRumbleCheckBox.setChecked(current_rumble_state)
|
||||
formLayout.addRow(self.gamepadRumbleTitle, self.gamepadRumbleCheckBox)
|
||||
|
||||
# # 8. Legendary Authentication
|
||||
# # 9. Legendary Authentication
|
||||
# self.legendaryAuthButton = AutoSizeButton(
|
||||
# _("Open Legendary Login"),
|
||||
# icon=self.theme_manager.get_icon("login")self.theme_manager.get_icon("login")
|
||||
@@ -2021,8 +2036,6 @@ class MainWindow(QMainWindow):
|
||||
old_filter = self.current_display_filter
|
||||
save_display_filter(filter_key)
|
||||
|
||||
save_display_filter(filter_key)
|
||||
|
||||
proxy_url = self.proxyUrlEdit.text().strip()
|
||||
proxy_user = self.proxyUserEdit.text().strip()
|
||||
proxy_password = self.proxyPasswordEdit.text().strip()
|
||||
@@ -2037,6 +2050,19 @@ class MainWindow(QMainWindow):
|
||||
rumble_enabled = self.gamepadRumbleCheckBox.isChecked()
|
||||
save_rumble_config(rumble_enabled)
|
||||
|
||||
gamepad_type_text = self.gamepadTypeCombo.currentText()
|
||||
gpad_type = "playstation" if gamepad_type_text == "PlayStation" else "xbox"
|
||||
save_gamepad_type(gpad_type)
|
||||
|
||||
if hasattr(self, 'input_manager'):
|
||||
if gpad_type == "playstation":
|
||||
self.input_manager.gamepad_type = GamepadType.PLAYSTATION
|
||||
elif gpad_type == "xbox":
|
||||
self.input_manager.gamepad_type = GamepadType.XBOX
|
||||
else:
|
||||
self.input_manager.gamepad_type = GamepadType.UNKNOWN
|
||||
self.updateControlHints()
|
||||
|
||||
if filter_key != old_filter:
|
||||
for card in self.game_library_manager.game_card_cache.values():
|
||||
card.update_badge_visibility(filter_key)
|
||||
|
Reference in New Issue
Block a user