Skip to content

Commit

Permalink
Improve compatibility with macOS Ventura and macOS Monterey.
Browse files Browse the repository at this point in the history
  • Loading branch information
cormiertyshawn895 committed Sep 2, 2022
1 parent 12b48a3 commit 9388c4f
Show file tree
Hide file tree
Showing 21 changed files with 412 additions and 54 deletions.
8 changes: 4 additions & 4 deletions README.md
@@ -1,13 +1,13 @@
<p align="center">
<a href="https://github.com/cormiertyshawn895/Retroactive/releases/download/1.9/Retroactive.1.9.zip" alt="Download Retroactive"><img width="188" height="188" src="screenshots/icon.png" alt="Download Retroactive"></a>
<a href="https://github.com/cormiertyshawn895/Retroactive/releases/download/2.0/Retroactive.2.0.zip" alt="Download Retroactive"><img width="188" height="188" src="screenshots/icon.png" alt="Download Retroactive"></a>
</p>

## Retroactive

Run Aperture, iPhoto, and iTunes on macOS Big Sur and macOS Catalina. Xcode 11.7 on macOS Mojave. Final Cut Pro 7, Logic Pro 9, and iWork ’09 on macOS Mojave or macOS High Sierra.
Run Aperture, iPhoto, and iTunes on macOS Ventura, macOS Monterey, macOS Big Sur, and macOS Catalina. Xcode 11.7 on macOS Mojave. Final Cut Pro 7, Logic Pro 9, and iWork ’09 on macOS Mojave or macOS High Sierra.

<p align="center">
<a href="https://github.com/cormiertyshawn895/Retroactive/releases/download/1.9/Retroactive.1.9.zip" alt="Download Retroactive"><img width="282" height="68" src="screenshots/resources/download-button.png" alt="Download Retroactive"></a>
<a href="https://github.com/cormiertyshawn895/Retroactive/releases/download/2.0/Retroactive.2.0.zip" alt="Download Retroactive"><img width="282" height="68" src="screenshots/resources/download-button.png" alt="Download Retroactive"></a>
<p>
<p align="center">
<a href="https://github.com/cormiertyshawn895/Retroactive/releases" alt="View Release Page"><img width="160" height="18" src="screenshots/resources/release-button.png" alt="View Release Page"></a>
Expand All @@ -33,7 +33,7 @@ Retroactive will not harm your Mac. This alert only shows up because Retroactive

### Picking an app

On macOS Big Sur and macOS Catalina, Retroactive can unlock Aperture and iPhoto, or install iTunes. Pick the app you want to run. If you want to run multiple apps from here, pick any one of them. You will always be able to get back to this screen later.
On macOS Ventura, macOS Monterey, macOS Big Sur, and macOS Catalina, Retroactive can unlock Aperture and iPhoto, or install iTunes. Pick the app you want to run. If you want to run multiple apps from here, pick any one of them. You will always be able to get back to this screen later.

![](screenshots/4.jpg)

Expand Down
20 changes: 16 additions & 4 deletions Retroactive.xcodeproj/project.pbxproj
Expand Up @@ -8,9 +8,12 @@

