From d656e2b07399ffdf1f9d5ab65736e5674349a717 Mon Sep 17 00:00:00 2001 From: mirkobrombin Date: Tue, 15 Oct 2024 09:54:46 +0200 Subject: [PATCH] feat[close #3515]: Win11 support --- bottles/backend/managers/dependency.py | 2 +- bottles/backend/managers/manager.py | 13 ++++----- bottles/backend/wine/catalogs.py | 8 +++--- bottles/backend/wine/regkeys.py | 11 ++++++++ bottles/backend/wine/winecfg.py | 28 ++++++++++++++++++++ bottles/backend/wine/wineprogram.py | 5 +++- bottles/frontend/cli/cli.py | 2 +- bottles/frontend/views/bottle_preferences.py | 2 +- 8 files changed, 57 insertions(+), 14 deletions(-) diff --git a/bottles/backend/managers/dependency.py b/bottles/backend/managers/dependency.py index 7ae28f34315..a63815e6cdb 100644 --- a/bottles/backend/managers/dependency.py +++ b/bottles/backend/managers/dependency.py @@ -632,7 +632,7 @@ def __step_replace_font(config: BottleConfig, step: dict): def __step_set_windows(config: BottleConfig, step: dict): """Set the Windows version.""" rk = RegKeys(config) - rk.set_windows(step.get("version")) + rk.lg_set_windows(step.get("version")) return True @staticmethod diff --git a/bottles/backend/managers/manager.py b/bottles/backend/managers/manager.py index 67ba635141c..2a923ec8a60 100644 --- a/bottles/backend/managers/manager.py +++ b/bottles/backend/managers/manager.py @@ -819,7 +819,7 @@ def check_bottles(self, silent: bool = False): def process_bottle(bottle): _name = bottle - _bottle = os.path.join(Paths.bottles, bottle) + _bottle = str(os.path.join(Paths.bottles, bottle)) _placeholder = os.path.join(_bottle, "placeholder.yml") _config = os.path.join(_bottle, "bottle.yml") @@ -852,7 +852,7 @@ def process_bottle(bottle): # Check if the path in the bottle config corresponds to the folder name # if not, change the config to reflect the folder name - # if the folder name is "illegal" accross all platforms, rename the folder + # if the folder name is "illegal" across all platforms, rename the folder # "universal" platform works for all filesystem/OSes sane_name = pathvalidate.sanitize_filepath(_name, platform="universal") @@ -864,7 +864,9 @@ def process_bottle(bottle): if sane_name != _name: # This hopefully doesn't happen, but it's managed logging.warning(f"Broken path in bottle {_name}, fixing...") - shutil.move(_bottle, os.path.join(Paths.bottles, sane_name)) + shutil.move( + _bottle, str(os.path.join(Paths.bottles, sane_name)) + ) # Restart the process bottle function. Normally, can't be recursive! process_bottle(sane_name) return @@ -1112,8 +1114,7 @@ def create_bottle_from_config(self, config: BottleConfig) -> bool: res = self.dependency_manager.install(config, dep) if not res.ok: logging.error( - _("Failed to install dependency: %s") - % dep.get("Description", "n/a"), + _("Failed to install dependency: %s") % dependency, jn=True, ) return False @@ -1364,7 +1365,7 @@ def components_check(): if ( "soda" not in runner_name.lower() and "caffe" not in runner_name.lower() ): # Caffe/Soda came with win10 by default - rk.set_windows(config.Windows) + rk.lg_set_windows(config.Windows) wineboot.update() FileUtils.wait_for_files(reg_files) diff --git a/bottles/backend/wine/catalogs.py b/bottles/backend/wine/catalogs.py index 19a3d314b2d..1190bb8dca7 100644 --- a/bottles/backend/wine/catalogs.py +++ b/bottles/backend/wine/catalogs.py @@ -4,7 +4,7 @@ "CSDVersionHex": "0", "CurrentBuild": "22000", "CurrentBuildNumber": "22000", - "CurrentVersion": "10.0", + "CurrentVersion": "6.3", "CurrentMinorVersionNumber": "0", "CurrentMajorVersionNumber": "a", # 10 "ProductType": "WinNT", @@ -13,9 +13,9 @@ "win10": { "CSDVersion": "", "CSDVersionHex": "0", - "CurrentBuild": "17763", - "CurrentBuildNumber": "17763", - "CurrentVersion": "10.0", + "CurrentBuild": "19043", + "CurrentBuildNumber": "19043", + "CurrentVersion": "6.3", "CurrentMinorVersionNumber": "0", "CurrentMajorVersionNumber": "a", # 10 "ProductType": "WinNT", diff --git a/bottles/backend/wine/regkeys.py b/bottles/backend/wine/regkeys.py index 740f64215c4..18a56527731 100644 --- a/bottles/backend/wine/regkeys.py +++ b/bottles/backend/wine/regkeys.py @@ -4,6 +4,7 @@ from bottles.backend.wine.catalogs import win_versions from bottles.backend.wine.reg import Reg from bottles.backend.wine.wineboot import WineBoot +from bottles.backend.wine.winecfg import WineCfg logging = Logger() @@ -14,6 +15,16 @@ def __init__(self, config: BottleConfig): self.config = config self.reg = Reg(self.config) + def lg_set_windows(self, version: str): + """ + Legacy method to change Windows version in a bottle using + the Wine Configuration tool. + """ + winecfg = WineCfg(self.config) + res = winecfg.set_windows_version(version) + if not res.ok: + raise ValueError(f"Failed to set Windows version to {version}") + def set_windows(self, version: str): """ Change Windows version in a bottle from the given diff --git a/bottles/backend/wine/winecfg.py b/bottles/backend/wine/winecfg.py index 1644992dae5..242c23a7aac 100644 --- a/bottles/backend/wine/winecfg.py +++ b/bottles/backend/wine/winecfg.py @@ -1,5 +1,10 @@ +import os +import time + from bottles.backend.logger import Logger from bottles.backend.wine.wineprogram import WineProgram +from bottles.backend.wine.winedbg import WineDbg +from bottles.backend.wine.wineboot import WineBoot logging = Logger() @@ -7,3 +12,26 @@ class WineCfg(WineProgram): program = "Wine Configuration" command = "winecfg" + + def set_windows_version(self, version): + logging.info(f"Setting Windows version to {version}") + + winedbg = WineDbg(self.config) + wineboot = WineBoot(self.config) + + wineboot.kill() + + res = self.launch( + args=f"-v {version}", + communicate=True, + environment={ + "DISPLAY": os.environ.get("DISPLAY", ":0"), + "WAYLAND_DISPLAY": os.environ.get("WAYLAND_DISPLAY", ""), + }, + action_name="set_windows_version", + ) + + winedbg.wait_for_process("winecfg") + wineboot.restart() + + return res diff --git a/bottles/backend/wine/wineprogram.py b/bottles/backend/wine/wineprogram.py index 2a848e0b683..86166eca48c 100644 --- a/bottles/backend/wine/wineprogram.py +++ b/bottles/backend/wine/wineprogram.py @@ -74,7 +74,10 @@ def launch( post_script=post_script, cwd=cwd, arguments=program_args, - ).run() + ) + + # logging.info("Executing command:", res.command) + res = res.run() return res def launch_terminal(self, args: Optional[str] = None): diff --git a/bottles/frontend/cli/cli.py b/bottles/frontend/cli/cli.py index 54008721465..bda3e46285e 100644 --- a/bottles/frontend/cli/cli.py +++ b/bottles/frontend/cli/cli.py @@ -551,7 +551,7 @@ def edit_bottle(self): mng.update_config(bottle, k, v, scope="Environment_Variables") if _win is not None: - RegKeys(bottle).set_windows(_win) + RegKeys(bottle).lg_set_windows(_win) if _runner is not None: Runner.runner_update(bottle, mng, _runner) diff --git a/bottles/frontend/views/bottle_preferences.py b/bottles/frontend/views/bottle_preferences.py index e23e6372828..3d6e43437b3 100644 --- a/bottles/frontend/views/bottle_preferences.py +++ b/bottles/frontend/views/bottle_preferences.py @@ -1008,7 +1008,7 @@ def update(result, error=False): config=self.config, key="Windows", value=windows_version ).data["config"] - RunAsync(rk.set_windows, callback=update, version=windows_version) + RunAsync(rk.lg_set_windows, callback=update, version=windows_version) break def __set_language(self, *_args):