mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-06-20 22:20:53 +10:00
Add support for KDK caching
This commit is contained in:
+13
-3
@@ -9,9 +9,19 @@
|
|||||||
- Resolve Photos app crash
|
- Resolve Photos app crash
|
||||||
- Workaround tile window popup freezing apps by disabling the feature
|
- Workaround tile window popup freezing apps by disabling the feature
|
||||||
- Workaround monochrome desktop widgets rendering issues by enforcing full color (can be disabled in OCLP settings)
|
- Workaround monochrome desktop widgets rendering issues by enforcing full color (can be disabled in OCLP settings)
|
||||||
- Add new Launch Daemon for clean up on macOS updates
|
- Add new arguments:
|
||||||
- Resolves KDKless Macs failing to boot after updating from 14.0 to 14.x
|
- `--cache_os`: Cache nessasary patcher files for OS to be installed (ex. KDKs)
|
||||||
- `/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.macos-update.plist`
|
- `--prepare_for_update`: Clean up patcher files for OS to be installed (ex. /Library/Extensions)
|
||||||
|
- Add new Launch Daemons for handling macOS updates:
|
||||||
|
- `macos-update.plist`:
|
||||||
|
- Resolves KDKless Macs failing to boot after updating from 14.0 to 14.x
|
||||||
|
- Adds support for KDK caching for OS to be installed
|
||||||
|
- Invoked when update is staged
|
||||||
|
- `/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.macos-update.plist`
|
||||||
|
- `os-caching.plist`
|
||||||
|
- Resolves unsupported/old KDKs from being used post-update
|
||||||
|
- Invoked when update is downloading
|
||||||
|
- `/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.os-caching.plist`
|
||||||
- Load UI icons from local path
|
- Load UI icons from local path
|
||||||
- Resolves macOS downloader crash on slower machines
|
- Resolves macOS downloader crash on slower machines
|
||||||
- Resolve iMac18,2 internal 4K display support
|
- Resolve iMac18,2 internal 4K display support
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AssociatedBundleIdentifiers</key>
|
||||||
|
<string>com.dortania.opencore-legacy-patcher</string>
|
||||||
|
<key>Label</key>
|
||||||
|
<string>com.dortania.opencore-legacy-patcher.rsr-monitor</string>
|
||||||
|
<key>ProgramArguments</key>
|
||||||
|
<array>
|
||||||
|
<string>/Library/Application Support/Dortania/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher</string>
|
||||||
|
<string>--cache_os</string>
|
||||||
|
</array>
|
||||||
|
<key>WatchPaths</key>
|
||||||
|
<array>
|
||||||
|
<string>/System/Volumes/Update/Preflight.plist</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
+40
-20
@@ -11,6 +11,7 @@ from data import model_array, os_data
|
|||||||
from resources.build import build
|
from resources.build import build
|
||||||
from resources.sys_patch import sys_patch, sys_patch_auto
|
from resources.sys_patch import sys_patch, sys_patch_auto
|
||||||
from resources import defaults, utilities, validation, constants
|
from resources import defaults, utilities, validation, constants
|
||||||
|
from resources.wx_gui import gui_entry
|
||||||
|
|
||||||
|
|
||||||
# Generic building args
|
# Generic building args
|
||||||
@@ -46,8 +47,11 @@ class arguments:
|
|||||||
return
|
return
|
||||||
|
|
||||||
if self.args.prepare_for_update:
|
if self.args.prepare_for_update:
|
||||||
logging.info("Preparing host for macOS update")
|
self._prepare_for_update_handler()
|
||||||
self._clean_le_handler()
|
return
|
||||||
|
|
||||||
|
if self.args.cache_os:
|
||||||
|
self._cache_os_handler()
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.args.auto_patch:
|
if self.args.auto_patch:
|
||||||
@@ -97,31 +101,47 @@ class arguments:
|
|||||||
sys_patch_auto.AutomaticSysPatch(self.constants).start_auto_patch()
|
sys_patch_auto.AutomaticSysPatch(self.constants).start_auto_patch()
|
||||||
|
|
||||||
|
|
||||||
|
def _prepare_for_update_handler(self) -> None:
|
||||||
|
"""
|
||||||
|
Prepare host for macOS update
|
||||||
|
"""
|
||||||
|
logging.info("Preparing host for macOS update")
|
||||||
|
|
||||||
|
os_data = utilities.fetch_staged_update(variant="Update")
|
||||||
|
if os_data[0] is None:
|
||||||
|
logging.info("No update staged, skipping")
|
||||||
|
return
|
||||||
|
|
||||||
|
os_version = os_data[0]
|
||||||
|
os_build = os_data[1]
|
||||||
|
|
||||||
|
logging.info(f"Preparing for update to {os_version} ({os_build})")
|
||||||
|
|
||||||
|
self._clean_le_handler()
|
||||||
|
|
||||||
|
|
||||||
|
def _cache_os_handler(self) -> None:
|
||||||
|
"""
|
||||||
|
Fetch KDK for incoming OS
|
||||||
|
"""
|
||||||
|
results = subprocess.run(["ps", "-ax"], stdout=subprocess.PIPE)
|
||||||
|
if results.stdout.decode("utf-8").count("OpenCore-Patcher --cache_os") > 1:
|
||||||
|
logging.info("Another instance of OS caching is running, exiting")
|
||||||
|
return
|
||||||
|
|
||||||
|
gui_entry.EntryPoint(self.constants).start(entry=gui_entry.SupportedEntryPoints.OS_CACHE)
|
||||||
|
|
||||||
|
|
||||||
def _clean_le_handler(self) -> None:
|
def _clean_le_handler(self) -> None:
|
||||||
"""
|
"""
|
||||||
Check if software update is staged
|
Clean /Library/Extensions of problematic kexts
|
||||||
If so, clean /Library/Extensions
|
Note macOS Ventura and older do this automatically
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.constants.detected_os < os_data.os_data.sonoma:
|
if self.constants.detected_os < os_data.os_data.sonoma:
|
||||||
logging.info("Host doesn't require cleaning, skipping")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
update_config = "/System/Volumes/Update/Update.plist"
|
logging.info("Cleaning /Library/Extensions")
|
||||||
if not Path(update_config).exists():
|
|
||||||
logging.info("No update staged, skipping")
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
update_staged = plistlib.load(open(update_config, "rb"))
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"Failed to load update config: {e}")
|
|
||||||
return
|
|
||||||
if "update-asset-attributes" not in update_staged:
|
|
||||||
logging.info("No update staged, skipping")
|
|
||||||
return
|
|
||||||
|
|
||||||
logging.info("Update staged, cleaning /Library/Extensions")
|
|
||||||
|
|
||||||
for kext in Path("/Library/Extensions").glob("*.kext"):
|
for kext in Path("/Library/Extensions").glob("*.kext"):
|
||||||
if not Path(f"{kext}/Contents/Info.plist").exists():
|
if not Path(f"{kext}/Contents/Info.plist").exists():
|
||||||
|
|||||||
@@ -296,6 +296,10 @@ class Constants:
|
|||||||
def update_launch_daemon_path(self):
|
def update_launch_daemon_path(self):
|
||||||
return self.launch_services_path / Path("com.dortania.opencore-legacy-patcher.macos-update.plist")
|
return self.launch_services_path / Path("com.dortania.opencore-legacy-patcher.macos-update.plist")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def kdk_launch_daemon_path(self):
|
||||||
|
return self.launch_services_path / Path("com.dortania.opencore-legacy-patcher.os-caching.plist")
|
||||||
|
|
||||||
# ACPI
|
# ACPI
|
||||||
@property
|
@property
|
||||||
def pci_ssdt_path(self):
|
def pci_ssdt_path(self):
|
||||||
|
|||||||
@@ -648,7 +648,10 @@ class PatchSysVolume:
|
|||||||
self._execute_patchset(sys_patch_generate.GenerateRootPatchSets(self.computer.real_model, self.constants, self.hardware_details).patchset)
|
self._execute_patchset(sys_patch_generate.GenerateRootPatchSets(self.computer.real_model, self.constants, self.hardware_details).patchset)
|
||||||
|
|
||||||
if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur:
|
if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur:
|
||||||
sys_patch_auto.AutomaticSysPatch(self.constants).install_auto_patcher_launch_agent()
|
needs_daemon = False
|
||||||
|
if self.constants.detected_os >= os_data.os_data.ventura and self.skip_root_kmutil_requirement is False:
|
||||||
|
needs_daemon = True
|
||||||
|
sys_patch_auto.AutomaticSysPatch(self.constants).install_auto_patcher_launch_agent(kdk_caching_needed=needs_daemon)
|
||||||
|
|
||||||
self._rebuild_root_volume()
|
self._rebuild_root_volume()
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import logging
|
|||||||
import plistlib
|
import plistlib
|
||||||
import subprocess
|
import subprocess
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
import hashlib
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -331,7 +332,7 @@ Please check the Github page for more information about this release."""
|
|||||||
logging.info("- Unable to determine if boot disk is removable, skipping prompt")
|
logging.info("- Unable to determine if boot disk is removable, skipping prompt")
|
||||||
|
|
||||||
|
|
||||||
def install_auto_patcher_launch_agent(self):
|
def install_auto_patcher_launch_agent(self, kdk_caching_needed: bool = False):
|
||||||
"""
|
"""
|
||||||
Install the Auto Patcher Launch Agent
|
Install the Auto Patcher Launch Agent
|
||||||
|
|
||||||
@@ -350,12 +351,16 @@ Please check the Github page for more information about this release."""
|
|||||||
self.constants.auto_patch_launch_agent_path: "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist",
|
self.constants.auto_patch_launch_agent_path: "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist",
|
||||||
self.constants.update_launch_daemon_path: "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.macos-update.plist",
|
self.constants.update_launch_daemon_path: "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.macos-update.plist",
|
||||||
**({ self.constants.rsr_monitor_launch_daemon_path: "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.rsr-monitor.plist" } if self._create_rsr_monitor_daemon() else {}),
|
**({ self.constants.rsr_monitor_launch_daemon_path: "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.rsr-monitor.plist" } if self._create_rsr_monitor_daemon() else {}),
|
||||||
|
**({ self.constants.kdk_launch_daemon_path: "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.os-caching.plist" } if kdk_caching_needed is True else {} ),
|
||||||
}
|
}
|
||||||
|
|
||||||
for service in services:
|
for service in services:
|
||||||
name = Path(service).name
|
name = Path(service).name
|
||||||
logging.info(f"- Installing {name}")
|
logging.info(f"- Installing {name}")
|
||||||
if Path(services[service]).exists():
|
if Path(services[service]).exists():
|
||||||
|
if hashlib.sha256(open(service, "rb").read()).hexdigest() == hashlib.sha256(open(services[service], "rb").read()).hexdigest():
|
||||||
|
logging.info(f" - {name} checksums match, skipping")
|
||||||
|
continue
|
||||||
logging.info(f" - Existing service found, removing")
|
logging.info(f" - Existing service found, removing")
|
||||||
utilities.process_status(utilities.elevated(["rm", services[service]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
utilities.process_status(utilities.elevated(["rm", services[service]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||||
# Create parent directories
|
# Create parent directories
|
||||||
|
|||||||
+30
-1
@@ -553,6 +553,33 @@ def elevated(*args, **kwargs) -> subprocess.CompletedProcess:
|
|||||||
return subprocess.run(["sudo"] + [args[0][0]] + args[0][1:], **kwargs)
|
return subprocess.run(["sudo"] + [args[0][0]] + args[0][1:], **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_staged_update(variant: str = "Update") -> (str, str):
|
||||||
|
"""
|
||||||
|
Check for staged macOS update
|
||||||
|
Supported variants:
|
||||||
|
- Preflight
|
||||||
|
- Update
|
||||||
|
"""
|
||||||
|
|
||||||
|
os_build = None
|
||||||
|
os_version = None
|
||||||
|
|
||||||
|
update_config = f"/System/Volumes/Update/{variant}.plist"
|
||||||
|
if not Path(update_config).exists():
|
||||||
|
return (None, None)
|
||||||
|
try:
|
||||||
|
update_staged = plistlib.load(open(update_config, "rb"))
|
||||||
|
except:
|
||||||
|
return (None, None)
|
||||||
|
if "update-asset-attributes" not in update_staged:
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
os_build = update_staged["update-asset-attributes"]["Build"]
|
||||||
|
os_version = update_staged["update-asset-attributes"]["OSVersion"]
|
||||||
|
|
||||||
|
return os_version, os_build
|
||||||
|
|
||||||
|
|
||||||
def check_cli_args():
|
def check_cli_args():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("--build", help="Build OpenCore", action="store_true", required=False)
|
parser.add_argument("--build", help="Build OpenCore", action="store_true", required=False)
|
||||||
@@ -581,6 +608,7 @@ def check_cli_args():
|
|||||||
parser.add_argument("--patch_sys_vol", help="Patches root volume", action="store_true", required=False)
|
parser.add_argument("--patch_sys_vol", help="Patches root volume", action="store_true", required=False)
|
||||||
parser.add_argument("--unpatch_sys_vol", help="Unpatches root volume, EXPERIMENTAL", action="store_true", required=False)
|
parser.add_argument("--unpatch_sys_vol", help="Unpatches root volume, EXPERIMENTAL", action="store_true", required=False)
|
||||||
parser.add_argument("--prepare_for_update", help="Prepares host for macOS update, ex. clean /Library/Extensions", action="store_true", required=False)
|
parser.add_argument("--prepare_for_update", help="Prepares host for macOS update, ex. clean /Library/Extensions", action="store_true", required=False)
|
||||||
|
parser.add_argument("--cache_os", help="Caches patcher files (ex. KDKs) for incoming OS in Preflight.plist", action="store_true", required=False)
|
||||||
|
|
||||||
# validation args
|
# validation args
|
||||||
parser.add_argument("--validate", help="Runs Validation Tests for CI", action="store_true", required=False)
|
parser.add_argument("--validate", help="Runs Validation Tests for CI", action="store_true", required=False)
|
||||||
@@ -598,7 +626,8 @@ def check_cli_args():
|
|||||||
args.unpatch_sys_vol or
|
args.unpatch_sys_vol or
|
||||||
args.validate or
|
args.validate or
|
||||||
args.auto_patch or
|
args.auto_patch or
|
||||||
args.prepare_for_update
|
args.prepare_for_update or
|
||||||
|
args.cache_os
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -0,0 +1,188 @@
|
|||||||
|
"""
|
||||||
|
UI to display to users before a macOS update is applied
|
||||||
|
Primarily for caching updates required for incoming OS (ex. KDKs)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from resources import constants, kdk_handler, utilities
|
||||||
|
from resources.wx_gui import gui_support, gui_download
|
||||||
|
|
||||||
|
|
||||||
|
class OSUpdateFrame(wx.Frame):
|
||||||
|
"""
|
||||||
|
Create a modal frame for displaying information to the user before an update is applied
|
||||||
|
"""
|
||||||
|
def __init__(self, parent: wx.Frame, title: str, global_constants: constants.Constants, screen_location: tuple = None):
|
||||||
|
logging.info("Initializing Prepare Update Frame")
|
||||||
|
|
||||||
|
if parent:
|
||||||
|
self.frame = parent
|
||||||
|
else:
|
||||||
|
super().__init__(parent, title=title, size=(360, 140), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)
|
||||||
|
self.frame = self
|
||||||
|
self.frame.Centre()
|
||||||
|
|
||||||
|
self.title = title
|
||||||
|
self.constants: constants.Constants = global_constants
|
||||||
|
|
||||||
|
os_data = utilities.fetch_staged_update(variant="Preflight")
|
||||||
|
if os_data[0] is None:
|
||||||
|
logging.info("No staged update found")
|
||||||
|
self._exit()
|
||||||
|
logging.info(f"Staged update found: {os_data[0]} ({os_data[1]})")
|
||||||
|
self.os_data = os_data
|
||||||
|
|
||||||
|
self._generate_ui()
|
||||||
|
|
||||||
|
self.kdk_obj: kdk_handler.KernelDebugKitObject = None
|
||||||
|
def _kdk_thread_spawn():
|
||||||
|
self.kdk_obj = kdk_handler.KernelDebugKitObject(self.constants, self.os_data[1], self.os_data[0], passive=True)
|
||||||
|
|
||||||
|
kdk_thread = threading.Thread(target=_kdk_thread_spawn)
|
||||||
|
kdk_thread.start()
|
||||||
|
|
||||||
|
while kdk_thread.is_alive():
|
||||||
|
wx.Yield()
|
||||||
|
|
||||||
|
if self.kdk_obj.success is False:
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
kdk_download_obj = self.kdk_obj.retrieve_download()
|
||||||
|
if not kdk_download_obj:
|
||||||
|
# KDK is already downloaded
|
||||||
|
# Return false since we didn't display anything
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
self.kdk_download_obj = kdk_download_obj
|
||||||
|
|
||||||
|
self.frame.Show()
|
||||||
|
|
||||||
|
self.did_cancel = False
|
||||||
|
self._notifyUser()
|
||||||
|
|
||||||
|
# Allow 10 seconds for the user to cancel the download
|
||||||
|
# If nothing, continue
|
||||||
|
for i in range(0, 10):
|
||||||
|
if self.did_cancel is True:
|
||||||
|
self._exit()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
gui_download.DownloadFrame(
|
||||||
|
self,
|
||||||
|
title=self.title,
|
||||||
|
global_constants=self.constants,
|
||||||
|
download_obj=kdk_download_obj,
|
||||||
|
item_name=f"KDK Build {self.kdk_obj.kdk_url_build}"
|
||||||
|
)
|
||||||
|
if kdk_download_obj.download_complete is False:
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
logging.info("KDK download complete, validating with hdiutil")
|
||||||
|
self.kdk_checksum_result = False
|
||||||
|
def _validate_kdk_checksum_thread():
|
||||||
|
self.kdk_checksum_result = self.kdk_obj.validate_kdk_checksum()
|
||||||
|
|
||||||
|
kdk_checksum_thread = threading.Thread(target=_validate_kdk_checksum_thread)
|
||||||
|
kdk_checksum_thread.start()
|
||||||
|
|
||||||
|
while kdk_checksum_thread.is_alive():
|
||||||
|
wx.Yield()
|
||||||
|
|
||||||
|
if self.kdk_checksum_result is False:
|
||||||
|
logging.error("KDK checksum validation failed")
|
||||||
|
logging.error(self.kdk_obj.error_msg)
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
logging.info("KDK checksum validation passed")
|
||||||
|
|
||||||
|
logging.info("Mounting KDK")
|
||||||
|
if not Path(self.constants.kdk_download_path).exists():
|
||||||
|
logging.error("KDK download path does not exist")
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
self.kdk_install_result = False
|
||||||
|
def _install_kdk_thread():
|
||||||
|
self.kdk_install_result = kdk_handler.KernelDebugKitUtilities().install_kdk_dmg(self.constants.kdk_download_path, only_install_backup=True)
|
||||||
|
|
||||||
|
kdk_install_thread = threading.Thread(target=_install_kdk_thread)
|
||||||
|
kdk_install_thread.start()
|
||||||
|
|
||||||
|
while kdk_install_thread.is_alive():
|
||||||
|
wx.Yield()
|
||||||
|
|
||||||
|
if self.kdk_install_result is False:
|
||||||
|
logging.info("Failed to install KDK")
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
logging.info("KDK installed successfully")
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_ui(self) -> None:
|
||||||
|
"""
|
||||||
|
Display frame
|
||||||
|
|
||||||
|
|
||||||
|
Title: OpenCore Legacy Patcher is preparing to update your system
|
||||||
|
Body: Please wait while we prepare your system for the update.
|
||||||
|
This may take a few minutes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
header = wx.StaticText(self.frame, label="Preparing for macOS Software Update", pos=(-1,5))
|
||||||
|
header.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
||||||
|
header.Centre(wx.HORIZONTAL)
|
||||||
|
|
||||||
|
# list OS
|
||||||
|
label = wx.StaticText(self.frame, label=f"macOS {self.os_data[0]} ({self.os_data[1]})", pos=(-1, 35))
|
||||||
|
label.SetFont(gui_support.font_factory(13, wx.FONTWEIGHT_NORMAL))
|
||||||
|
label.Centre(wx.HORIZONTAL)
|
||||||
|
|
||||||
|
# this may take a few minutes
|
||||||
|
label = wx.StaticText(self.frame, label="This may take a few minutes.", pos=(-1, 55))
|
||||||
|
label.SetFont(gui_support.font_factory(13, wx.FONTWEIGHT_NORMAL))
|
||||||
|
label.Centre(wx.HORIZONTAL)
|
||||||
|
|
||||||
|
# Add a progress bar
|
||||||
|
self.progress_bar = wx.Gauge(self.frame, range=100, pos=(10, 75), size=(340, 20))
|
||||||
|
self.progress_bar.SetValue(0)
|
||||||
|
self.progress_bar.Pulse()
|
||||||
|
|
||||||
|
# Set frame size below progress bar
|
||||||
|
self.frame.SetSize((360, 140))
|
||||||
|
|
||||||
|
|
||||||
|
def _notifyUser(self) -> None:
|
||||||
|
"""
|
||||||
|
Notify user of what OCLP is doing
|
||||||
|
Note will be spawned through wx.CallAfter
|
||||||
|
"""
|
||||||
|
threading.Thread(target=self._notifyUserThread).start()
|
||||||
|
|
||||||
|
|
||||||
|
def _notifyUserThread(self) -> None:
|
||||||
|
"""
|
||||||
|
Notify user of what OCLP is doing
|
||||||
|
"""
|
||||||
|
message=f"OpenCore Legacy Patcher has detected that a macOS update is being downloaded:\n{self.os_data[0]} ({self.os_data[1]})\n\nThe patcher needs to prepare the system for the update, and will download any additional resources it may need post-update.\n\nThis may take a few minutes, the patcher will exit when it is done."
|
||||||
|
# Yes/No for caching
|
||||||
|
dlg = wx.MessageDialog(self.frame, message=message, caption="OpenCore Legacy Patcher", style=wx.YES_NO | wx.ICON_INFORMATION)
|
||||||
|
dlg.SetYesNoLabels("&Ok", "&Cancel")
|
||||||
|
result = dlg.ShowModal()
|
||||||
|
if result == wx.ID_NO:
|
||||||
|
logging.info("User cancelled OS caching")
|
||||||
|
self.kdk_download_obj.stop()
|
||||||
|
self.did_cancel = True
|
||||||
|
|
||||||
|
def _exit(self):
|
||||||
|
"""
|
||||||
|
Exit the frame
|
||||||
|
"""
|
||||||
|
self.frame.Close()
|
||||||
|
sys.exit()
|
||||||
@@ -6,6 +6,7 @@ import logging
|
|||||||
|
|
||||||
from resources import constants
|
from resources import constants
|
||||||
from resources.wx_gui import (
|
from resources.wx_gui import (
|
||||||
|
gui_cache_os_update,
|
||||||
gui_main_menu,
|
gui_main_menu,
|
||||||
gui_build,
|
gui_build,
|
||||||
gui_install_oc,
|
gui_install_oc,
|
||||||
@@ -24,6 +25,7 @@ class SupportedEntryPoints:
|
|||||||
INSTALL_OC = gui_install_oc.InstallOCFrame
|
INSTALL_OC = gui_install_oc.InstallOCFrame
|
||||||
SYS_PATCH = gui_sys_patch_start.SysPatchStartFrame
|
SYS_PATCH = gui_sys_patch_start.SysPatchStartFrame
|
||||||
UPDATE_APP = gui_update.UpdateFrame
|
UPDATE_APP = gui_update.UpdateFrame
|
||||||
|
OS_CACHE = gui_cache_os_update.OSUpdateFrame
|
||||||
|
|
||||||
|
|
||||||
class EntryPoint:
|
class EntryPoint:
|
||||||
|
|||||||
Reference in New Issue
Block a user