/* Begin PBXBuildFile section */
040914AB24558DDB00EC2475 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 040914AA24558DDB00EC2475 /* main.swift */; };
0412C27628C18E35006FB234 /* SheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0412C27528C18E35006FB234 /* SheetViewController.swift */; };
0412C27828C18E51006FB234 /* QRCodeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0412C27728C18E51006FB234 /* QRCodeGenerator.swift */; };
042E9E492381AC2C001D3F38 /* AppKit in Resources */ = {isa = PBXBuildFile; fileRef = 042E9E452381AC2B001D3F38 /* AppKit */; };
042E9E4B2381AC2C001D3F38 /* GeneralFixerScript in Resources */ = {isa = PBXBuildFile; fileRef = 042E9E472381AC2B001D3F38 /* GeneralFixerScript */; };
042E9E4C2381AC2C001D3F38 /* VideoFixer in Resources */ = {isa = PBXBuildFile; fileRef = 042E9E482381AC2B001D3F38 /* VideoFixer */; };
0432042F28C1B00C00421FDE /* Python.framework.zip in Resources */ = {isa = PBXBuildFile; fileRef = 0432042E28C1B00C00421FDE /* Python.framework.zip */; };
0443E5E924562A7A008C4E9B /* MobileDevice.framework.zip in Resources */ = {isa = PBXBuildFile; fileRef = 0443E5E824562A7A008C4E9B /* MobileDevice.framework.zip */; };
046034E22381B41200070C86 /* KeynoteFixer in Resources */ = {isa = PBXBuildFile; fileRef = 046034E12381B41200070C86 /* KeynoteFixer */; };
046034E42381B6E800070C86 /* KeynoteScript in Resources */ = {isa = PBXBuildFile; fileRef = 046034E32381B6E800070C86 /* KeynoteScript */; };
Expand Down Expand Up @@ -119,9 +122,12 @@
/* Begin PBXFileReference section */
040914A124558D7300EC2475 /* genstrings */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = genstrings; sourceTree = BUILT_PRODUCTS_DIR; };
040914AA24558DDB00EC2475 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
0412C27528C18E35006FB234 /* SheetViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SheetViewController.swift; sourceTree = "<group>"; };
0412C27728C18E51006FB234 /* QRCodeGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeGenerator.swift; sourceTree = "<group>"; };
042E9E452381AC2B001D3F38 /* AppKit */ = {isa = PBXFileReference; lastKnownFileType = folder; path = AppKit; sourceTree = "<group>"; };
042E9E472381AC2B001D3F38 /* GeneralFixerScript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = GeneralFixerScript; sourceTree = "<group>"; };
042E9E482381AC2B001D3F38 /* VideoFixer */ = {isa = PBXFileReference; lastKnownFileType = folder; path = VideoFixer; sourceTree = "<group>"; };
0432042E28C1B00C00421FDE /* Python.framework.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Python.framework.zip; sourceTree = "<group>"; };
0443E5E824562A7A008C4E9B /* MobileDevice.framework.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = MobileDevice.framework.zip; sourceTree = "<group>"; };
046034E12381B41200070C86 /* KeynoteFixer */ = {isa = PBXFileReference; lastKnownFileType = folder; path = KeynoteFixer; sourceTree = "<group>"; };
046034E32381B6E800070C86 /* KeynoteScript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = KeynoteScript; sourceTree = "<group>"; };
Expand Down Expand Up @@ -343,6 +349,7 @@
046034E52381C18900070C86 /* BrowserKit.framework.zip */,
046034E62381C18A00070C86 /* ProKit.framework.zip */,
04DA79C425613EB200B65B4E /* CodecComponents.zip */,
0432042E28C1B00C00421FDE /* Python.framework.zip */,
604F709F240B104400687E1B /* Generated */,
046034E12381B41200070C86 /* KeynoteFixer */,
32F763552364EA2200200ED7 /* ApertureFixer */,
Expand Down Expand Up @@ -400,6 +407,7 @@
32D181F723643630006253DE /* StepTwo */ = {
isa = PBXGroup;
children = (
0412C27528C18E35006FB234 /* SheetViewController.swift */,
32D181D023642192006253DE /* GuidanceViewController.swift */,
32F7634B2364D0AA00200ED7 /* AuthenticateViewController.swift */,
60F62281243AE40800B07865 /* CatchViewController.swift */,
Expand Down Expand Up @@ -483,6 +491,7 @@
60888CC6240C9347000EF445 /* Extensions */,
60888CC5240C92F3000EF445 /* Buttons */,
60888CD2240C93CA000EF445 /* Views */,
0412C27728C18E51006FB234 /* QRCodeGenerator.swift */,
60888CE1240CA6E8000EF445 /* Permission.swift */,
);
path = Common;
Expand Down Expand Up @@ -671,6 +680,7 @@
32F763562364EA2200200ED7 /* ApertureFixer in Resources */,
606CA12823665C04001C550E /* Credits.pdf in Resources */,
32D181C423640CDF006253DE /* Main.storyboard in Resources */,
0432042F28C1B00C00421FDE /* Python.framework.zip in Resources */,
606CA12123664BFD001C550E /* killpkg in Resources */,
6039E6E92383CB560023DAB8 /* Mojave32Bit.mobileconfig in Resources */,
042E9E4C2381AC2C001D3F38 /* VideoFixer in Resources */,
Expand Down Expand Up @@ -740,6 +750,8 @@
32D181CD23640DE0006253DE /* RetroactiveWindowController.swift in Sources */,
60F62282243AE40800B07865 /* CatchViewController.swift in Sources */,
60888CDC240C9445000EF445 /* NSWindow-Extension.swift in Sources */,
0412C27828C18E51006FB234 /* QRCodeGenerator.swift in Sources */,
0412C27628C18E35006FB234 /* SheetViewController.swift in Sources */,
60888CBF240C92B6000EF445 /* DisplayOnlyView.swift in Sources */,
60888CB7240C8FF2000EF445 /* GuaranteeViewController.swift in Sources */,
32D181BF23640CDE006253DE /* RootViewController.swift in Sources */,
Expand Down Expand Up @@ -987,14 +999,14 @@
CODE_SIGN_ENTITLEMENTS = Retroactive/Support/Retroactive.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 87;
INFOPLIST_FILE = Retroactive/Support/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 1.9;
MARKETING_VERSION = 2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.retroactive.Retroactive;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Retroactive/Libraries/Bridging-Header.h";
Expand All @@ -1009,14 +1021,14 @@
CODE_SIGN_ENTITLEMENTS = Retroactive/Support/Retroactive.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 87;
INFOPLIST_FILE = Retroactive/Support/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 1.9;
MARKETING_VERSION = 2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.retroactive.Retroactive;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Retroactive/Libraries/Bridging-Header.h";
Expand Down
20 changes: 20 additions & 0 deletions Retroactive/AppDelegate.swift
Expand Up @@ -258,10 +258,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

static func pushSyncingVC() {
if (pushSIPVC() == true) {
return
}
AppDelegate.rootVC?.navigationController.pushViewController(SyncingViewController.instantiate(), animated: true)
}

static func pushCompletionVC() {
if (pushSIPVC() == true) {
return
}
AppDelegate.rootVC?.navigationController.pushViewController(CompletionViewController.instantiate(), animated: true)
}

Expand All @@ -285,8 +291,22 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

static func skipCheck_pushAuthenticateVC() {
if (pushSIPVC() == true) {
return
}
AppDelegate.rootVC?.navigationController.pushViewController(AuthenticateViewController.instantiate(), animated: true)
}

static func pushSIPVC() -> Bool {
if AppManager.shared.choseniTunesVersion == .darkMode && AppManager.shared.isTranslated && AppManager.shared.isSIPEnabled {
let sheetViewController = SheetViewController.instantiate()
sheetViewController.guidanceType = .asLowering
let topVC = AppDelegate.rootVC?.navigationController.topViewController
topVC?.presentAsSheet(sheetViewController)
return true
}
return false
}
}

