From a8f76af6bcfc4f3ea58564c99ca643fe6914634e Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Sat, 5 Oct 2024 11:14:46 -0600 Subject: [PATCH] GUI: Support saving settings on-model --- CHANGELOG.md | 10 +++ opencore_legacy_patcher/constants.py | 4 +- opencore_legacy_patcher/efi_builder/misc.py | 2 +- opencore_legacy_patcher/support/defaults.py | 84 +++++++++++++++++-- .../kernel_collection/auxiliary.py | 2 +- .../wx_gui/gui_settings.py | 24 +++++- 6 files changed, 113 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b9b518b62..22bd0363fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ # OpenCore Legacy Patcher changelog ## 2.1.0 +- Disable FeatureUnlock by default + - Intended to maintain long term stability + - If features unlocked by FeatureUnlock desired, can be enabled in settings +- Disable mediaanalysisd on Metal 3802-based GPUs + - Intended to maintain long term stability + - If Live Text support desired, can be enabled in settings +- Support for retaining GUI settings when building on-model + - When switching to a different model, model-specific GUI settings will be reset + - Note resetting saved settings not implemented yet + - Delete `/Users/Shared/.com.dortania.opencore-legacy-patcher.plist` and restart app to reset settings ## 2.0.2 - Fix Nvidia Kepler patches not installing on Monterey diff --git a/opencore_legacy_patcher/constants.py b/opencore_legacy_patcher/constants.py index fc884ad89e..780d34ad8f 100644 --- a/opencore_legacy_patcher/constants.py +++ b/opencore_legacy_patcher/constants.py @@ -186,8 +186,8 @@ def __init__(self) -> None: self.custom_board_serial_number: str = "" # Set SMBIOS board serial number ## FeatureUnlock Settings - self.fu_status: bool = True # Enable FeatureUnlock - self.fu_arguments: str = None # Set FeatureUnlock arguments + self.fu_status: bool = False # Enable FeatureUnlock + self.fu_arguments: str = None # Set FeatureUnlock arguments ## Security Settings self.sip_status: bool = True # System Integrity Protection diff --git a/opencore_legacy_patcher/efi_builder/misc.py b/opencore_legacy_patcher/efi_builder/misc.py index a930f67455..29897abedb 100644 --- a/opencore_legacy_patcher/efi_builder/misc.py +++ b/opencore_legacy_patcher/efi_builder/misc.py @@ -72,7 +72,7 @@ def _feature_unlock_handling(self) -> None: return support.BuildSupport(self.model, self.constants, self.config).enable_kext("FeatureUnlock.kext", self.constants.featureunlock_version, self.constants.featureunlock_path) - if self.constants.fu_arguments is not None: + if self.constants.fu_arguments is not None and self.constants.fu_arguments != "": logging.info(f"- Adding additional FeatureUnlock args: {self.constants.fu_arguments}") self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += self.constants.fu_arguments diff --git a/opencore_legacy_patcher/support/defaults.py b/opencore_legacy_patcher/support/defaults.py index d9e04f2b43..5020677140 100644 --- a/opencore_legacy_patcher/support/defaults.py +++ b/opencore_legacy_patcher/support/defaults.py @@ -2,8 +2,12 @@ defaults.py: Generate default data for host/target """ +import logging +import plistlib import subprocess +from pathlib import Path + from .. import constants from ..detections import device_probe @@ -22,19 +26,52 @@ class GenerateDefaults: - def __init__(self, model: str, host_is_target: bool, global_constants: constants.Constants) -> None: + def __init__(self, model: str, host_is_target: bool, global_constants: constants.Constants, ignore_settings_file: bool = False) -> None: self.constants: constants.Constants = global_constants self.model: str = model self.host_is_target: bool = host_is_target + self.ignore_settings_file: bool = ignore_settings_file # Reset Variables self.constants.sip_status = True self.constants.secure_status = False self.constants.disable_cs_lv = False self.constants.disable_amfi = False - self.constants.fu_status = True + self.constants.fu_status = False + + # Reset Variables - GUI override + # Match constants.py for model specific settings + # TODO: Write a sane system for this... + self.constants.firewire_boot = False + self.constants.xhci_boot = False + self.constants.nvme_boot = False + self.constants.force_quad_thread = False + self.constants.enable_wake_on_wlan = False + self.constants.disable_tb = False + self.constants.dGPU_switch = False + self.constants.disallow_cpufriend = False + self.constants.disable_mediaanalysisd = False + self.constants.set_alc_usage = True + self.constants.nvram_write = True + self.constants.allow_nvme_fixing = True + self.constants.allow_3rd_party_drives = True + self.constants.disable_fw_throttle = False + self.constants.software_demux = False + self.constants.disable_connectdrivers = False + self.constants.amd_gop_injection = False + self.constants.nvidia_kepler_gop_injection = False + self.constants.disable_cs_lv = False + self.constants.disable_amfi = False + self.constants.secure_status = False + self.constants.serial_settings = "None" + self.constants.override_smbios = "Default" + self.constants.allow_native_spoofs = False + self.constants.allow_oc_everywhere = False + self.constants.sip_status = True + self.constants.custom_sip_value = None + self.constants.fu_arguments = None @@ -55,6 +92,8 @@ def __init__(self, model: str, host_is_target: bool, global_constants: constants self._misc_hardwares_probe() self._smbios_probe() self._check_amfipass_supported() + self._load_gui_defaults() + def _general_probe(self) -> None: """ @@ -185,7 +224,6 @@ def _networking_probe(self) -> None: is_modern_wifi = True else: - print("Checking WiFi") if self.model not in smbios_data.smbios_dictionary: return if ( @@ -217,11 +255,10 @@ def _networking_probe(self) -> None: self.constants.disable_cs_lv = True self.constants.disable_amfi = True - if is_legacy_wifi is True: - # 13.0: Enabling AirPlay to Mac patches breaks Control Center on legacy chipsets - # AirPlay to Mac was unsupported regardless, so we can safely disable it - self.constants.fu_status = True - self.constants.fu_arguments = " -disable_sidecar_mac" + # if is_legacy_wifi is True: + # # 13.0: Enabling AirPlay to Mac patches breaks Control Center on legacy chipsets + # # AirPlay to Mac was unsupported regardless, so we can safely disable it + # self.constants.fu_arguments = " -disable_sidecar_mac" def _misc_hardwares_probe(self) -> None: @@ -274,6 +311,7 @@ def _gpu_probe(self) -> None: device_probe.NVIDIA.Archs.Kepler, ]: self.constants.disable_amfi = True + self.constants.disable_mediaanalysisd = True if arch in [ device_probe.AMD.Archs.Legacy_GCN_7000, @@ -365,3 +403,33 @@ def _check_amfipass_supported(self) -> None: self.constants.disable_amfi = False self.constants.disable_cs_lv = False + + + def _load_gui_defaults(self) -> None: + """ + Load GUI defaults from global settings + """ + if not self.host_is_target: + return + if self.ignore_settings_file is True: + return + + settings_plist = global_settings.GlobalEnviromentSettings().global_settings_plist + if not Path(settings_plist).exists(): + return + + try: + plist = plistlib.load(Path(settings_plist).open("rb")) + except Exception as e: + logging.error("Error: Unable to read global settings file") + logging.error(e) + return + + for key in plist: + if not key.startswith("GUI:"): + continue + + constants_key = key.replace("GUI:", "") + if hasattr(self.constants, constants_key): + logging.info(f"Setting {constants_key} to {plist[key]}") + setattr(self.constants, constants_key, plist[key]) \ No newline at end of file diff --git a/opencore_legacy_patcher/sys_patch/kernelcache/kernel_collection/auxiliary.py b/opencore_legacy_patcher/sys_patch/kernelcache/kernel_collection/auxiliary.py index 61ad64917d..2ac517fea7 100644 --- a/opencore_legacy_patcher/sys_patch/kernelcache/kernel_collection/auxiliary.py +++ b/opencore_legacy_patcher/sys_patch/kernelcache/kernel_collection/auxiliary.py @@ -40,7 +40,7 @@ def _force_auxiliary_usage(self) -> bool: collection to be used. """ - print("- Forcing Auxiliary Kernel Collection usage") + logging.info("- Forcing Auxiliary Kernel Collection usage") result = subprocess_wrapper.run_as_root(["/usr/bin/killall", "syspolicyd", "kernelmanagerd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if result.returncode != 0: logging.info("- Unable to kill syspolicyd and kernelmanagerd") diff --git a/opencore_legacy_patcher/wx_gui/gui_settings.py b/opencore_legacy_patcher/wx_gui/gui_settings.py index 627e4eca84..89d0bdb450 100644 --- a/opencore_legacy_patcher/wx_gui/gui_settings.py +++ b/opencore_legacy_patcher/wx_gui/gui_settings.py @@ -1106,6 +1106,7 @@ def on_spinctrl(self, event: wx.Event, label: str) -> None: def _update_setting(self, variable, value): logging.info(f"Updating Local Setting: {variable} = {value}") setattr(self.constants, variable, value) + global_settings.GlobalEnviromentSettings().write_property(f"GUI:{variable}", value) def _update_global_settings(self, variable, value, global_setting = None): @@ -1160,11 +1161,16 @@ def on_sip_value(self, event: wx.Event) -> None: if hex(self.sip_value) == "0x0": self.constants.custom_sip_value = None self.constants.sip_status = True + global_settings.GlobalEnviromentSettings().write_property("GUI:custom_sip_value", None) + global_settings.GlobalEnviromentSettings().write_property("GUI:sip_status", True) elif hex(self.sip_value) == "0x803": self.constants.custom_sip_value = None self.constants.sip_status = False + global_settings.GlobalEnviromentSettings().write_property("GUI:custom_sip_value", None) + global_settings.GlobalEnviromentSettings().write_property("GUI:sip_status", False) else: self.constants.custom_sip_value = hex(self.sip_value) + global_settings.GlobalEnviromentSettings().write_property("GUI:custom_sip_value", hex(self.sip_value)) self.sip_configured_label.SetLabel(f"Currently configured SIP: {hex(self.sip_value)}") @@ -1191,10 +1197,12 @@ def on_generate_serial_number(self, event: wx.Event) -> None: def on_custom_serial_number_textbox(self, event: wx.Event) -> None: self.constants.custom_serial_number = event.GetEventObject().GetValue() + global_settings.GlobalEnviromentSettings().write_property("GUI:custom_serial_number", self.constants.custom_serial_number) def on_custom_board_serial_number_textbox(self, event: wx.Event) -> None: self.constants.custom_board_serial_number = event.GetEventObject().GetValue() + global_settings.GlobalEnviromentSettings().write_property("GUI:custom_board_serial_number", self.constants.custom_board_serial_number) def _populate_fu_override(self, panel: wx.Panel) -> None: @@ -1207,7 +1215,7 @@ def _populate_fu_override(self, panel: wx.Panel) -> None: gpu_combo_box.Bind(wx.EVT_CHOICE, self.fu_selection_click) if self.constants.fu_status is False: gpu_combo_box.SetStringSelection("Disabled") - elif self.constants.fu_arguments is None: + elif self.constants.fu_arguments is None or self.constants.fu_arguments == "": gpu_combo_box.SetStringSelection("Enabled") else: gpu_combo_box.SetStringSelection("Partial") @@ -1219,17 +1227,23 @@ def fu_selection_click(self, event: wx.Event) -> None: logging.info("Updating FU Status: Enabled") self.constants.fu_status = True self.constants.fu_arguments = None + global_settings.GlobalEnviromentSettings().write_property("GUI:fu_status", True) + global_settings.GlobalEnviromentSettings().write_property("GUI:fu_arguments", "") return if value == "Partial": logging.info("Updating FU Status: Partial") self.constants.fu_status = True self.constants.fu_arguments = " -disable_sidecar_mac" + global_settings.GlobalEnviromentSettings().write_property("GUI:fu_status", True) + global_settings.GlobalEnviromentSettings().write_property("GUI:fu_arguments", " -disable_sidecar_mac") return logging.info("Updating FU Status: Disabled") self.constants.fu_status = False self.constants.fu_arguments = None + global_settings.GlobalEnviromentSettings().write_property("GUI:fu_status", False) + global_settings.GlobalEnviromentSettings().write_property("GUI:fu_arguments", "") def _populate_graphics_override(self, panel: wx.Panel) -> None: @@ -1269,6 +1283,9 @@ def gpu_selection_click(self, event: wx.Event) -> None: self.constants.imac_model = "Navi" else: raise Exception("Unknown GPU Model") + global_settings.GlobalEnviromentSettings().write_property("GUI:imac_vendor", "AMD") + global_settings.GlobalEnviromentSettings().write_property("GUI:metal_build", True) + global_settings.GlobalEnviromentSettings().write_property("GUI:imac_model", self.constants.imac_model) elif "Nvidia" in gpu_choice: self.constants.imac_vendor = "Nvidia" self.constants.metal_build = True @@ -1278,9 +1295,14 @@ def gpu_selection_click(self, event: wx.Event) -> None: self.constants.imac_model = "GT" else: raise Exception("Unknown GPU Model") + global_settings.GlobalEnviromentSettings().write_property("GUI:imac_vendor", "Nvidia") + global_settings.GlobalEnviromentSettings().write_property("GUI:metal_build", True) + global_settings.GlobalEnviromentSettings().write_property("GUI:imac_model", self.constants.imac_model) else: self.constants.imac_vendor = "None" self.constants.metal_build = False + global_settings.GlobalEnviromentSettings().write_property("GUI:imac_vendor", "None") + global_settings.GlobalEnviromentSettings().write_property("GUI:metal_build", False) def _get_system_settings(self, variable) -> bool: