diff --git a/payloads/Tools/OpenCore-Patcher-Helper.app/Contents/Info.plist b/payloads/Tools/OpenCore-Patcher-Helper.app/Contents/Info.plist
index 48c6d54f4..082a4cdf7 100644
--- a/payloads/Tools/OpenCore-Patcher-Helper.app/Contents/Info.plist
+++ b/payloads/Tools/OpenCore-Patcher-Helper.app/Contents/Info.plist
@@ -13,7 +13,7 @@
CFBundleInfoDictionaryVersion
6.0
CFBundleName
- OpenCore-Patcher
+ OpenCore-Patcher-Helper
CFBundlePackageType
APPL
LSMinimumSystemVersion
diff --git a/resources/constants.py b/resources/constants.py
index f90ba79f3..0610026fa 100644
--- a/resources/constants.py
+++ b/resources/constants.py
@@ -131,6 +131,7 @@ class Constants:
self.launcher_script: str = None # Determine launch file path (None if PyInstaller)
self.booted_oc_disk: str = None # Determine current disk OCLP booted from
self.unpack_thread = None # Determine if unpack thread finished (threading.Thread)
+ self.update_stage: int = 0 # Determine update stage (see gui_support.py)
self.commit_info: tuple = (None, None, None) # Commit info (Branch, Commit Date, Commit URL)
diff --git a/resources/main.py b/resources/main.py
index 278d1ff33..9797cfcdf 100644
--- a/resources/main.py
+++ b/resources/main.py
@@ -6,7 +6,6 @@ import logging
import threading
from pathlib import Path
-from resources.gui import gui_main
from resources.wx_gui import gui_entry
from resources import (
constants,
@@ -39,7 +38,6 @@ class OpenCoreLegacyPatcher:
self._generate_base_data()
if utilities.check_cli_args() is None:
- # gui_main.wx_python_gui(self.constants).main_menu(None)
gui_entry.EntryPoint(self.constants).start()
@@ -101,7 +99,7 @@ class OpenCoreLegacyPatcher:
logging.info("- Detected arguments, switching to CLI mode")
self.constants.gui_mode = True # Assumes no user interaction is required
- ignore_args = ["--auto_patch", "--gui_patch", "--gui_unpatch"]
+ ignore_args = ["--auto_patch", "--gui_patch", "--gui_unpatch", "--update_installed"]
if not any(x in sys.argv for x in ignore_args):
self.constants.current_path = Path.cwd()
self.constants.cli_mode = True
diff --git a/resources/utilities.py b/resources/utilities.py
index 186be82b1..63d3fad97 100644
--- a/resources/utilities.py
+++ b/resources/utilities.py
@@ -572,6 +572,7 @@ def check_cli_args():
parser.add_argument("--gui_patch", help="Starts GUI in Root Patcher", action="store_true", required=False)
parser.add_argument("--gui_unpatch", help="Starts GUI in Root Unpatcher", action="store_true", required=False)
parser.add_argument("--auto_patch", help="Check if patches are needed and prompt user", action="store_true", required=False)
+ parser.add_argument("--update_installed", help="Prompt user to finish updating via GUI", action="store_true", required=False)
args = parser.parse_args()
if not (args.build or args.patch_sys_vol or args.unpatch_sys_vol or args.validate or args.auto_patch):
diff --git a/resources/wx_gui/gui_build.py b/resources/wx_gui/gui_build.py
index e0cdc3541..d6e1d519c 100644
--- a/resources/wx_gui/gui_build.py
+++ b/resources/wx_gui/gui_build.py
@@ -33,6 +33,9 @@ class BuildFrame(wx.Frame):
self._generate_elements(self.frame_modal)
+ if self.constants.update_stage != gui_support.AutoUpdateStages.INACTIVE:
+ self.constants.update_stage = gui_support.AutoUpdateStages.BUILDING
+
self.SetPosition(screen_location) if screen_location else self.Centre()
self.frame_modal.ShowWindowModal()
diff --git a/resources/wx_gui/gui_install_oc.py b/resources/wx_gui/gui_install_oc.py
index 83f017af8..fbe117435 100644
--- a/resources/wx_gui/gui_install_oc.py
+++ b/resources/wx_gui/gui_install_oc.py
@@ -3,7 +3,7 @@ import threading
import logging
import traceback
-from resources.wx_gui import gui_main_menu, gui_support
+from resources.wx_gui import gui_main_menu, gui_support, gui_sys_patch
from resources import constants, install
@@ -27,6 +27,9 @@ class InstallOCFrame(wx.Frame):
self._generate_elements()
+ if self.constants.update_stage != gui_support.AutoUpdateStages.INACTIVE:
+ self.constants.update_stage = gui_support.AutoUpdateStages.INSTALLING
+
self.SetPosition(screen_location) if screen_location else self.Centre()
self.Show()
@@ -262,7 +265,25 @@ class InstallOCFrame(wx.Frame):
wx.GetApp().Yield()
if self.result is True:
- if not self.constants.custom_model:
+ if self.constants.update_stage != gui_support.AutoUpdateStages.INACTIVE:
+ self.constants.update_stage = gui_support.AutoUpdateStages.ROOT_PATCHING
+ popup_message = wx.MessageDialog(
+ self,
+ f"OpenCore has finished installing to disk.\n\nWould you like to update your root patches next?", "Success",
+ wx.YES_NO | wx.YES_DEFAULT
+ )
+ popup_message.ShowModal()
+ if popup_message.GetReturnCode() == wx.ID_YES:
+ gui_sys_patch.SysPatchFrame(
+ parent=None,
+ title=self.title,
+ global_constants=self.constants,
+ screen_location=self.GetPosition()
+ )
+ self.Destroy()
+ return
+
+ elif not self.constants.custom_model:
gui_support.RestartHost(self).restart(message="OpenCore has finished installing to disk.\n\nYou will need to reboot and hold the Option key and select OpenCore/Boot EFI's option.\n\nWould you like to reboot?")
else:
popup_message = wx.MessageDialog(
@@ -271,6 +292,9 @@ class InstallOCFrame(wx.Frame):
wx.OK
)
popup_message.ShowModal()
+ else:
+ if self.constants.update_stage != gui_support.AutoUpdateStages.INACTIVE:
+ self.constants.update_stage = gui_support.AutoUpdateStages.FINISHED
def _install_oc(self, partition: dict) -> None:
diff --git a/resources/wx_gui/gui_main_menu.py b/resources/wx_gui/gui_main_menu.py
index 5c2bd6568..23c6e663d 100644
--- a/resources/wx_gui/gui_main_menu.py
+++ b/resources/wx_gui/gui_main_menu.py
@@ -1,4 +1,7 @@
+# Generate GUI for main menu
import wx
+import sys
+import time
import logging
import threading
@@ -113,6 +116,34 @@ class MainFrame(wx.Frame):
self.on_build_and_install()
return
+ if "--update_installed" in sys.argv and self.constants.has_checked_updates is False and gui_support.CheckProperties(self.constants).host_can_build():
+ # Notify user that the update has been installed
+ self.constants.has_checked_updates = True
+ pop_up = wx.MessageDialog(
+ self,
+ f"OpenCore Legacy Patcher has been updated to the latest version: {self.constants.patcher_version}\n\nWould you like to update OpenCore and your root volume patches?",
+ "Update successful!",
+ style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ pop_up.ShowModal()
+
+ if pop_up.GetReturnCode() != wx.ID_YES:
+ print("- Skipping OpenCore and root volume patch update...")
+ return
+
+
+ print("- Updating OpenCore and root volume patches...")
+ self.constants.update_stage = gui_support.AutoUpdateStages.CHECKING
+ self.Hide()
+ pos = self.GetPosition()
+ gui_build.BuildFrame(
+ parent=None,
+ title=self.title,
+ global_constants=self.constants,
+ screen_location=pos
+ )
+ self.Close()
+
threading.Thread(target=self._check_for_updates).start()
diff --git a/resources/wx_gui/gui_support.py b/resources/wx_gui/gui_support.py
index 1aea7db61..ee587de2f 100644
--- a/resources/wx_gui/gui_support.py
+++ b/resources/wx_gui/gui_support.py
@@ -11,6 +11,15 @@ from resources import constants
from data import model_array, os_data
+class AutoUpdateStages:
+ INACTIVE = 0
+ CHECKING = 1
+ BUILDING = 2
+ INSTALLING = 3
+ ROOT_PATCHING = 4
+ FINISHED = 5
+
+
class GenerateMenubar:
def __init__(self) -> None:
diff --git a/resources/wx_gui/gui_sys_patch.py b/resources/wx_gui/gui_sys_patch.py
index 5620ababa..df2ca7d53 100644
--- a/resources/wx_gui/gui_sys_patch.py
+++ b/resources/wx_gui/gui_sys_patch.py
@@ -39,6 +39,7 @@ class SysPatchFrame(wx.Frame):
self.constants: constants.Constants = global_constants
self.frame_modal: wx.Dialog = None
self.return_button: wx.Button = None
+ self.available_patches: bool = False
self.frame_modal = wx.Dialog(self, title=title, size=(360, 200))
self.SetPosition(screen_location) if screen_location else self.Centre()
@@ -49,6 +50,10 @@ class SysPatchFrame(wx.Frame):
self._generate_elements_display_patches(self.frame_modal, patches)
self.frame_modal.ShowWindowModal()
+ if self.constants.update_stage != gui_support.AutoUpdateStages.INACTIVE:
+ if self.available_patches is False:
+ gui_support.RestartHost(self).restart(message="No root patch updates needed!\n\nWould you like to reboot to apply the new OpenCore build?")
+
def _kdk_download(self, frame: wx.Frame = None) -> bool:
frame = self if not frame else frame
@@ -239,12 +244,14 @@ class SysPatchFrame(wx.Frame):
if not patches:
start_button.Disable()
else:
+ self.available_patches = True
if patches["Validation: Patching Possible"] is False:
start_button.Disable()
+ elif no_new_patches is False:
+ start_button.SetDefault()
if can_unpatch is False:
revert_button.Disable()
-
# Relaunch as root if not root
uid = os.geteuid()
if uid != 0: