From d725798c606c4c9c53bc2c68951c575befa1df0f Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Sat, 27 May 2023 13:24:41 -0600 Subject: [PATCH] GUI SysPatch: Seperate Display and Patch frames --- resources/wx_gui/gui_entry.py | 11 +- resources/wx_gui/gui_install_oc.py | 4 +- resources/wx_gui/gui_main_menu.py | 5 +- resources/wx_gui/gui_sys_patch_display.py | 302 ++++++++++++++++++ ...ui_sys_patch.py => gui_sys_patch_start.py} | 227 ++----------- 5 files changed, 331 insertions(+), 218 deletions(-) create mode 100644 resources/wx_gui/gui_sys_patch_display.py rename resources/wx_gui/{gui_sys_patch.py => gui_sys_patch_start.py} (55%) diff --git a/resources/wx_gui/gui_entry.py b/resources/wx_gui/gui_entry.py index cc8a167e9..c2bcda0ff 100644 --- a/resources/wx_gui/gui_entry.py +++ b/resources/wx_gui/gui_entry.py @@ -9,8 +9,7 @@ from resources.wx_gui import ( gui_main_menu, gui_build, gui_install_oc, - gui_sys_patch, - gui_support, + gui_sys_patch_start, gui_update, ) from resources.sys_patch import sys_patch_detect @@ -23,7 +22,7 @@ class SupportedEntryPoints: MAIN_MENU = gui_main_menu.MainFrame BUILD_OC = gui_build.BuildFrame INSTALL_OC = gui_install_oc.InstallOCFrame - SYS_PATCH = gui_sys_patch.SysPatchFrame + SYS_PATCH = gui_sys_patch_start.SysPatchStartFrame UPDATE_APP = gui_update.UpdateFrame @@ -49,7 +48,7 @@ class EntryPoint: self._generate_base_data() if "--gui_patch" in sys.argv or "--gui_unpatch" in sys.argv: - entry = gui_sys_patch.SysPatchFrame + entry = gui_sys_patch_start.SysPatchStartFrame patches = sys_patch_detect.DetectRootPatch(self.constants.computer.real_model, self.constants).detect_patch_set() logging.info(f"Entry point set: {entry.__name__}") @@ -64,9 +63,9 @@ class EntryPoint: atexit.register(self.OnCloseFrame) if "--gui_patch" in sys.argv: - self.frame.start_root_patching(patches) + self.frame.start_root_patching() elif "--gui_unpatch" in sys.argv: - self.frame.revert_root_patching(patches) + self.frame.revert_root_patching() self.app.MainLoop() diff --git a/resources/wx_gui/gui_install_oc.py b/resources/wx_gui/gui_install_oc.py index 3a0451e5c..70c2cbcb0 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, gui_sys_patch +from resources.wx_gui import gui_main_menu, gui_support, gui_sys_patch_display from resources import constants, install from data import os_data @@ -284,7 +284,7 @@ class InstallOCFrame(wx.Frame): popup_message.ShowModal() if popup_message.GetReturnCode() == wx.ID_YES: self.Hide() - gui_sys_patch.SysPatchFrame( + gui_sys_patch_display.SysPatchDisplayFrame( parent=None, title=self.title, global_constants=self.constants, diff --git a/resources/wx_gui/gui_main_menu.py b/resources/wx_gui/gui_main_menu.py index 05d4dc8c1..8a574abd8 100644 --- a/resources/wx_gui/gui_main_menu.py +++ b/resources/wx_gui/gui_main_menu.py @@ -8,10 +8,11 @@ import webbrowser from resources.wx_gui import ( gui_build, gui_macos_installer_download, - gui_sys_patch, gui_support, gui_help, gui_settings, + gui_sys_patch_start, + gui_sys_patch_display, gui_update, ) from resources import ( @@ -278,7 +279,7 @@ class MainFrame(wx.Frame): def on_post_install_root_patch(self, event: wx.Event = None): - gui_sys_patch.SysPatchFrame( + gui_sys_patch_display.SysPatchDisplayFrame( parent=self, title=self.title, global_constants=self.constants, diff --git a/resources/wx_gui/gui_sys_patch_display.py b/resources/wx_gui/gui_sys_patch_display.py new file mode 100644 index 000000000..0d305dc5d --- /dev/null +++ b/resources/wx_gui/gui_sys_patch_display.py @@ -0,0 +1,302 @@ + +import wx +import os +import logging +import plistlib + +from pathlib import Path + +from resources import ( + constants, +) +from resources.sys_patch import ( + sys_patch_detect +) +from resources.wx_gui import ( + gui_main_menu, + gui_support, + gui_sys_patch_start, +) + + +class SysPatchDisplayFrame(wx.Frame): + """ + Create a modal frame for displaying root patches + """ + def __init__(self, parent: wx.Frame, title: str, global_constants: constants.Constants, screen_location: tuple = None): + logging.info("Initializing Root Patch Display Frame") + + if parent: + self.frame = parent + else: + self.frame = wx.Frame.__init__(self, parent, title=title, size=(360, 200), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX) + self.title = title + 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.frame, title=title, size=(360, 200)) + + self._generate_elements_display_patches(self.frame_modal) + self.frame_modal.ShowWindowModal() + + if self.constants.update_stage != gui_support.AutoUpdateStages.INACTIVE: + if self.available_patches is False: + gui_support.RestartHost(self.frame).restart(message="No root patch updates needed!\n\nWould you like to reboot to apply the new OpenCore build?") + + + def _generate_elements_display_patches(self, frame: wx.Frame = None) -> None: + """ + Generate UI elements for root patching frame + + Format: + - Title label: Post-Install Menu + - Label: Available patches: + - Labels: {patch name} + - Button: Start Root Patching + - Button: Revert Root Patches + - Button: Return to Main Menu + """ + frame = self if not frame else frame + + title_label = wx.StaticText(frame, label="Post-Install Menu", pos=(-1, 10)) + title_label.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) + title_label.Centre(wx.HORIZONTAL) + + # Label: Available patches: + available_label = wx.StaticText(frame, label="Available patches for your system:", pos=(-1, title_label.GetPosition()[1] + title_label.GetSize()[1] + 10)) + available_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) + available_label.Centre(wx.HORIZONTAL) + + # Labels: {patch name} + patches: dict = sys_patch_detect.DetectRootPatch(self.constants.computer.real_model, self.constants).detect_patch_set() + can_unpatch: bool = patches["Validation: Unpatching Possible"] + + if not any(not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True for patch in patches): + logging.info("No applicable patches available") + patches = [] + + # Check if OCLP has already applied the same patches + no_new_patches = not self._check_if_new_patches_needed(patches) if patches else False + + if not patches: + # Prompt user with no patches found + patch_label = wx.StaticText(frame, label="No patches required", pos=(-1, available_label.GetPosition()[1] + 20)) + patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + patch_label.Centre(wx.HORIZONTAL) + + else: + # Add Label for each patch + i = 0 + if no_new_patches is True: + patch_label = wx.StaticText(frame, label="All applicable patches already installed", pos=(-1, available_label.GetPosition()[1] + 20)) + patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + patch_label.Centre(wx.HORIZONTAL) + i = i + 20 + else: + longest_patch = "" + for patch in patches: + if (not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True): + if len(patch) > len(longest_patch): + longest_patch = patch + anchor = wx.StaticText(frame, label=longest_patch, pos=(-1, available_label.GetPosition()[1] + 20)) + anchor.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + anchor.Centre(wx.HORIZONTAL) + anchor.Hide() + + logging.info("Available patches:") + for patch in patches: + if (not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True): + i = i + 20 + logging.info(f"- {patch}") + patch_label = wx.StaticText(frame, label=f"- {patch}", pos=(anchor.GetPosition()[0], available_label.GetPosition()[1] + i)) + patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + + if i == 20: + patch_label.SetLabel(patch_label.GetLabel().replace("-", "")) + patch_label.Centre(wx.HORIZONTAL) + + if patches["Validation: Patching Possible"] is False: + # Cannot patch due to the following reasons: + patch_label = wx.StaticText(frame, label="Cannot patch due to the following reasons:", pos=(-1, patch_label.GetPosition()[1] + 25)) + patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) + patch_label.Centre(wx.HORIZONTAL) + + longest_patch = "" + for patch in patches: + if not patch.startswith("Validation"): + continue + if patches[patch] is False: + continue + if patch == "Validation: Unpatching Possible": + continue + + if len(patch) > len(longest_patch): + longest_patch = patch + anchor = wx.StaticText(frame, label=longest_patch.split('Validation: ')[1], pos=(-1, patch_label.GetPosition()[1] + 20)) + anchor.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + anchor.Centre(wx.HORIZONTAL) + anchor.Hide() + + i = 0 + for patch in patches: + if not patch.startswith("Validation"): + continue + if patches[patch] is False: + continue + if patch == "Validation: Unpatching Possible": + continue + + patch_label = wx.StaticText(frame, label=f"- {patch.split('Validation: ')[1]}", pos=(anchor.GetPosition()[0], anchor.GetPosition()[1] + i)) + patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + i = i + 20 + + if i == 20: + patch_label.SetLabel(patch_label.GetLabel().replace("-", "")) + patch_label.Centre(wx.HORIZONTAL) + + else: + if self.constants.computer.oclp_sys_version and self.constants.computer.oclp_sys_date: + date = self.constants.computer.oclp_sys_date.split(" @") + date = date[0] if len(date) == 2 else "" + + patch_text = f"{self.constants.computer.oclp_sys_version}, {date}" + + patch_label = wx.StaticText(frame, label="Root Volume last patched:", pos=(-1, patch_label.GetPosition().y + 25)) + patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) + patch_label.Centre(wx.HORIZONTAL) + + patch_label = wx.StaticText(frame, label=patch_text, pos=(available_label.GetPosition().x - 10, patch_label.GetPosition().y + 20)) + patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + patch_label.Centre(wx.HORIZONTAL) + + + # Button: Start Root Patching + start_button = wx.Button(frame, label="Start Root Patching", pos=(10, patch_label.GetPosition().y + 25), size=(170, 30)) + start_button.Bind(wx.EVT_BUTTON, lambda event: self.on_start_root_patching(patches)) + start_button.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + start_button.Centre(wx.HORIZONTAL) + + # Button: Revert Root Patches + revert_button = wx.Button(frame, label="Revert Root Patches", pos=(10, start_button.GetPosition().y + start_button.GetSize().height - 5), size=(170, 30)) + revert_button.Bind(wx.EVT_BUTTON, lambda event: self.on_revert_root_patching(patches)) + revert_button.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + revert_button.Centre(wx.HORIZONTAL) + + # Button: Return to Main Menu + return_button = wx.Button(frame, label="Return to Main Menu", pos=(10, revert_button.GetPosition().y + revert_button.GetSize().height), size=(150, 30)) + return_button.Bind(wx.EVT_BUTTON, self.on_return_dismiss) + return_button.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) + return_button.Centre(wx.HORIZONTAL) + self.return_button = return_button + + # Disable buttons if unsupported + 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() + else: + self.available_patches = False + if can_unpatch is False: + revert_button.Disable() + + # Relaunch as root if not root + if os.geteuid() != 0: + start_button.Bind(wx.EVT_BUTTON, gui_support.RelaunchApplicationAsRoot(frame, self.constants).relaunch) + revert_button.Bind(wx.EVT_BUTTON, gui_support.RelaunchApplicationAsRoot(frame, self.constants).relaunch) + + # Set frame size + frame.SetSize((-1, return_button.GetPosition().y + return_button.GetSize().height + 35)) + + + def on_start_root_patching(self, patches: dict): + frame = gui_sys_patch_start.SysPatchStartFrame( + parent=None, + title=self.title, + global_constants=self.constants, + patches=patches, + ) + frame.start_root_patching() + self.on_return_dismiss() + + + def on_revert_root_patching(self, patches: dict): + frame = gui_sys_patch_start.SysPatchStartFrame( + parent=None, + title=self.title, + global_constants=self.constants, + patches=patches, + ) + frame.revert_root_patching() + self.on_return_dismiss() + + + def on_return_to_main_menu(self, event: wx.Event = None): + # Get frame from event + frame_modal: wx.Dialog = event.GetEventObject().GetParent() + frame: wx.Frame = frame_modal.Parent + frame_modal.Hide() + frame.Hide() + + main_menu_frame = gui_main_menu.MainFrame( + None, + title=self.title, + global_constants=self.constants, + ) + main_menu_frame.Show() + frame.Destroy() + + + def on_return_dismiss(self, event: wx.Event = None): + self.frame_modal.Hide() + self.frame_modal.Destroy() + + + def _check_if_new_patches_needed(self, patches: dict) -> bool: + """ + Checks if any new patches are needed for the user to install + Newer users will assume the root patch menu will present missing patches. + Thus we'll need to see if the exact same OCLP build was used already + """ + + logging.info("Checking if new patches are needed") + + if self.constants.commit_info[0] in ["Running from source", "Built from source"]: + return True + + if self.constants.computer.oclp_sys_url != self.constants.commit_info[2]: + # If commits are different, assume patches are as well + return True + + oclp_plist = "/System/Library/CoreServices/OpenCore-Legacy-Patcher.plist" + if not Path(oclp_plist).exists(): + # If it doesn't exist, no patches were ever installed + # ie. all patches applicable + return True + + oclp_plist_data = plistlib.load(open(oclp_plist, "rb")) + for patch in patches: + if (not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True): + # Patches should share the same name as the plist key + # See sys_patch_dict.py for more info + patch_installed = False + for key in oclp_plist_data: + if isinstance(oclp_plist_data[key], (bool, int)): + continue + if "Display Name" not in oclp_plist_data[key]: + continue + if oclp_plist_data[key]["Display Name"] == patch: + patch_installed = True + break + + if patch_installed is False: + logging.info(f"- Patch {patch} not installed") + return True + + logging.info("No new patches detected for system") + return False \ No newline at end of file diff --git a/resources/wx_gui/gui_sys_patch.py b/resources/wx_gui/gui_sys_patch_start.py similarity index 55% rename from resources/wx_gui/gui_sys_patch.py rename to resources/wx_gui/gui_sys_patch_start.py index 5e4304920..565d798a5 100644 --- a/resources/wx_gui/gui_sys_patch.py +++ b/resources/wx_gui/gui_sys_patch_start.py @@ -1,6 +1,5 @@ import wx -import os import sys import time import logging @@ -27,39 +26,27 @@ from resources.wx_gui import ( from data import os_data -class SysPatchFrame(wx.Frame): +class SysPatchStartFrame(wx.Frame): """ Create a frame for root patching Uses a Modal Dialog for smoother transition from other frames """ def __init__(self, parent: wx.Frame, title: str, global_constants: constants.Constants, screen_location: tuple = None, patches: dict = {}): logging.info("Initializing Root Patching Frame") - self.frame = parent - self.initiated_with_parent = False - if not self.frame and patches == {}: - super(SysPatchFrame, self).__init__(parent, title=title, size=(350, 200), style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)) - self.frame = self - self.frame.Centre() - else: - self.initiated_with_parent = True self.title = title self.constants: constants.Constants = global_constants self.frame_modal: wx.Dialog = None self.return_button: wx.Button = None self.available_patches: bool = False + self.patches: dict = patches - self.frame_modal = wx.Dialog(self.frame, title=title, size=(360, 200)) + super(SysPatchStartFrame, self).__init__(parent, title=title, size=(350, 200), style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)) + gui_support.GenerateMenubar(self, self.constants).generate() + self.Centre() - if patches: - return - - 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.frame).restart(message="No root patch updates needed!\n\nWould you like to reboot to apply the new OpenCore build?") + if self.patches == {}: + self.patches = sys_patch_detect.DetectRootPatch(self.constants.computer.real_model, self.constants).detect_patch_set() def _kdk_download(self, frame: wx.Frame = None) -> bool: @@ -137,178 +124,13 @@ class SysPatchFrame(wx.Frame): progress_bar.SetValue(100) logging.info("KDK download complete") + + for child in frame.GetChildren(): + child.Destroy() + return True - def _generate_elements_display_patches(self, frame: wx.Frame = None, patches: dict = {}) -> None: - """ - Generate UI elements for root patching frame - - Format: - - Title label: Post-Install Menu - - Label: Available patches: - - Labels: {patch name} - - Button: Start Root Patching - - Button: Revert Root Patches - - Button: Return to Main Menu - """ - frame = self if not frame else frame - - title_label = wx.StaticText(frame, label="Post-Install Menu", pos=(-1, 10)) - title_label.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) - title_label.Centre(wx.HORIZONTAL) - - # Label: Available patches: - available_label = wx.StaticText(frame, label="Available patches for your system:", pos=(-1, title_label.GetPosition()[1] + title_label.GetSize()[1] + 10)) - available_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) - available_label.Centre(wx.HORIZONTAL) - - # Labels: {patch name} - patches: dict = sys_patch_detect.DetectRootPatch(self.constants.computer.real_model, self.constants).detect_patch_set() if not patches else patches - can_unpatch: bool = patches["Validation: Unpatching Possible"] - - if not any(not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True for patch in patches): - logging.info("No applicable patches available") - patches = [] - - # Check if OCLP has already applied the same patches - no_new_patches = not self._check_if_new_patches_needed(patches) if patches else False - - if not patches: - # Prompt user with no patches found - patch_label = wx.StaticText(frame, label="No patches required", pos=(-1, available_label.GetPosition()[1] + 20)) - patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - patch_label.Centre(wx.HORIZONTAL) - - else: - # Add Label for each patch - i = 0 - if no_new_patches is True: - patch_label = wx.StaticText(frame, label="All applicable patches already installed", pos=(-1, available_label.GetPosition()[1] + 20)) - patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - patch_label.Centre(wx.HORIZONTAL) - i = i + 20 - else: - longest_patch = "" - for patch in patches: - if (not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True): - if len(patch) > len(longest_patch): - longest_patch = patch - anchor = wx.StaticText(frame, label=longest_patch, pos=(-1, available_label.GetPosition()[1] + 20)) - anchor.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - anchor.Centre(wx.HORIZONTAL) - anchor.Hide() - - logging.info("Available patches:") - for patch in patches: - if (not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True): - i = i + 20 - logging.info(f"- {patch}") - patch_label = wx.StaticText(frame, label=f"- {patch}", pos=(anchor.GetPosition()[0], available_label.GetPosition()[1] + i)) - patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - - if i == 20: - patch_label.SetLabel(patch_label.GetLabel().replace("-", "")) - patch_label.Centre(wx.HORIZONTAL) - - if patches["Validation: Patching Possible"] is False: - # Cannot patch due to the following reasons: - patch_label = wx.StaticText(frame, label="Cannot patch due to the following reasons:", pos=(-1, patch_label.GetPosition()[1] + 25)) - patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) - patch_label.Centre(wx.HORIZONTAL) - - longest_patch = "" - for patch in patches: - if not patch.startswith("Validation"): - continue - if patches[patch] is False: - continue - if patch == "Validation: Unpatching Possible": - continue - - if len(patch) > len(longest_patch): - longest_patch = patch - anchor = wx.StaticText(frame, label=longest_patch.split('Validation: ')[1], pos=(-1, patch_label.GetPosition()[1] + 20)) - anchor.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - anchor.Centre(wx.HORIZONTAL) - anchor.Hide() - - i = 0 - for patch in patches: - if not patch.startswith("Validation"): - continue - if patches[patch] is False: - continue - if patch == "Validation: Unpatching Possible": - continue - - patch_label = wx.StaticText(frame, label=f"- {patch.split('Validation: ')[1]}", pos=(anchor.GetPosition()[0], anchor.GetPosition()[1] + i)) - patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - i = i + 20 - - if i == 20: - patch_label.SetLabel(patch_label.GetLabel().replace("-", "")) - patch_label.Centre(wx.HORIZONTAL) - - else: - if self.constants.computer.oclp_sys_version and self.constants.computer.oclp_sys_date: - date = self.constants.computer.oclp_sys_date.split(" @") - date = date[0] if len(date) == 2 else "" - - patch_text = f"{self.constants.computer.oclp_sys_version}, {date}" - - patch_label = wx.StaticText(frame, label="Root Volume last patched:", pos=(-1, patch_label.GetPosition().y + 25)) - patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) - patch_label.Centre(wx.HORIZONTAL) - - patch_label = wx.StaticText(frame, label=patch_text, pos=(available_label.GetPosition().x - 10, patch_label.GetPosition().y + 20)) - patch_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - patch_label.Centre(wx.HORIZONTAL) - - - # Button: Start Root Patching - start_button = wx.Button(frame, label="Start Root Patching", pos=(10, patch_label.GetPosition().y + 25), size=(170, 30)) - start_button.Bind(wx.EVT_BUTTON, lambda event: self.start_root_patching(patches)) - start_button.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - start_button.Centre(wx.HORIZONTAL) - - # Button: Revert Root Patches - revert_button = wx.Button(frame, label="Revert Root Patches", pos=(10, start_button.GetPosition().y + start_button.GetSize().height - 5), size=(170, 30)) - revert_button.Bind(wx.EVT_BUTTON, lambda event: self.revert_root_patching(patches)) - revert_button.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - revert_button.Centre(wx.HORIZONTAL) - - # Button: Return to Main Menu - return_button = wx.Button(frame, label="Return to Main Menu", pos=(10, revert_button.GetPosition().y + revert_button.GetSize().height), size=(150, 30)) - return_button.Bind(wx.EVT_BUTTON, self.on_return_dismiss if self.initiated_with_parent else self.on_return_to_main_menu) - return_button.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont")) - return_button.Centre(wx.HORIZONTAL) - self.return_button = return_button - - # Disable buttons if unsupported - 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() - else: - self.available_patches = False - if can_unpatch is False: - revert_button.Disable() - - # Relaunch as root if not root - uid = os.geteuid() - if uid != 0: - start_button.Bind(wx.EVT_BUTTON, gui_support.RelaunchApplicationAsRoot(frame, self.constants).relaunch) - revert_button.Bind(wx.EVT_BUTTON, gui_support.RelaunchApplicationAsRoot(frame, self.constants).relaunch) - - # Set frame size - frame.SetSize((-1, return_button.GetPosition().y + return_button.GetSize().height + 35)) - - def _generate_modal(self, patches: dict = {}, variant: str = "Root Patching"): """ Create UI for root patching/unpatching @@ -389,27 +211,21 @@ class SysPatchFrame(wx.Frame): dialog.ShowWindowModal() - def start_root_patching(self, patches: dict): - self.frame.Close() if self.frame else None - super(SysPatchFrame, self).__init__(None, title=self.title, size=(350, 260), style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)) - gui_support.GenerateMenubar(self, self.constants).generate() - self.Centre() - self.return_button.Bind(wx.EVT_BUTTON, self.on_return_to_main_menu) if self.return_button else None - + def start_root_patching(self): logging.info("Starting root patching") while gui_support.PayloadMount(self.constants, self).is_unpack_finished() is False: wx.Yield() - if patches["Settings: Kernel Debug Kit missing"] is True: + if self.patches["Settings: Kernel Debug Kit missing"] is True: if self._kdk_download(self) is False: self.on_return_to_main_menu() return - self._generate_modal(patches, "Root Patching") + self._generate_modal(self.patches, "Root Patching") self.return_button.Disable() - thread = threading.Thread(target=self._start_root_patching, args=(patches,)) + thread = threading.Thread(target=self._start_root_patching, args=(self.patches,)) thread.start() while thread.is_alive(): @@ -430,18 +246,13 @@ class SysPatchFrame(wx.Frame): logger.removeHandler(logger.handlers[2]) - def revert_root_patching(self, patches: dict): - self.frame.Close() if self.frame else None - super(SysPatchFrame, self).__init__(None, title=self.title, size=(350, 260), style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)) - gui_support.GenerateMenubar(self, self.constants).generate() - self.Centre() - self.return_button.Bind(wx.EVT_BUTTON, self.on_return_to_main_menu) if self.return_button else None - + def revert_root_patching(self): logging.info("Reverting root patches") - self._generate_modal(patches, "Revert Root Patches") + + self._generate_modal(self.patches, "Revert Root Patches") self.return_button.Disable() - thread = threading.Thread(target=self._revert_root_patching, args=(patches,)) + thread = threading.Thread(target=self._revert_root_patching, args=(self.patches,)) thread.start() while thread.is_alive():