Clover.app v1.22

Improved Clover installer with better detailed log.
This commit is contained in:
vectorsigma72 2020-05-13 19:09:30 +02:00
parent 84c8474388
commit 6aac20b758
12 changed files with 197 additions and 186 deletions

View File

@ -1309,7 +1309,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1.21;
CURRENT_PROJECT_VERSION = 1.22;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Clover/Frameworks",
@ -1336,7 +1336,7 @@
"$(PROJECT_DIR)/Clover/Library",
"$(PROJECT_DIR)",
);
MARKETING_VERSION = 1.21;
MARKETING_VERSION = 1.22;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = org.slice.Clover;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1357,7 +1357,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1.21;
CURRENT_PROJECT_VERSION = 1.22;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Clover/Frameworks",
@ -1383,7 +1383,7 @@
"$(PROJECT_DIR)/Clover/Library",
"$(PROJECT_DIR)",
);
MARKETING_VERSION = 1.21;
MARKETING_VERSION = 1.22;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = org.slice.Clover;
PRODUCT_NAME = "$(TARGET_NAME)";

View File

@ -37,6 +37,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
var daSession : DASession? = nil
var daContext : UnsafeMutablePointer<Int> = UnsafeMutablePointer<Int>.allocate(capacity: 1)
//MARK: deinit
deinit {
if (self.daSession != nil) {
DASessionUnscheduleFromRunLoop(self.daSession!,
@ -47,6 +48,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
self.daContext.deallocate()
}
//MARK: Applicatin Delegate
func applicationDidBecomeActive(_ notification: Notification) {
// print("applicationDidBecomeActive")
}
@ -143,7 +145,16 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
}
CFRunLoopRun()
}
//MARK: Disks obeservation call back
@objc func reFreshDisksList() {
(self.settingsWC?.contentViewController as? SettingsViewController)?.searchDisks()
(self.settingsWC?.contentViewController as? SettingsViewController)?.searchESPDisks()
(self.installerWC?.contentViewController as? InstallerViewController)?.populateTargets()
(self.installerOutWC?.contentViewController as? InstallerOutViewController)?.populateTargets()
}
//MARK: Documents
func applicationShouldOpenUntitledFile(_ sender: NSApplication) -> Bool {
if !self.havefinishLaunching {
if let files : NSArray = UDs.value(forKey: "Docs") as? NSArray {
@ -155,6 +166,22 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
return false
}
//MARK: Activation Policy
func setActivationPolicy() {
let documents = NSDocumentController.shared.documents
var showDock : Bool = documents.count > 1
if !showDock {
showDock = AppSD.installerWC != nil || AppSD.installerOutWC != nil || AppSD.themeManagerWC != nil
}
NSApp.setActivationPolicy(showDock ? .regular : .accessory)
if showDock {
NSApp.activate(ignoringOtherApps: true)
}
}
//MARK: Popover
@objc func showPopover(_ sender: Any?) {
if (self.popover == nil) {
self.popover = NSPopover()
@ -178,7 +205,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
self.popover?.show(relativeTo: v.bounds, of: v, preferredEdge: NSRectEdge.maxY)
}
}
//NSApp.activate(ignoringOtherApps: true)
}
}
@ -186,14 +212,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
return true
}
@objc func reFreshDisksList() {
(self.settingsWC?.contentViewController as? SettingsViewController)?.searchDisks()
(self.settingsWC?.contentViewController as? SettingsViewController)?.searchESPDisks()
(self.installerWC?.contentViewController as? InstallerViewController)?.populateTargets()
(self.installerOutWC?.contentViewController as? InstallerOutViewController)?.populateTargets()
}
//MARK: App termination
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
return self.isInstalling ? .terminateLater : .terminateNow
}

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15504"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -153,17 +153,17 @@
</connections>
</button>
<scrollView focusRingType="none" borderType="line" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="29d-rx-wyR">
<rect key="frame" x="191" y="46" width="469" height="100"/>
<rect key="frame" x="191" y="46" width="469" height="116"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="sgJ-el-Xcb">
<rect key="frame" x="1" y="1" width="467" height="98"/>
<rect key="frame" x="1" y="1" width="467" height="114"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView editable="NO" drawsBackground="NO" importsGraphics="NO" verticallyResizable="YES" allowsDocumentBackgroundColorChange="YES" smartInsertDelete="YES" id="jRs-Un-piV">
<rect key="frame" x="0.0" y="0.0" width="467" height="98"/>
<textView editable="NO" drawsBackground="NO" importsGraphics="NO" verticallyResizable="YES" allowsCharacterPickerTouchBarItem="NO" textCompletion="NO" id="jRs-Un-piV">
<rect key="frame" x="0.0" y="0.0" width="467" height="114"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<size key="minSize" width="467" height="98"/>
<size key="minSize" width="467" height="114"/>
<size key="maxSize" width="469" height="10000000"/>
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
</textView>
@ -182,13 +182,13 @@
<rect key="frame" x="572" y="21" width="16" height="16"/>
</progressIndicator>
<scrollView wantsLayer="YES" focusRingType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2IB-nz-hvO">
<rect key="frame" x="191" y="154" width="469" height="247"/>
<rect key="frame" x="191" y="170" width="469" height="231"/>
<clipView key="contentView" id="nIe-kl-Tbc">
<rect key="frame" x="1" y="1" width="467" height="245"/>
<rect key="frame" x="1" y="1" width="467" height="229"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView selectable="YES" id="wuN-Fc-foZ">
<rect key="frame" x="0.0" y="0.0" width="467" height="241"/>
<rect key="frame" x="0.0" y="0.0" width="467" height="229"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" id="3QJ-S2-HNO">
<size key="itemSize" width="50" height="50"/>
@ -229,7 +229,7 @@
<constraint firstItem="UUc-TY-xzg" firstAttribute="top" secondItem="29d-rx-wyR" secondAttribute="bottom" constant="7" id="QQC-gX-VdQ"/>
<constraint firstItem="PmA-i6-75b" firstAttribute="top" secondItem="YIQ-b2-eUp" secondAttribute="bottom" constant="10" id="Qxd-h7-jMv"/>
<constraint firstItem="Hwp-8t-DOD" firstAttribute="top" secondItem="X04-eM-Ork" secondAttribute="bottom" constant="10" id="SV7-JX-NMo"/>
<constraint firstItem="29d-rx-wyR" firstAttribute="top" relation="greaterThanOrEqual" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="UTw-RK-jlw"/>
<constraint firstItem="29d-rx-wyR" firstAttribute="top" relation="greaterThanOrEqual" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="236" id="UTw-RK-jlw"/>
<constraint firstItem="ovO-Bp-yLs" firstAttribute="leading" secondItem="nlq-eW-Xo1" secondAttribute="trailing" constant="8" symbolic="YES" id="WE7-q8-lRv"/>
<constraint firstItem="2IB-nz-hvO" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="4" id="WWi-rs-SvD"/>
<constraint firstItem="UUc-TY-xzg" firstAttribute="centerY" secondItem="vhj-ej-Juw" secondAttribute="centerY" id="XNR-oi-Z1V"/>
@ -245,7 +245,7 @@
<constraint firstItem="PmA-i6-75b" firstAttribute="firstBaseline" secondItem="UUc-TY-xzg" secondAttribute="firstBaseline" id="fkB-OV-oxL"/>
<constraint firstAttribute="trailing" secondItem="2IB-nz-hvO" secondAttribute="trailing" constant="20" symbolic="YES" id="fwq-Eg-Fy0"/>
<constraint firstItem="Hwp-8t-DOD" firstAttribute="leading" secondItem="k5V-Bw-sHC" secondAttribute="leading" id="gXd-2b-FML"/>
<constraint firstItem="29d-rx-wyR" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="259" id="gXm-jZ-Wgg"/>
<constraint firstItem="29d-rx-wyR" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="359" id="gXm-jZ-Wgg"/>
<constraint firstItem="vhj-ej-Juw" firstAttribute="leading" secondItem="UUc-TY-xzg" secondAttribute="trailing" constant="12" id="giO-nc-Axb"/>
<constraint firstItem="ovO-Bp-yLs" firstAttribute="leading" secondItem="dxu-Os-Jgh" secondAttribute="trailing" constant="8" symbolic="YES" id="h6v-zb-fD4"/>
<constraint firstItem="X04-eM-Ork" firstAttribute="top" relation="greaterThanOrEqual" secondItem="nlq-eW-Xo1" secondAttribute="bottom" constant="45" id="jTV-ea-zrh"/>
@ -256,7 +256,7 @@
<constraint firstItem="2IB-nz-hvO" firstAttribute="leading" secondItem="29d-rx-wyR" secondAttribute="leading" id="rCg-kP-7Rv"/>
<constraint firstItem="2IB-nz-hvO" firstAttribute="leading" secondItem="ovO-Bp-yLs" secondAttribute="trailing" constant="13" id="rkb-NN-pbA"/>
<constraint firstItem="bcF-vq-OaV" firstAttribute="top" secondItem="dxu-Os-Jgh" secondAttribute="bottom" constant="9" id="sDd-AL-EE4"/>
<constraint firstAttribute="bottom" secondItem="2IB-nz-hvO" secondAttribute="bottom" constant="154" id="sgt-2U-mwk"/>
<constraint firstAttribute="bottom" secondItem="2IB-nz-hvO" secondAttribute="bottom" constant="170" id="sgt-2U-mwk"/>
<constraint firstItem="29d-rx-wyR" firstAttribute="leading" secondItem="UUc-TY-xzg" secondAttribute="leading" id="swH-Iv-tVp"/>
<constraint firstItem="jL3-FD-wKF" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="57" id="tyI-5R-0di"/>
<constraint firstItem="ovO-Bp-yLs" firstAttribute="leading" secondItem="YIQ-b2-eUp" secondAttribute="trailing" constant="8" symbolic="YES" id="vVj-b9-Seh"/>

