2022-03-15 07:21:03 +13:00
|
|
|
import os
|
|
|
|
from logging import getLogger
|
2023-09-20 10:39:15 +12:00
|
|
|
from typing import Tuple, Union, Optional
|
2022-03-15 07:21:03 +13:00
|
|
|
|
2023-12-19 04:34:18 +13:00
|
|
|
from PyQt5.QtCore import pyqtSignal, Qt
|
2023-09-20 10:39:15 +12:00
|
|
|
from PyQt5.QtGui import QShowEvent
|
2024-02-18 23:44:04 +13:00
|
|
|
from PyQt5.QtWidgets import QGroupBox, QFileDialog, QFormLayout, QComboBox
|
2022-03-15 07:21:03 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
from rare.models.wrapper import Wrapper, WrapperType
|
|
|
|
from rare.shared import RareCore
|
|
|
|
from rare.shared.wrappers import Wrappers
|
|
|
|
from rare.utils import config_helper as config
|
2024-02-18 23:44:04 +13:00
|
|
|
from rare.utils.compat import steam
|
2024-02-13 05:30:23 +13:00
|
|
|
from rare.utils.paths import proton_compat_dir
|
2023-02-19 04:29:41 +13:00
|
|
|
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
2022-03-15 07:21:03 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
logger = getLogger("ProtonSettings")
|
2022-03-15 07:21:03 +13:00
|
|
|
|
2022-03-29 10:14:11 +13:00
|
|
|
|
2023-03-15 00:19:51 +13:00
|
|
|
class ProtonSettings(QGroupBox):
|
2023-04-01 00:03:32 +13:00
|
|
|
# str: option key
|
2023-09-20 10:39:15 +12:00
|
|
|
environ_changed: pyqtSignal = pyqtSignal(str)
|
|
|
|
# bool: state
|
|
|
|
tool_enabled: pyqtSignal = pyqtSignal(bool)
|
2022-03-15 07:21:03 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(ProtonSettings, self).__init__(parent=parent)
|
2024-01-25 04:58:26 +13:00
|
|
|
self.setTitle(self.tr("Proton settings"))
|
2022-03-15 07:21:03 +13:00
|
|
|
|
2023-12-19 04:34:18 +13:00
|
|
|
self.tool_combo = QComboBox(self)
|
|
|
|
self.tool_combo.currentIndexChanged.connect(self.__on_proton_changed)
|
|
|
|
|
|
|
|
self.tool_prefix = PathEdit(
|
2023-03-16 09:49:18 +13:00
|
|
|
file_mode=QFileDialog.DirectoryOnly,
|
2022-03-15 07:21:03 +13:00
|
|
|
edit_func=self.proton_prefix_edit,
|
|
|
|
save_func=self.proton_prefix_save,
|
2023-09-20 10:39:15 +12:00
|
|
|
placeholder=self.tr("Please select path for proton prefix"),
|
2023-12-19 04:34:18 +13:00
|
|
|
parent=self
|
2022-03-15 07:21:03 +13:00
|
|
|
)
|
2023-12-19 04:34:18 +13:00
|
|
|
|
|
|
|
layout = QFormLayout(self)
|
|
|
|
layout.addRow(self.tr("Proton tool"), self.tool_combo)
|
|
|
|
layout.addRow(self.tr("Compat data"), self.tool_prefix)
|
2023-12-20 07:53:21 +13:00
|
|
|
layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
|
2023-12-19 04:34:18 +13:00
|
|
|
layout.setLabelAlignment(Qt.AlignRight | Qt.AlignVCenter)
|
|
|
|
layout.setFormAlignment(Qt.AlignLeading | Qt.AlignTop)
|
2022-03-15 07:21:03 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
self.app_name: str = "default"
|
|
|
|
self.core = RareCore.instance().core()
|
|
|
|
self.wrappers: Wrappers = RareCore.instance().wrappers()
|
|
|
|
self.tool_wrapper: Optional[Wrapper] = None
|
|
|
|
|
|
|
|
def showEvent(self, a0: QShowEvent) -> None:
|
|
|
|
if a0.spontaneous():
|
|
|
|
return super().showEvent(a0)
|
2023-12-19 04:34:18 +13:00
|
|
|
|
|
|
|
self.tool_combo.blockSignals(True)
|
|
|
|
self.tool_combo.clear()
|
|
|
|
self.tool_combo.addItem(self.tr("Don't use a compatibility tool"), None)
|
2024-02-18 23:44:04 +13:00
|
|
|
tools = steam.find_tools()
|
2023-09-20 10:39:15 +12:00
|
|
|
for tool in tools:
|
2023-12-19 04:34:18 +13:00
|
|
|
self.tool_combo.addItem(tool.name, tool)
|
2023-09-20 10:39:15 +12:00
|
|
|
try:
|
|
|
|
wrapper = next(
|
|
|
|
filter(lambda w: w.is_compat_tool, self.wrappers.get_game_wrapper_list(self.app_name))
|
|
|
|
)
|
|
|
|
self.tool_wrapper = wrapper
|
|
|
|
tool = next(filter(lambda t: t.checksum == wrapper.checksum, tools))
|
2023-12-19 04:34:18 +13:00
|
|
|
index = self.tool_combo.findData(tool)
|
2023-09-20 10:39:15 +12:00
|
|
|
except StopIteration:
|
|
|
|
index = 0
|
2023-12-19 04:34:18 +13:00
|
|
|
self.tool_combo.setCurrentIndex(index)
|
|
|
|
self.tool_combo.blockSignals(False)
|
|
|
|
|
|
|
|
enabled = bool(self.tool_combo.currentData(Qt.UserRole))
|
|
|
|
self.tool_prefix.blockSignals(True)
|
|
|
|
self.tool_prefix.setText(config.get_proton_compatdata(self.app_name, fallback=""))
|
|
|
|
self.tool_prefix.setEnabled(enabled)
|
|
|
|
self.tool_prefix.blockSignals(False)
|
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
super().showEvent(a0)
|
|
|
|
|
|
|
|
def __on_proton_changed(self, index):
|
2024-02-18 23:44:04 +13:00
|
|
|
steam_tool: Union[steam.ProtonTool, steam.CompatibilityTool] = self.tool_combo.itemData(index)
|
2023-09-20 10:39:15 +12:00
|
|
|
|
2024-02-18 23:44:04 +13:00
|
|
|
steam_environ = steam.get_steam_environment(steam_tool, self.tool_prefix.text())
|
2023-09-20 10:39:15 +12:00
|
|
|
for key, value in steam_environ.items():
|
2023-12-19 04:34:18 +13:00
|
|
|
config.save_envvar(self.app_name, key, value)
|
2023-09-20 10:39:15 +12:00
|
|
|
self.environ_changed.emit(key)
|
|
|
|
|
|
|
|
wrappers = self.wrappers.get_game_wrapper_list(self.app_name)
|
|
|
|
if self.tool_wrapper and self.tool_wrapper in wrappers:
|
|
|
|
wrappers.remove(self.tool_wrapper)
|
|
|
|
if steam_tool is None:
|
|
|
|
self.tool_wrapper = None
|
2022-03-21 10:49:00 +13:00
|
|
|
else:
|
2023-09-20 10:39:15 +12:00
|
|
|
wrapper = Wrapper(
|
|
|
|
command=steam_tool.command(), name=steam_tool.name, wtype=WrapperType.COMPAT_TOOL
|
2022-03-21 10:49:00 +13:00
|
|
|
)
|
2023-09-20 10:39:15 +12:00
|
|
|
wrappers.append(wrapper)
|
|
|
|
self.tool_wrapper = wrapper
|
|
|
|
self.wrappers.set_game_wrapper_list(self.app_name, wrappers)
|
2023-04-01 00:03:32 +13:00
|
|
|
|
2023-12-19 04:34:18 +13:00
|
|
|
self.tool_prefix.setEnabled(steam_tool is not None)
|
2024-02-13 05:30:23 +13:00
|
|
|
if steam_tool:
|
|
|
|
if not (compatdata_path := config.get_proton_compatdata(self.app_name, fallback="")):
|
|
|
|
compatdata_path = proton_compat_dir(self.app_name)
|
|
|
|
config.save_proton_compatdata(self.app_name, str(compatdata_path))
|
|
|
|
target = compatdata_path.joinpath("pfx")
|
|
|
|
if not target.is_dir():
|
|
|
|
os.makedirs(target, exist_ok=True)
|
|
|
|
self.tool_prefix.setText(str(compatdata_path))
|
|
|
|
else:
|
|
|
|
self.tool_prefix.setText("")
|
2022-03-21 10:49:00 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
self.tool_enabled.emit(steam_tool is not None)
|
2022-03-15 07:21:03 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
@staticmethod
|
|
|
|
def proton_prefix_edit(text: str) -> Tuple[bool, str, int]:
|
2022-03-15 07:21:03 +13:00
|
|
|
if not text:
|
2023-03-15 00:19:51 +13:00
|
|
|
return False, text, IndicatorReasonsCommon.EMPTY
|
2022-03-15 07:21:03 +13:00
|
|
|
parent_dir = os.path.dirname(text)
|
2023-02-19 01:33:42 +13:00
|
|
|
return os.path.exists(parent_dir), text, IndicatorReasonsCommon.DIR_NOT_EXISTS
|
2022-03-15 07:21:03 +13:00
|
|
|
|
|
|
|
def proton_prefix_save(self, text: str):
|
2023-03-15 00:19:51 +13:00
|
|
|
if not text:
|
2022-03-21 10:49:00 +13:00
|
|
|
return
|
2023-12-19 04:34:18 +13:00
|
|
|
config.save_proton_compatdata(self.app_name, text)
|
2023-04-01 00:03:32 +13:00
|
|
|
self.environ_changed.emit("STEAM_COMPAT_DATA_PATH")
|
2022-03-15 07:21:03 +13:00
|
|
|
|