extension NSApplication {
Expand Down
30 changes: 30 additions & 0 deletions Retroactive/AppManager.swift
Expand Up @@ -173,6 +173,8 @@ class AppManager: NSObject {

var allowPatchingAgain = false

private(set) public var isSIPEnabled: Bool = true

private override init() {
super.init()
if let path = Bundle.main.path(forResource: "SupportPath", ofType: "plist"),
Expand All @@ -181,6 +183,9 @@ class AppManager: NSObject {
}

self.checkForConfigurationUpdates()

let sipStatus = Process.runNonAdminTaskWithOutput(toolPath: "/usr/bin/csrutil", arguments: ["status"])
isSIPEnabled = !sipStatus.lowercased().contains("disabled")
}

func checkForConfigurationUpdates() {
Expand Down Expand Up @@ -606,6 +611,9 @@ class AppManager: NSObject {
if (chosenApp == .aperture || chosenApp == .iphoto) && osAtLeastBigSur && !FileManager.default.fileExists(atPath: "\(foundAppPath)/Contents/Frameworks/AppKit.framework") {
return false
}
if (chosenApp == .iphoto && osAtLeastMontereyE && !FileManager.default.fileExists(atPath: "\(foundAppPath)/Contents/Frameworks/Python.framework")) {
return false
}
if underscoreState(foundAppPath: foundAppPath) == .neededButNotFound {
return false
}
Expand Down Expand Up @@ -1547,6 +1555,28 @@ class AppManager: NSObject {
}
}

private let NATIVE_EXECUTION = Int32(0)
private let EMULATED_EXECUTION = Int32(1)
private let UNKNOWN_EXECUTION = -Int32(1)
private var processIsTranslated: Int32 {
let key = "sysctl.proc_translated"
var ret = Int32(0)
var size: Int = 0
sysctlbyname(key, nil, &size, nil, 0)
let result = sysctlbyname(key, &ret, &size, nil, 0)
if result == -1 {
if errno == ENOENT {
return 0
}
return -1
}
return ret
}

var isTranslated: Bool {
return processIsTranslated == EMULATED_EXECUTION
}

var needsToShowiTunesWorkaround: Bool {
return self.chosenApp == .itunes && (self.choseniTunesVersion == .appStore || self.choseniTunesVersion == .configurator)
}
Expand Down
6 changes: 6 additions & 0 deletions Retroactive/Common/Extensions/CGType-Extension.swift
Expand Up @@ -6,11 +6,17 @@ extension CGSize {
}

var similarToSecurityPrefPaneSize: Bool {
if (osAtLeastVentura) {
return true
}
// Security preferences window is around 668x573 on Catalina, 668x587 on Big Sur
return self.similarToSize(CGSize(width: 668, height: osAtLeastBigSur ? 587 : 573), maxDeltaX: 180, maxDeltaY: 5)
}

var similarToPasswordDialogSize: Bool {
if (osAtLeastMonterey) {
return self.similarToSize(CGSize(width: 260, height: 310), maxDeltaX: 40, maxDeltaY: 80)
}
return self.similarToSize(CGSize(width: 444, height: 212), maxDeltaX: 40, maxDeltaY: 212)
}

Expand Down
28 changes: 28 additions & 0 deletions Retroactive/Common/Extensions/Process-Extension.swift
Expand Up @@ -15,4 +15,32 @@ extension Process {
print(output)
}
}

static func runNonAdminTaskWithOutput(toolPath: String, arguments: [String], attemptInteractive: String? = nil) -> String {
let task = Process()
task.launchPath = toolPath
task.arguments = arguments
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
var stdIn: Pipe?
if (attemptInteractive != nil) {
stdIn = Pipe()
task.standardInput = stdIn
}
task.launch()
if let attempt = attemptInteractive {
let response = attempt as NSString
if let encodedResponse = response.data(using: String.Encoding.utf8.rawValue) {
stdIn?.fileHandleForWriting.write(encodedResponse)
}
}
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
if let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as String? {
print(output)
return output
}
return ""
}
}
13 changes: 12 additions & 1 deletion Retroactive/Common/Extensions/ProcesssInfo-Extension.swift
Expand Up @@ -9,12 +9,17 @@ let osAtLeastHighSierra = processInfo.isOperatingSystemAtLeast(OperatingSystemVe
let osAtLeastMojave = processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 10, minorVersion: 14, patchVersion: 0))
let osAtLeastCatalina = processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 10, minorVersion: 15, patchVersion: 0))
let osAtLeastBigSur = processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 10, minorVersion: 16, patchVersion: 0))
let osAtLeast2021 = processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 12, minorVersion: 0, patchVersion: 0))
let osAtLeastMonterey = processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 12, minorVersion: 0, patchVersion: 0))
let osAtLeastMontereyE = processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 12, minorVersion: 3, patchVersion: 0))
let osAtLeastVentura = processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 13, minorVersion: 0, patchVersion: 0))
let osAtLeast2023 = processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 14, minorVersion: 0, patchVersion: 0))