View File

@ -33,6 +33,7 @@ final class InstallerWindowController: NSWindowController, NSWindowDelegate {
self.window = nil
self.close()
AppSD.installerWC = nil // remove a strong reference
AppSD.setActivationPolicy()
return true
}
@ -570,6 +571,11 @@ final class InstallerViewController: NSViewController {
}
task.terminationHandler = { t in
DispatchQueue.main.async {
self.view.window?.level = .floating
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .normal
}
if t.terminationStatus == 0 {
if isMountPoint(path: disk) {
DispatchQueue.main.async {
@ -578,24 +584,17 @@ final class InstallerViewController: NSViewController {
self.setPreferences(for: self.targetVol)
}
}
DispatchQueue.main.async {
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .floating
self.view.window?.level = .normal
}
} else {
NSSound.beep()
DispatchQueue.main.async {
if #available(OSX 10.11, *) {
self.driversCollection.reloadData()
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .floating
self.view.window?.level = .normal
}
}
}
}
task.launch()
})
} else {
self.targetVol = getMountPoint(from: disk) ?? ""
@ -756,9 +755,10 @@ final class InstallerViewController: NSViewController {
func post(text: String, add: Bool, color: NSColor?, scroll: Bool) {
//let attributes = self.infoText.textStorage?.attributes(at: 0, effectiveRange: nil)
let textColor = (color == nil) ? NSColor.controlTextColor : color!
let attributes = [/*NSAttributedString.Key.font: font,*/ NSAttributedString.Key.foregroundColor: textColor]
let astr = NSAttributedString(string: text, attributes: attributes)
let font = NSFont.userFixedPitchFont(ofSize: 11)
let attributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor]
let astr = NSAttributedString(string: text, attributes: attributes as [NSAttributedString.Key : Any])
if add {
self.infoText.textStorage?.append(astr)
} else {
@ -882,48 +882,46 @@ final class InstallerViewController: NSViewController {
let revIn = findCloverRevision(at: self.targetVol.addPath("EFI")) ?? "0000"
let mediaName = getMediaName(from: getBSDParent(of: disk) ?? "") ?? "NoName"
let backUpPath = NSHomeDirectory().addPath("Desktop/CloverBackUp/\(mediaName)/r\(revIn)_\(now)/EFI")
if #available(OSX 10.10, *) {
DispatchQueue.global(qos: .userInteractive).async {
do {
if !fm.fileExists(atPath: backUpPath.deletingLastPath) {
try fm.createDirectory(atPath: backUpPath.deletingLastPath,
withIntermediateDirectories: true,
attributes: nil)
}
try fm.copyItem(atPath: self.targetVol.addPath("EFI"),
toPath: backUpPath)
//post(text: "backup made at '\(backUpPath)'.\n", add: true, color: nil, scroll: false)
Cloverapp.setValue(backUpPath, forKey: "BackUpPath")
self.installClover(disk: disk, settingDict: Cloverapp)
} catch {
DispatchQueue.main.async {
self.post(text: "The backup failed:\n", add: true, color: nil, scroll: false)
self.post(text: error.localizedDescription, add: false, color: nil, scroll: false)
AppSD.isInstalling = false
self.installButton.isEnabled = true
self.spinner.stopAnimation(nil)
}
DispatchQueue.global(priority: .background).async(execute: { () -> Void in
do {
if !fm.fileExists(atPath: backUpPath.deletingLastPath) {
try fm.createDirectory(atPath: backUpPath.deletingLastPath,
withIntermediateDirectories: true,
attributes: nil)
}
try fm.copyItem(atPath: self.targetVol.addPath("EFI"),
toPath: backUpPath)
//post(text: "backup made at '\(backUpPath)'.\n", add: true, color: nil, scroll: false)
Cloverapp.setValue(backUpPath, forKey: "BackUpPath")
self.installClover(disk: disk, settingDict: Cloverapp)
} catch {
DispatchQueue.main.async {
self.post(text: "The backup failed:\n", add: true, color: nil, scroll: false)
self.post(text: error.localizedDescription, add: false, color: nil, scroll: false)
AppSD.isInstalling = false
self.installButton.isEnabled = true
self.spinner.stopAnimation(nil)
}
}
}
})
} else {
if #available(OSX 10.10, *) {
DispatchQueue.global(qos: .userInteractive).async {
self.installClover(disk: disk, settingDict: Cloverapp)
}
}
DispatchQueue.global(priority: .background).async(execute: { () -> Void in
self.installClover(disk: disk, settingDict: Cloverapp)
})
}
}
func installClover(disk: String, settingDict : NSDictionary) {
self.post(text: "Installation begin..\n", add: true, color: nil, scroll: false)
run(cmd: "LC_ALL=C /usr/sbin/diskutil list > /tmp/diskutil.List")
DispatchQueue.main.async {
self.post(text: "Installation begin..\n", add: true, color: nil, scroll: false)
}
if !isMountPoint(path: self.targetVol) {
DispatchQueue.main.async {
NSSound.beep()
self.post(text: "Can't find target volume, installation aborted.", add: true, color: nil, scroll: false)
}
return
}
@ -944,11 +942,6 @@ final class InstallerViewController: NSViewController {
DispatchQueue.main.async {
self.spinner.startAnimation(nil)
self.installButton.isEnabled = false
self.view.window?.level = .floating // just a hack to keep window in front momentarily
}
DispatchQueue.main.asyncAfter(deadline: .now() + 6.0) {
self.view.window?.level = .normal
}
let task = Process()
@ -972,18 +965,12 @@ final class InstallerViewController: NSViewController {
if data.count > 0 {
let output = String(decoding: data, as: UTF8.self)
DispatchQueue.main.async {
if self.view.window?.level != .normal {
self.view.window?.level = .normal
}
self.post(text: "\n" + output,
add: true,
color: nil,
scroll: true)
}
fh.waitForDataInBackgroundAndNotify()
} else {
NotificationCenter.default.removeObserver(op1 as Any)
}
}
@ -994,6 +981,9 @@ final class InstallerViewController: NSViewController {
NotificationCenter.default.removeObserver(op2 as Any)
let success = (task.terminationStatus == 0)
DispatchQueue.main.async {
self.view.window?.level = .floating
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .normal
let message = success ? "Installation succeded".locale : "Installation failed".locale
self.post(text: "\n\(message).", add: true, color: nil, scroll: true)
@ -1016,6 +1006,7 @@ final class InstallerViewController: NSViewController {
self.setPreferences(for: self.targetVol)
}
}
NotificationCenter.default.removeObserver(op1 as Any)
}
task.launch()

View File

@ -31,6 +31,7 @@ final class InstallerOutWindowController: NSWindowController, NSWindowDelegate {
self.window = nil
self.close()
AppSD.installerWC = nil // remove a strong reference
AppSD.setActivationPolicy()
return true
}
@ -515,6 +516,12 @@ final class InstallerOutViewController: NSViewController {
}
task.terminationHandler = { t in
DispatchQueue.main.async {
self.view.window?.level = .floating
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .normal
}
if t.terminationStatus == 0 {
if isMountPoint(path: disk) {
DispatchQueue.main.async {
@ -523,19 +530,11 @@ final class InstallerOutViewController: NSViewController {
self.setPreferences(for: self.targetVol)
}
}
DispatchQueue.main.async {
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .floating
self.view.window?.level = .normal
}
} else {
NSSound.beep()
DispatchQueue.main.async {
self.driversOutline.reloadData()
self.expandAllSections()
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .floating
self.view.window?.level = .normal
}
}
}
@ -696,11 +695,11 @@ final class InstallerOutViewController: NSViewController {
// MARK: Post text
func post(text: String, add: Bool, color: NSColor?, scroll: Bool) {
//let attributes = self.infoText.textStorage?.attributes(at: 0, effectiveRange: nil)
let textColor = (color == nil) ? NSColor.controlTextColor : color!
let attributes = [/*NSAttributedString.Key.font: font,*/ NSAttributedString.Key.foregroundColor: textColor]
let font = NSFont.userFixedPitchFont(ofSize: 11)
let attributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor]
let astr = NSAttributedString(string: text, attributes: attributes)
let astr = NSAttributedString(string: text, attributes: attributes as [NSAttributedString.Key : Any])
//DispatchQueue.global(qos: .background).async {
DispatchQueue.main.async {
if add {
@ -817,31 +816,40 @@ final class InstallerOutViewController: NSViewController {
let mediaName = getMediaName(from: getBSDParent(of: disk) ?? "") ?? "NoName"
let backUpPath = NSHomeDirectory().addPath("Desktop/CloverBackUp/\(mediaName)/r\(revIn)_\(now)/EFI")
do {
if !fm.fileExists(atPath: backUpPath.deletingLastPath) {
try fm.createDirectory(atPath: backUpPath.deletingLastPath,
withIntermediateDirectories: true,
attributes: nil)
DispatchQueue.global(priority: .background).async(execute: { () -> Void in
do {
if !fm.fileExists(atPath: backUpPath.deletingLastPath) {
try fm.createDirectory(atPath: backUpPath.deletingLastPath,
withIntermediateDirectories: true,
attributes: nil)
}
try fm.copyItem(atPath: self.targetVol.addPath("EFI"),
toPath: backUpPath)
//post(text: "backup made at '\(backUpPath)'.\n", add: true, color: nil, scroll: false)
Cloverapp.setValue(backUpPath, forKey: "BackUpPath")
self.installClover(disk: disk, settingDict: Cloverapp)
} catch {
self.post(text: "The backup failed:\n", add: true, color: nil, scroll: false)
self.post(text: error.localizedDescription, add: false, color: nil, scroll: false)
}
try fm.copyItem(atPath: self.targetVol.addPath("EFI"),
toPath: backUpPath)
//post(text: "backup made at '\(backUpPath)'.\n", add: true, color: nil, scroll: false)
Cloverapp.setValue(backUpPath, forKey: "BackUpPath")
self.installClover(disk: disk, settingDict: Cloverapp)
} catch {
post(text: "The backup failed:\n", add: true, color: nil, scroll: false)
post(text: error.localizedDescription, add: false, color: nil, scroll: false)
}
})
} else {
self.installClover(disk: disk, settingDict: Cloverapp)
DispatchQueue.global(priority: .background).async(execute: { () -> Void in
self.installClover(disk: disk, settingDict: Cloverapp)
})
}
}
func installClover(disk: String, settingDict : NSDictionary) {
self.post(text: "Installation begin..\n", add: true, color: nil, scroll: false)
run(cmd: "LC_ALL=C /usr/sbin/diskutil list > /tmp/diskutil.List")
DispatchQueue.main.async {
self.post(text: "Installation begin..\n", add: true, color: nil, scroll: false)
}
if !isMountPoint(path: self.targetVol) {
NSSound.beep()
self.post(text: "Can't find target volume, installation aborted.", add: true, color: nil, scroll: false)
DispatchQueue.main.async {
NSSound.beep()
self.post(text: "Can't find target volume, installation aborted.", add: true, color: nil, scroll: false)
}
return
}
@ -857,46 +865,47 @@ final class InstallerOutViewController: NSViewController {
try? fm.removeItem(atPath: "/tmp/Cloverapp")
if settingDict.write(toFile: "/tmp/Cloverapp", atomically: false) {
self.installButton.isEnabled = false
AppSD.isInstalling = true
self.spinner.startAnimation(nil)
self.view.window?.level = .floating // just a hack to keep window in front momentarily
DispatchQueue.main.asyncAfter(deadline: .now() + 6.0) {
self.view.window?.level = .normal
}
let helperPath = Bundle.main.executablePath!.deletingLastPath.addPath("CloverDaemonNew")
let script = "do shell script \"'\(helperPath)' --CLOVER\" with administrator privileges"
var err : NSDictionary? = nil
let result : NSAppleEventDescriptor = NSAppleScript(source: script)!.executeAndReturnError(&err)
self.post(text: result.stringValue ?? "", add: false, color: nil, scroll: true)
self.spinner.stopAnimation(nil)
let message = (err == nil) ? "Installation succeded".locale : "Installation failed".locale
self.post(text: "\n\(message).", add: true, color: nil, scroll: true)
let alert = NSAlert()
alert.messageText = message
if #available(OSX 10.10, *) {
alert.informativeText = (err == nil) ? "😀" : "😱"
}
alert.alertStyle = (err == nil) ? .informational : .critical
alert.addButton(withTitle: "Close".locale)
alert.beginSheetModal(for: self.view.window!) { (reponse) in
DispatchQueue.main.async {
self.installButton.isEnabled = false
AppSD.isInstalling = true
self.spinner.startAnimation(nil)
let helperPath = Bundle.main.executablePath!.deletingLastPath.addPath("CloverDaemonNew")
let script = "do shell script \"'\(helperPath)' --CLOVER\" with administrator privileges"
var err : NSDictionary? = nil
let result : NSAppleEventDescriptor = NSAppleScript(source: script)!.executeAndReturnError(&err)
self.post(text: result.stringValue ?? "", add: false, color: nil, scroll: true)
self.spinner.stopAnimation(nil)
let message = (err == nil) ? "Installation succeded".locale : "Installation failed".locale
self.post(text: "\n\(message).", add: true, color: nil, scroll: true)
let alert = NSAlert()
alert.messageText = message
if #available(OSX 10.10, *) {
alert.informativeText = (err == nil) ? "😀" : "😱"
}
alert.alertStyle = (err == nil) ? .informational : .critical
alert.addButton(withTitle: "Close".locale)
alert.beginSheetModal(for: self.view.window!) { (reponse) in
}
AppSD.isInstalling = false
self.installButton.isEnabled = true
self.spinner.stopAnimation(nil)
if isMountPoint(path: self.targetVol) {
self.targetVol = getMountPoint(from: disk) ?? ""
}
AppSD.reFreshDisksList()
self.setPreferences(for: self.targetVol)
}
AppSD.isInstalling = false
self.installButton.isEnabled = true
self.spinner.stopAnimation(nil)
if isMountPoint(path: self.targetVol) {
self.targetVol = getMountPoint(from: disk) ?? ""
}
AppSD.reFreshDisksList()
self.setPreferences(for: self.targetVol)
} else {
NSSound.beep()
self.post(text: "Can't write temporary files, installation aborted.", add: true, color: nil, scroll: false)
DispatchQueue.main.async {
NSSound.beep()
self.post(text: "Can't write temporary files, installation aborted.", add: true, color: nil, scroll: false)
}
}
}
}

View File

@ -56,10 +56,7 @@ final class Document: NSDocument {
override func removeWindowController(_ windowController: NSWindowController) {
super.removeWindowController(windowController)
let documents = NSDocumentController.shared.documents
if documents.count == 1 {
NSApp.setActivationPolicy(.accessory)
}
AppSD.setActivationPolicy()
}
override func makeWindowControllers() {

View File

@ -132,6 +132,7 @@ func loadPlist(at path: String) {
dc.openDocument(withContentsOf: URL(fileURLWithPath: path), display: true) {
(document, documentWasAlreadyOpen, error) in
if error != nil {
AppSD.setActivationPolicy()
print(error!.localizedDescription)
NSSound.beep()
} else {
@ -141,10 +142,6 @@ func loadPlist(at path: String) {
}
}
} else {
// check if a document is opened some where
if NSDocumentController.shared.documents.count == 0 {
NSApp.setActivationPolicy(.accessory)
}
// Use reccomended programs (hope) to avoid Text Edit
var success = NSWorkspace.shared.openFile(path, withApplication: "PlistEdit Pro")
if !success {
@ -158,5 +155,6 @@ func loadPlist(at path: String) {
if !success { // open the directory path
success = NSWorkspace.shared.openFile(path.deletingLastPath)
}
AppSD.setActivationPolicy()
}
}

View File

@ -634,11 +634,8 @@ final class SettingsViewController:
AppSD.themeManagerWC = ThemeManagerWC.loadFromNib()
}
AppSD.themeManagerWC?.showWindow(self)
AppSD.themeManagerWC?.window?.level = .floating
AppSD.themeManagerWC?.window?.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
AppSD.themeManagerWC?.window?.level = .normal
AppSD.setActivationPolicy()
}
}
@ -757,17 +754,14 @@ final class SettingsViewController:
// make the app regular
NSApp.setActivationPolicy(.regular)
NSApp.activate(ignoringOtherApps: true)
op.begin { (result) in
if result == .OK {
if let path = op.url?.path {
loadPlist(at: path) // this will make the app regular again in 10.11+
}
} else {
// check if a document is opened some where
if NSDocumentController.shared.documents.count == 0 {
NSApp.setActivationPolicy(.accessory)
}
AppSD.setActivationPolicy()
}
}
}
@ -855,20 +849,16 @@ final class SettingsViewController:
}
AppSD.installerWC?.showWindow(self)
AppSD.installerWC?.window?.level = .floating
AppSD.installerWC?.window?.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
AppSD.installerWC?.window?.level = .normal
AppSD.setActivationPolicy()
} else {
if (AppSD.installerOutWC == nil) {
AppSD.installerOutWC = InstallerOutWindowController.loadFromNib()
}
AppSD.installerOutWC?.showWindow(self)
AppSD.installerOutWC?.window?.level = .floating
AppSD.installerOutWC?.window?.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
AppSD.installerOutWC?.window?.level = .normal
AppSD.setActivationPolicy()
}
}
}

View File

@ -66,8 +66,6 @@ NSComboBoxDataSource {
super.viewDidLoad()
}
self.loaded = true
self.view.window?.title = self.view.window!.title.locale
let settingVC = AppSD.settingsWC?.contentViewController as? SettingsViewController
settingVC?.themeUserCBox.isEnabled = false
@ -760,7 +758,6 @@ NSComboBoxDataSource {
if let disk = sender?.selectedItem?.representedObject as? String {
if !isMountPoint(path: disk) {
self.installButton.isEnabled = false
self.view.window?.level = .floating
DispatchQueue.global(priority: .background).async(execute: { () -> Void in
let cmd = "diskutil mount \(disk)"
let msg = String(format: "Clover wants to mount %@", disk)
@ -777,6 +774,11 @@ NSComboBoxDataSource {
}
task.terminationHandler = { t in
DispatchQueue.main.async {
self.view.window?.level = .floating
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .normal
}
if t.terminationStatus == 0 {
if isMountPoint(path: disk) {
DispatchQueue.main.async {
@ -787,17 +789,11 @@ NSComboBoxDataSource {
}
DispatchQueue.main.async {
self.installButton.isEnabled = true
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .floating
self.view.window?.level = .normal
}
} else {
DispatchQueue.main.async {
NSSound.beep()
self.installButton.isEnabled = true
self.view.window?.makeKeyAndOrderFront(nil)
self.view.window?.level = .floating
self.view.window?.level = .normal
self.showInstalledThemes(self.installedThemesCheckBox)
}
}
@ -866,6 +862,7 @@ final class ThemeManagerWC: NSWindowController, NSWindowDelegate {
self.window = nil
self.close()
AppSD.themeManagerWC = nil // remove a strong reference
AppSD.setActivationPolicy()
return true
}
}

View File

@ -11,6 +11,7 @@ import Foundation
final class Installer: NSObject {
let ktempLogPath = "/tmp/cltmplog"
let kDiskUtilListPath = "/tmp/diskutil.List"
private var realTime : Bool = true
private var gTargetVolume : String? = nil
@ -33,6 +34,7 @@ final class Installer: NSObject {
}
t.arguments = ["-c", "rm -rf /tmp/Clover* && rm -f /tmp/boot0* && rm -f /tmp/boot1*"]
t.launch()
t.waitUntilExit()
}
private func saveLog() {
@ -185,7 +187,6 @@ final class Installer: NSObject {
// MARK: Install
func install() {
let df = DateFormatter()
df.locale = Locale(identifier: "en_US")
df.dateFormat = "yyyy-MM-dd hh:mm:ss"
@ -219,7 +220,7 @@ final class Installer: NSObject {
let alt : Bool = (CloverappDict["alt"] as? NSNumber)?.boolValue ?? false
log("\(version) (v\(daemonVersion)), \(now)")
log("\(version) (installer library v\(daemonVersion)), \(now)")
log("macOS \(ProcessInfo().operatingSystemVersionString)")
log("SELF = \(CommandLine.arguments[0])")
if geteuid() != 0 {
@ -318,14 +319,25 @@ final class Installer: NSObject {
}
if (boot2 != nil) {
log("Installation type: BIOS")
log("boot2: \(boot2!)")
preferences.setValue(boot2!, forKey: "boot2")
boot2Path = CloverV2.addPath("Bootloaders/x64").addPath(boot2!)
if !fm.fileExists(atPath: boot2Path!) {
exit("Error: cannot found \"\(boot2!)\".")
}
} else {
log("Installation type: UEFI")
}
if let dlist = try? String(contentsOfFile: kDiskUtilListPath) {
log("\n\n\(dlist)\n")
}
if fm.fileExists(atPath: kDiskUtilListPath) {
try? fm.removeItem(atPath: kDiskUtilListPath)
}
// MARK: Create Directories
createDirectory(at: targetVol.addPath("EFI/CLOVER"), attr: attributes, exitOnError: true)
createDirectory(at: targetVol.addPath("EFI/BOOT"), attr: attributes, exitOnError: true)
@ -452,7 +464,7 @@ final class Installer: NSObject {
} catch { }
for d in docs {
if d.fileExtension == "efi" {
if !d.hasPrefix(".") {
var a : [FileAttributeKey: Any]? = nil
do {
a = try fm.attributesOfItem(atPath: cv2docs.addPath(d))
@ -605,8 +617,6 @@ final class Installer: NSObject {
let output = String(decoding: data, as: UTF8.self)
self.log(output)
fh.waitForDataInBackgroundAndNotify()
} else {
NotificationCenter.default.removeObserver(op1 as Any)
}
}
@ -618,7 +628,7 @@ final class Installer: NSObject {
if task.terminationStatus != 0 {
self.exit("Error: failed installing boot sectors.")
}
NotificationCenter.default.removeObserver(op1 as Any)
}
task.launch()
@ -654,9 +664,11 @@ final class Installer: NSObject {
}
task.arguments = [ "umount", "force", disk ]
task.launch()
task.waitUntilExit()
}
cleanUp()
}
Darwin.exit(EXIT_SUCCESS)
// ------------- end
}

View File

@ -8,7 +8,7 @@
import Foundation
let daemonVersion = "1.1.4"
let daemonVersion = "1.1.5"
let fm = FileManager.default

View File

@ -40,7 +40,7 @@ fi
}
echo
echo "Installing boot sectors (version of Wed 30 Dec 2019, 20:01)"
echo "Installing boot sectors (version of Wed 13 May 2020, 15:49)"
echo
echo "disk: ${disk}"
echo "bootdev: ${bootdev}"
@ -94,8 +94,6 @@ if [[ "${rootdisk}" == "${disk}" ]]; then
keepmounted=1
fi
echo
LC_ALL=C /usr/sbin/diskutil list
echo
# hfs can cause a panic writing boot sectors if journaled