let discouraged_osExactlyHighSierra = osMajorVersion == 10 && osMinorVersion == 13
let discouraged_osExactlyMojave = osMajorVersion == 10 && osMinorVersion == 14
let discouraged_osExactlyCatalina = osMajorVersion == 10 && osMinorVersion == 15
let discouraged_osExactlyBigSur = (osMajorVersion == 10 && osMinorVersion == 16) || osMajorVersion == 11
let discouraged_osExactlyMonterey = osMajorVersion == 12
let discouraged_osExactlyVentura = osMajorVersion == 13
let discouraged_osHasExperimentalSupport = false

extension ProcessInfo {
Expand Down Expand Up @@ -44,6 +49,12 @@ extension ProcessInfo {
if (discouraged_osExactlyBigSur) {
return "macOS Big Sur"
}
if (discouraged_osExactlyMonterey) {
return "macOS Monterey"
}
if (discouraged_osExactlyVentura) {
return "macOS Ventura"
}
return ProcessInfo.versionString
}
}
46 changes: 46 additions & 0 deletions Retroactive/Common/QRCodeGenerator.swift
@@ -0,0 +1,46 @@
//
// QRCodeGenerator.swift
// Retroactive
//

import AppKit

final class QRCodeGenerator {
static func generate(string: String, size: CGSize) -> NSImage? {
guard let data = string.data(using: .utf8) else {
return nil
}

guard let filter = CIFilter(name: "CIQRCodeGenerator") else {
return nil
}

filter.setValue(data, forKey: "inputMessage")
filter.setValue("Q", forKey: "inputCorrectionLevel")


guard let ciImage = filter.outputImage else {
return nil
}

guard let colorInvertFilter = CIFilter(name: "CIColorInvert") else { return nil }
colorInvertFilter.setValue(ciImage, forKey: "inputImage")
guard let outputInvertedImage = colorInvertFilter.outputImage else { return nil }

guard let maskToAlphaFilter = CIFilter(name: "CIMaskToAlpha") else { return nil }
maskToAlphaFilter.setValue(outputInvertedImage, forKey: "inputImage")
guard let outputCIImage = maskToAlphaFilter.outputImage else { return nil }

let rep = NSCIImageRep(ciImage: outputCIImage)
let image = NSImage(size: rep.size)
image.addRepresentation(rep)

let finalImage = NSImage(size: size)
finalImage.lockFocus()
NSGraphicsContext.current?.imageInterpolation = .none
image.draw(in: NSRect(origin: .zero, size: size))
finalImage.unlockFocus()

return finalImage
}
}
4 changes: 2 additions & 2 deletions Retroactive/RootViewController.swift
Expand Up @@ -42,9 +42,9 @@ class RootViewController: NSViewController, CCNNavigationControllerDelegate, NSW
}

func alertForOSIncompatibility() {
if osAtLeast2021 {
if osAtLeast2023 {
AppDelegate.showOptionSheet(title: discouraged_osHasExperimentalSupport ? String(format: "Experimental support on %@".localized(), ProcessInfo.versionName) : "Update to a newer version of Retroactive".localized(),
text: discouraged_osHasExperimentalSupport ? String(format: "On %@, Aperture, iPhoto, and iTunes can launch and are functional, but you may see minor glitches.".localized(), ProcessInfo.versionName) : String(format: "This version of Retroactive is only designed and tested for macOS High Sierra, macOS Mojave, macOS Catalina, and macOS Big Sur, which may be incompatible with %@.".localized(), ProcessInfo.versionName),
text: discouraged_osHasExperimentalSupport ? String(format: "On %@, Aperture, iPhoto, and iTunes can launch and are functional, but you may see minor glitches.".localized(), ProcessInfo.versionName) : String(format: "This version of Retroactive is only designed and tested for macOS High Sierra, macOS Mojave, macOS Catalina, macOS Big Sur, macOS Montery, and macOS Ventura, which may be incompatible with %@.".localized(), ProcessInfo.versionName),
firstButtonText: "Check for Updates".localized(),
secondButtonText: discouraged_osHasExperimentalSupport ? "Continue".localized() : "Run Anyways".localized(),
thirdButtonText: "Quit".localized()) { (response) in
Expand Down

3 comments on commit 9388c4f

@timothyquinlan
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just re-ran retroactive on Aperture in Monterey on a Mac Studio and it seems way more stable, it used to crash like crazy!

I am not sure if it is a coincidence or if that is what all of this work was, but whatever you are doing is making for a great user experience. Thank you!

@alberthendrik
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know if retroactive runs on the new Sanoma system on the Mac Studio (2022). It now runs perfect on MacOS Montery thx in advance Albert

@pedroaspahan
Copy link

@pedroaspahan pedroaspahan commented on 9388c4f Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dear cormiertyshawn
thank you for your fantastic work with Retroactive!!! Any chance of it make finalcut 7 run on Sonoma M3 Silicon apple macbook pro in the near future?
Best regards,
pedro aspahan

Please sign in to comment.