diff --git a/.gitignore b/.gitignore
index cd4afb8..4b7b5f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,7 @@
arm64
x86_64
build
+CmdBar
+CmdBar.app
+cmdbar_updater
+src/updater
diff --git a/src/AboutViewController.swift b/src/AboutViewController.swift
index 04decfc..30ecb83 100644
--- a/src/AboutViewController.swift
+++ b/src/AboutViewController.swift
@@ -5,7 +5,7 @@
// Created by Igor Kolokolnikov on 8/16/23.
//
-import Cocoa
+import AppKit
// MARK: - Constants
fileprivate enum AboutLinks {
@@ -24,12 +24,6 @@ enum Strings {
static let activating = "Activating..."
}
-fileprivate enum ViewConstants {
- static let spacing2: CGFloat = 2
- static let spacing10: CGFloat = 10
- static let spacing20: CGFloat = 20
-}
-
// MARK: - Controller
class AboutViewController: NSViewController, NSTextFieldDelegate {
// MARK: - Views
diff --git a/src/AppDelegate.swift b/src/AppDelegate.swift
index 0e5284e..498c827 100644
--- a/src/AppDelegate.swift
+++ b/src/AppDelegate.swift
@@ -1,4 +1,4 @@
-import Cocoa
+import AppKit
import ServiceManagement
class AppDelegate: NSObject, NSApplicationDelegate {
diff --git a/src/CBMenuBarItem.swift b/src/CBMenuBarItem.swift
index f7c65d4..d64350a 100644
--- a/src/CBMenuBarItem.swift
+++ b/src/CBMenuBarItem.swift
@@ -28,7 +28,7 @@
// from the coverage of the license being applied to the rest of the code.
//
-import Cocoa
+import AppKit
import os
final class CBMenuBarItem: NSObject, NSWindowDelegate {
diff --git a/src/CmdBar.entitlements b/src/CmdBar.entitlements
index 0c67376..4b29477 100644
--- a/src/CmdBar.entitlements
+++ b/src/CmdBar.entitlements
@@ -1,5 +1,10 @@
-
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.get-task-allow
+
+
diff --git a/src/CmdManager.swift b/src/CmdManager.swift
index d0ad443..f362b1f 100644
--- a/src/CmdManager.swift
+++ b/src/CmdManager.swift
@@ -1,14 +1,12 @@
-import Foundation
-import Cocoa
+import AppKit
-// MARK: - CmdFile
class CmdFile {
- // MARK: - State
private var timer: DispatchSourceTimer?
private(set) var lastExec = Int(Date().timeIntervalSince1970)
var untilNextExec: Int {
get {
- let res = reloadTime - (Int(Date().timeIntervalSince1970) - lastExec)
+ let res = reloadTime -
+ (Int(Date().timeIntervalSince1970) - lastExec)
if res <= 0 { return reloadTime }
return res
}
@@ -16,11 +14,10 @@ class CmdFile {
private(set) var url: URL
private(set) var reloadTime: Int
- private var statusItem: CBMenuBarItem = CBMenuBarItem()
+ private(set) var statusItem: CBMenuBarItem = CBMenuBarItem()
private var shouldWait = false
- // MARK: - Initializers
init(url: URL, reloadTime: Int) {
self.url = url
self.reloadTime = reloadTime
@@ -37,7 +34,6 @@ class CmdFile {
cancelTimer()
}
- // MARK: - Reload Widget
private func reloadWidget() {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
if let url = self?.url {
@@ -45,10 +41,13 @@ class CmdFile {
let execResult = execute(atPath: url)
DispatchQueue.main.async {
if execResult.title.isEmpty {
- self?.statusItem.setImage(title: "exclamationmark.triangle.fill", description: "Warning")
+ self?.statusItem.setImage(
+ title: "exclamationmark.triangle.fill",
+ description: "Warning")
self?.statusItem.setTitle("")
} else {
- self?.statusItem.setImage(title: nil, description: "")
+ self?.statusItem.setImage(title: nil,
+ description: "")
self?.statusItem.setTitle(execResult.0)
}
self?.statusItem.setContents(to: execResult.body)
@@ -58,7 +57,6 @@ class CmdFile {
}
}
- // MARK: - Timer
private func setupTimer() {
timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer?.schedule(deadline: .now(), repeating: .seconds(reloadTime))
@@ -91,15 +89,12 @@ class CmdFile {
}
}
-// MARK: - CmdManager
class CmdManager {
- //MARK: - State
static let standard = CmdManager()
var paths: [CmdFile] = []
private var defaultStatusItem: NSStatusItem?
- // MARK: - Configure
func configure() {
getPaths()
if paths.isEmpty {
@@ -111,23 +106,31 @@ class CmdManager {
private func getPaths() {
let manager = FileManager.default
- let path = manager.homeDirectoryForCurrentUser.appending(path: ".cmdbar")
- if let contents = try? manager.contentsOfDirectory(atPath: path.path()) {
+ let path = manager.homeDirectoryForCurrentUser
+ .appending(path: ".cmdbar")
+ if let contents = try? manager
+ .contentsOfDirectory(atPath: path.path()) {
for content in contents {
let filePath = path.appending(path: content)
let domains = filePath.path().components(separatedBy: ".")
if (isValidTimeFormat(domains[domains.count - 1])) {
- paths.append(CmdFile(url: filePath, reloadTime: intervalToSeconds(from: domains[domains.count - 1])))
- } else if (domains.last == "sh" && isValidTimeFormat(domains[domains.count - 2])) {
- paths.append(CmdFile(url: filePath, reloadTime: intervalToSeconds(from: domains[domains.count - 2])))
+ paths.append(CmdFile(url: filePath,
+ reloadTime: intervalToSeconds(
+ from: domains[domains.count - 1])))
+ } else if domains.last == "sh" &&
+ isValidTimeFormat(domains[domains.count - 2]) {
+ paths.append(CmdFile(url: filePath,
+ reloadTime: intervalToSeconds(
+ from: domains[domains.count - 2])))
}
}
}
}
private func setupMenu() {
- defaultStatusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
+ defaultStatusItem = NSStatusBar.system
+ .statusItem(withLength: NSStatusItem.variableLength)
if let btn = defaultStatusItem?.button {
let image = NSApp.applicationIconImage
image!.size = NSSize(width: 22, height: 22)
@@ -135,13 +138,21 @@ class CmdManager {
}
guard defaultStatusItem != nil else { return }
let menu = NSMenu()
- menu.addItem(NSMenuItem(title: "Reload", action: #selector(reloadWidgets), keyEquivalent: ""))
+ menu.addItem(NSMenuItem(title: "Reload",
+ action: #selector(reloadWidgets),
+ keyEquivalent: ""))
menu.addItem(NSMenuItem.separator())
- menu.addItem(NSMenuItem(title: "About", action: #selector(showAbout), keyEquivalent: ""))
+ menu.addItem(NSMenuItem(title: "About",
+ action: #selector(showAbout),
+ keyEquivalent: ""))
menu.addItem(NSMenuItem.separator())
- menu.addItem(NSMenuItem(title: "Check for Updates...", action: #selector(checkForUpdates), keyEquivalent: ""))
+ menu.addItem(NSMenuItem(title: "Check for Updates...",
+ action: #selector(checkForUpdates),
+ keyEquivalent: ""))
menu.addItem(NSMenuItem.separator())
- menu.addItem(NSMenuItem(title: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))
+ menu.addItem(NSMenuItem(title: "Quit",
+ action: #selector(NSApplication.terminate(_:)),
+ keyEquivalent: "q"))
defaultStatusItem!.menu = menu
}
@@ -164,7 +175,6 @@ class CmdManager {
reloadItems()
}
- // MARK: - NSMenu Functions
@objc private func showAbout() {
delegate.showAbout()
}
diff --git a/src/CmdViewController.swift b/src/CmdViewController.swift
index d9cc194..322fa26 100644
--- a/src/CmdViewController.swift
+++ b/src/CmdViewController.swift
@@ -1,22 +1,17 @@
-import Cocoa
+import AppKit
+import Carbon
import ServiceManagement
-import OSLog
fileprivate enum Metrics {
- static let contentMinWidth = 400.0
- static let contentMaxWidth = /*600.0*/ NSScreen.main!.visibleFrame.size.width * 0.7 // REVIEW: Under what circumstances can NSScreen return nil?
+ static let contentMinWidth = 400.0
+ static let contentMaxWidth = /*600.0*/ NSScreen.main!.visibleFrame.size.width * 0.7 // WARNING: Under what circumstances can NSScreen return nil?
static let contentMinHeight = 160.0
- static let contentMaxHeight = /*800.0*/ NSScreen.main!.visibleFrame.size.height * 0.8 // REVIEW: Under what circumstances can NSScreen return nil?
- static let padding = 10.0
- static let buttonSpacing = 2.0
+ static let contentMaxHeight = /*800.0*/ NSScreen.main!.visibleFrame.size.height * 0.8 // WARNING: Under what circumstances can NSScreen return nil?
+ static let padding = 10.0
+ static let buttonSpacing = 2.0
}
class CmdViewController: NSViewController {
- fileprivate static let logger = Logger(
- subsystem: Bundle.main.bundleIdentifier!,
- category: String(describing: CmdViewController.self)
- )
-
private weak var cmdFile: CmdFile?
private var timer: DispatchSourceTimer?
private var keyboardEvents: EventMonitor?
@@ -332,7 +327,10 @@ class CmdViewController: NSViewController {
}
private func resetReloadButton() {
- reloadButton.image = systemImage("arrow.clockwise.circle.fill", .title2, .large, .init(paletteColors: [.white, .systemBlue]))
+ reloadButton.image = systemImage("arrow.clockwise.circle.fill",
+ .title2, .large,
+ .init(paletteColors: [.white,
+ .systemBlue]))
reloadButton.action = #selector(reloadWidget)
reloadButton.toolTip = "Reload Current"
}
@@ -351,51 +349,51 @@ class CmdViewController: NSViewController {
}
private func setupKeyEvents() {
- keyboardEvents = LocalEventMonitor(mask: [.flagsChanged, .keyDown], handler: { [weak self] event in
+ keyboardEvents = LocalEventMonitor(mask: [.flagsChanged, .keyDown],
+ handler:
+ { [weak self] event in
let modifiers = event.modifierFlags.rawValue
- let command = NSEvent.ModifierFlags.command.rawValue
- let shift = NSEvent.ModifierFlags.shift.rawValue
- let control = NSEvent.ModifierFlags.control.rawValue
- let option = NSEvent.ModifierFlags.option.rawValue
+ let key = event.keyCode
- if event.modifierFlags.contains(.shift) {
- self?.reloadButton.image = systemImage("arrow.clockwise.circle.fill", .title2, .large, .init(paletteColors: [.white, .systemCyan]))
+ if modsContains(keys: OSShift, in: modifiers) {
+ self?.reloadButton.image =
+ systemImage("arrow.clockwise.circle.fill", .title2,
+ .large,.init(paletteColors: [.white,
+ .systemCyan]))
self?.reloadButton.action = #selector(self?.reloadWidgets)
self?.reloadButton.toolTip = "Reload All"
} else {
- self?.reloadButton.image = systemImage("arrow.clockwise.circle.fill", .title2, .large, .init(paletteColors: [.white, .systemBlue]))
+ self?.reloadButton.image =
+ systemImage("arrow.clockwise.circle.fill", .title2,
+ .large, .init(paletteColors: [.white,
+ .systemBlue]))
self?.reloadButton.action = #selector(self?.reloadWidget)
self?.reloadButton.toolTip = "Reload Current"
}
- // NOTE: Standalone keys should go last!
- if (modifiers & command) == command,
- (modifiers & (control | shift | option)) == 0,
- event.keyCode == 12 // Q
- {
- self?.terminateApp()
- } else if (modifiers & command) == command,
- (modifiers & (control | shift | option)) == 0,
- event.keyCode == 13 // W
- {
- self?.view.superview?.window?.resignKey()
- } else if (modifiers & command) == command,
- (modifiers & (control | shift | option)) == 0,
- event.keyCode == 15 // R
- {
- self?.reloadWidget()
- } else if (modifiers & (command & shift)) == command & shift,
- (modifiers & (control | option)) == 0,
- event.keyCode == 15 // R
- {
- self?.reloadWidgets()
- } else if (modifiers & command) == command,
- (modifiers & (control | shift | option)) == 0,
- event.keyCode == 8 // C
- {
- self?.textLabel.currentEditor()?.copy(nil)
- } else if event.keyCode == 12 || event.keyCode == 53 { // Q, ESC
- self?.view.superview?.window?.resignKey()
+ if modsContains(keys: OSCmd, in: modifiers) {
+ if key == kVK_ANSI_Q {
+ self?.terminateApp()
+ } else if key == kVK_ANSI_W {
+ self?.view.superview?.window?.resignKey()
+ } else if key == kVK_ANSI_R {
+ self?.reloadWidget()
+ } else if key == kVK_ANSI_C {
+ self?.textLabel.currentEditor()?.copy(nil)
+ }
+ } else if modsContains(keys: OSCmd | OSShift, in: modifiers) {
+ if key == kVK_ANSI_R {
+ // NOTE: We need to resign the window in order to
+ // prevent the program from intercepting the
+ // events, which result in sounds beign made for
+ // missing performKeyEquivalent.
+ self?.view.window?.resignKey()
+ self?.reloadWidgets()
+ }
+ } else if modsContainsNone(in: modifiers) {
+ if key == kVK_ANSI_Q || key == kVK_Escape {
+ self?.view.superview?.window?.resignKey()
+ }
}
return event
diff --git a/src/EditableNSTextField.swift b/src/EditableNSTextField.swift
index 30cf1ee..a010c70 100644
--- a/src/EditableNSTextField.swift
+++ b/src/EditableNSTextField.swift
@@ -1,32 +1,44 @@
-import Cocoa
+import AppKit
+import Carbon
final class EditableNSTextField: NSTextField {
- private let commandKey = NSEvent.ModifierFlags.command.rawValue
- private let commandShiftKey = NSEvent.ModifierFlags.command.rawValue | NSEvent.ModifierFlags.shift.rawValue
-
override func performKeyEquivalent(with event: NSEvent) -> Bool {
+ let modifiers = event.modifierFlags.rawValue
+ let key = event.keyCode
+
if event.type == NSEvent.EventType.keyDown {
- if (event.modifierFlags.rawValue & NSEvent.ModifierFlags.deviceIndependentFlagsMask.rawValue) == commandKey {
- switch event.charactersIgnoringModifiers! {
- case "x":
- if NSApp.sendAction(#selector(NSText.cut(_:)), to: nil, from: self) { return true }
- case "c":
- if NSApp.sendAction(#selector(NSText.copy(_:)), to: nil, from: self) { return true }
- case "v":
- if NSApp.sendAction(#selector(NSText.paste(_:)), to: nil, from: self) { return true }
- case "z":
- if NSApp.sendAction(Selector(("undo:")), to: nil, from: self) { return true }
- case "a":
- if NSApp.sendAction(#selector(NSResponder.selectAll(_:)), to: nil, from: self) { return true }
- default:
- break
+ if modsContains(keys: OSCmd, in: modifiers) {
+ if key == kVK_ANSI_X {
+ if NSApp.sendAction(#selector(NSText.cut(_:)),
+ to: nil, from: self)
+ { return true }
+ } else if key == kVK_ANSI_C {
+ if NSApp.sendAction(#selector(NSText.copy(_:)),
+ to: nil, from: self)
+ { return true }
+ } else if key == kVK_ANSI_V {
+ if NSApp.sendAction(#selector(NSText.paste(_:)),
+ to: nil, from: self)
+ { return true }
+ } else if key == kVK_ANSI_Z {
+ if NSApp.sendAction(Selector(("undo:")),
+ to: nil, from: self)
+ { return true }
+ } else if key == kVK_ANSI_A {
+ if NSApp.sendAction(
+ #selector(NSResponder.selectAll(_:)),
+ to: nil, from: self)
+ { return true }
}
- } else if (event.modifierFlags.rawValue & NSEvent.ModifierFlags.deviceIndependentFlagsMask.rawValue) == commandShiftKey {
- if event.charactersIgnoringModifiers == "Z" {
- if NSApp.sendAction(Selector(("redo:")), to: nil, from: self) { return true }
+ } else if modsContains(keys: OSCmd | OSShift, in: modifiers) {
+ if key == kVK_ANSI_Z {
+ if NSApp.sendAction(Selector(("redo:")),
+ to: nil, from: self)
+ { return true }
}
}
}
+
return super.performKeyEquivalent(with: event)
}
}
diff --git a/src/EventMonitor.swift b/src/EventMonitor.swift
index 1efd0bc..277dd41 100644
--- a/src/EventMonitor.swift
+++ b/src/EventMonitor.swift
@@ -1,4 +1,4 @@
-import Cocoa
+import AppKit
class EventMonitor {
fileprivate let mask: NSEvent.EventTypeMask
diff --git a/src/Helpers.swift b/src/Helpers.swift
index e5d75fb..6821267 100644
--- a/src/Helpers.swift
+++ b/src/Helpers.swift
@@ -1,6 +1,32 @@
import AppKit
+import Carbon
+
+let OSCtrl = NSEvent.ModifierFlags.control.rawValue
+let OSCmd = NSEvent.ModifierFlags.command.rawValue
+let OSOpt = NSEvent.ModifierFlags.option.rawValue
+let OSShift = NSEvent.ModifierFlags.shift.rawValue
+let OSMods = UInt(OSCtrl | OSCmd | OSOpt | OSShift)
+
+func modsContains(keys: UInt, in modifiers: UInt) -> Bool {
+ return (modifiers & keys) == keys && ((modifiers ^ keys) & OSMods) == 0
+}
+
+func modsContainsNone(in modifiers: UInt) -> Bool {
+ return (modifiers & OSMods) == 0
+}
+
+enum ViewConstants {
+ static let spacing2: CGFloat = 2
+ static let spacing5: CGFloat = 2
+ static let spacing10: CGFloat = 10
+ static let spacing15: CGFloat = 15
+ static let spacing20: CGFloat = 20
+ static let spacing25: CGFloat = 25
+ static let spacing30: CGFloat = 30
+ static let spacing35: CGFloat = 35
+ static let spacing40: CGFloat = 40
+}
-// MARK: - Tracking Notifications
fileprivate extension Notification.Name {
static let beginMenuTracking = Notification.Name("com.apple.HIToolbox.beginMenuTrackingNotification")
static let endMenuTracking = Notification.Name("com.apple.HIToolbox.endMenuTrackingNotification")
@@ -9,10 +35,10 @@ fileprivate extension Notification.Name {
#if(DEBUG)
struct EndpointConstants {
static var versionURL = "http://localhost:8081/version"
- static var appURL = "http://localhost:8081/download"
- static var appURLZip = "http://localhost:8081/static/app/CmdBar.zip"
- static var changelog = "http://localhost:8081/changelog"
- static var validateURL = "http://localhost:8081/validate"
+ static var appURL = "http://localhost:8081/download"
+ static var appURLZip = "http://localhost:8081/static/app/CmdBar.zip"
+ static var changelog = "http://localhost:8081/changelog"
+ static var validateURL = "http://localhost:8081/validate"
}
#else
struct EndpointConstants {
@@ -24,7 +50,6 @@ struct EndpointConstants {
}
#endif
-//
enum Resulting {
case success
case failure
@@ -156,7 +181,10 @@ func getColors(_ light: NSColor, _ dark: NSColor, for appearance: NSAppearance)
}
// ex: systemImage("sunrise.circle.fill", .title2, .large, .init(paletteColors: [.white, .systemOrange]))
-func systemImage(_ name: String, _ size: NSFont.TextStyle, _ scale: NSImage.SymbolScale, _ configuration: NSImage.SymbolConfiguration) -> NSImage? {
+func systemImage(_ name: String, _ size: NSFont.TextStyle,
+ _ scale: NSImage.SymbolScale,
+ _ configuration: NSImage.SymbolConfiguration) -> NSImage?
+{
return NSImage(systemSymbolName: name, accessibilityDescription: nil)?
.withSymbolConfiguration(
NSImage.SymbolConfiguration(textStyle: size, scale: scale)
diff --git a/src/LicenseManager.swift b/src/LicenseManager.swift
index 92c5b21..40a5669 100644
--- a/src/LicenseManager.swift
+++ b/src/LicenseManager.swift
@@ -5,7 +5,7 @@
// Created by Igor Kolokolnikov on 8/26/23.
//
-import Cocoa
+import AppKit
import CryptoKit
fileprivate struct LicenseModel: Codable {
diff --git a/src/Makefile b/src/Makefile
index 44ccb74..06ba4b1 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -86,7 +86,11 @@ $(EXEC).app: $(EXEC)
cp resources/AppIcon.icns $@/Contents/Resources/ && \
cp $(EXEC) $@/Contents/MacOS/ && \
cp cmdbar_updater $@/Contents/MacOS/ && \
- codesign -s ${DEVELOPER_ID} -f --timestamp -o runtime $(EXEC).app
+ $(if $(DEBUG), \
+ codesign --entitlements Grapp.entitlements \
+ -s ${APPLE_DEVELOPMENT} -f --timestamp -o runtime $(EXEC).app, \
+ codesign -s ${APPLE_DEVELOPER_ID_APPLICATION} -f --timestamp \
+ -o runtime $(EXEC).app)
all: zip cmdbar_updater $(EXEC).app
diff --git a/src/MenulessWindow.swift b/src/MenulessWindow.swift
index c13e346..e80a510 100644
--- a/src/MenulessWindow.swift
+++ b/src/MenulessWindow.swift
@@ -1,4 +1,4 @@
-import Cocoa
+import AppKit
class MenulessWindow: NSWindow {
init(viewController: NSViewController) {
diff --git a/src/PopoverPanel.swift b/src/PopoverPanel.swift
index 60c6e13..dce4705 100644
--- a/src/PopoverPanel.swift
+++ b/src/PopoverPanel.swift
@@ -1,4 +1,4 @@
-import Cocoa
+import AppKit
class PopoverPanel: NSPanel {
override var canBecomeKey: Bool { true }
@@ -6,7 +6,8 @@ class PopoverPanel: NSPanel {
init(viewController: NSViewController) {
super.init(
contentRect: CGRect(x: 0, y: 0, width: 100, height: 100),
- styleMask: [.titled, .nonactivatingPanel, .utilityWindow, .fullSizeContentView],
+ styleMask: [.titled, .nonactivatingPanel, .utilityWindow,
+ .fullSizeContentView],
backing: .buffered,
defer: false
)
@@ -22,7 +23,8 @@ class PopoverPanel: NSPanel {
titlebarAppearsTransparent = true
animationBehavior = .none
- collectionBehavior = [.moveToActiveSpace, .fullScreenAuxiliary, .transient]
+ collectionBehavior = [.moveToActiveSpace, .fullScreenAuxiliary,
+ .transient]
isReleasedWhenClosed = false
hidesOnDeactivate = false
diff --git a/src/UpdateViewController.swift b/src/UpdateViewController.swift
index dff3aba..6f1205e 100644
--- a/src/UpdateViewController.swift
+++ b/src/UpdateViewController.swift
@@ -1,28 +1,14 @@
-//
-// UpdateViewController.swift
-// CmdBar
-//
-// Created by Igor Kolokolnikov on 5/23/24.
-//
-
import AppKit
-fileprivate enum ViewConstants {
- static let spacing2: CGFloat = 2
- static let spacing10: CGFloat = 10
- static let spacing20: CGFloat = 20
- static let spacing40: CGFloat = 40
-}
-
fileprivate enum UpdateStatus: String {
- case check = "Check for updates..."
- case latest = "You're up-to-date!"
- case checking = "Checking for udpates..."
- case available = "A new version is available!"
- case downloading = "Downloading update..."
- case extracting = "Extracting update..."
- case install = "Ready to Install"
- case checkFailed = "Failed to Check for Updates"
+ case check = "Check for updates..."
+ case latest = "You're up-to-date!"
+ case checking = "Checking for udpates..."
+ case available = "A new version is available!"
+ case downloading = "Downloading update..."
+ case extracting = "Extracting update..."
+ case install = "Ready to Install"
+ case checkFailed = "Failed to Check for Updates"
case installFailed = "Failed to Install Update"
}
@@ -30,9 +16,9 @@ class UpdateViewController: NSViewController, UpdateManagerDelegate {
private weak var updaterDelegate: UpdateManagerDelegate?
private var appIconImage: NSImageView = {
- //let image = NSImageView(image: NSApp.applicationIconImage)
let image = NSImageView()
- image.image = NSWorkspace.shared.icon(forFile: Bundle.main.bundlePath)
+ image.image = NSWorkspace.shared
+ .icon(forFile: Bundle.main.bundlePath)
image.imageScaling = .scaleAxesIndependently
image.translatesAutoresizingMaskIntoConstraints = false
return image
@@ -45,7 +31,9 @@ class UpdateViewController: NSViewController, UpdateManagerDelegate {
textField.drawsBackground = false
textField.alignment = .left
textField.textColor = NSColor(name: nil) { getColors(.black, .white, for: $0) }
- textField.font = NSFont.systemFont(ofSize: NSFontDescriptor.preferredFontDescriptor(forTextStyle: .body).pointSize, weight: .bold)
+ textField.font = NSFont.systemFont(ofSize: NSFontDescriptor
+ .preferredFontDescriptor(forTextStyle: .body).pointSize,
+ weight: .bold)
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
@@ -59,18 +47,23 @@ class UpdateViewController: NSViewController, UpdateManagerDelegate {
textField.drawsBackground = false
textField.alignment = .left
textField.textColor = .gray
- textField.font = NSFont.systemFont(ofSize: NSFontDescriptor.preferredFontDescriptor(forTextStyle: .body).pointSize, weight: .bold)
+ textField.font = NSFont.systemFont(ofSize: NSFontDescriptor
+ .preferredFontDescriptor(forTextStyle: .body).pointSize,
+ weight: .bold)
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
- private var changelogLabel: NSScrollView = { // TODO: Improve some more. Maybe make it scrollable.
+ // TODO: Improve some more. Maybe make it scrollable.
+ private var changelogLabel: NSScrollView = {
let scrollableTextView = NSTextView.scrollableTextView()
scrollableTextView.isHidden = true
(scrollableTextView.documentView as? NSTextView)?.isEditable = false
-// (scrollableTextView.documentView as? NSTextView)?.drawsBackground = false
(scrollableTextView.documentView as? NSTextView)?.textColor = .gray
- (scrollableTextView.documentView as? NSTextView)?.font = NSFont.systemFont(ofSize: NSFontDescriptor.preferredFontDescriptor(forTextStyle: .body).pointSize, weight: .regular)
+ (scrollableTextView.documentView as? NSTextView)?.font =
+ NSFont.systemFont(ofSize: NSFontDescriptor
+ .preferredFontDescriptor(forTextStyle: .body).pointSize,
+ weight: .regular)
scrollableTextView.translatesAutoresizingMaskIntoConstraints = false
return scrollableTextView
}()
@@ -139,26 +132,46 @@ class UpdateViewController: NSViewController, UpdateManagerDelegate {
NSLayoutConstraint.activate([
appIconImage.widthAnchor.constraint(equalToConstant: 70),
- appIconImage.heightAnchor.constraint(equalTo: appIconImage.widthAnchor, multiplier: 1),
+ appIconImage.heightAnchor
+ .constraint(equalTo: appIconImage.widthAnchor,
+ multiplier: 1),
+ appIconImage.topAnchor.constraint(equalTo: view.topAnchor,
+ constant: ViewConstants.spacing10),
+ appIconImage.leadingAnchor
+ .constraint(equalTo: view.leadingAnchor,
+ constant: ViewConstants.spacing10),
- appIconImage.topAnchor.constraint(equalTo: view.topAnchor, constant: ViewConstants.spacing10),
- appIconImage.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: ViewConstants.spacing10),
+ statusLabel.topAnchor
+ .constraint(equalTo: appIconImage.topAnchor,
+ constant: ViewConstants.spacing10),
+ statusLabel.leadingAnchor
+ .constraint(equalTo: appIconImage.trailingAnchor,
+ constant: ViewConstants.spacing10),
- statusLabel.topAnchor.constraint(equalTo: appIconImage.topAnchor, constant: ViewConstants.spacing2),
- statusLabel.leadingAnchor.constraint(equalTo: appIconImage.trailingAnchor, constant: ViewConstants.spacing10),
+ subStatusLabel.topAnchor
+ .constraint(equalTo: statusLabel.bottomAnchor,
+ constant: ViewConstants.spacing10),
+ subStatusLabel.leadingAnchor
+ .constraint(equalTo: statusLabel.leadingAnchor),
- subStatusLabel.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: ViewConstants.spacing10),
- subStatusLabel.leadingAnchor.constraint(equalTo: statusLabel.leadingAnchor),
-
- changelogLabel.widthAnchor.constraint(equalTo: stackView.widthAnchor),
+ changelogLabel.widthAnchor
+ .constraint(equalTo: stackView.widthAnchor),
changelogLabel.heightAnchor.constraint(equalToConstant: 150),
- stackView.topAnchor.constraint(equalTo: subStatusLabel.bottomAnchor, constant: ViewConstants.spacing2),
- stackView.leadingAnchor.constraint(equalTo: statusLabel.leadingAnchor),
- view.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: ViewConstants.spacing20),
- view.bottomAnchor.constraint(equalTo: stackView.bottomAnchor, constant: ViewConstants.spacing20),
+ stackView.topAnchor
+ .constraint(equalTo: subStatusLabel.bottomAnchor,
+ constant: ViewConstants.spacing2),
+ stackView.leadingAnchor
+ .constraint(equalTo: statusLabel.leadingAnchor),
+ view.trailingAnchor
+ .constraint(equalTo: stackView.trailingAnchor,
+ constant: ViewConstants.spacing20),
+ view.bottomAnchor
+ .constraint(equalTo: stackView.bottomAnchor,
+ constant: ViewConstants.spacing20),
- buttonsStackView.heightAnchor.constraint(equalTo: updateButton.heightAnchor),
+ buttonsStackView.heightAnchor
+ .constraint(equalTo: updateButton.heightAnchor),
])
}
@@ -192,36 +205,44 @@ class UpdateViewController: NSViewController, UpdateManagerDelegate {
case .check:
break
case .latest:
- self?.statusLabel.stringValue = UpdateStatus.latest.rawValue
+ self?.statusLabel.stringValue = UpdateStatus.latest
+ .rawValue
break
case .checking:
- self?.statusLabel.stringValue = UpdateStatus.checking.rawValue
+ self?.statusLabel.stringValue = UpdateStatus.checking
+ .rawValue
self?.updateButton.keyEquivalent = ""
self?.updateButton.isEnabled = false
case .available:
self?.updateButton.title = "Download"
self?.updateButton.keyEquivalent = ""
- self?.statusLabel.stringValue = UpdateStatus.available.rawValue
+ self?.statusLabel.stringValue = UpdateStatus.available
+ .rawValue
self?.updateButton.action = #selector(self!.downloadUpdate)
case .downloading:
self?.updateButton.isEnabled = false
self?.updateButton.title = "Install"
self?.progressIndicator.isHidden = false
- self?.statusLabel.stringValue = UpdateStatus.downloading.rawValue
+ self?.statusLabel.stringValue = UpdateStatus.downloading
+ .rawValue
case .extracting:
self?.updateButton.isEnabled = false
self?.updateButton.title = "Install"
self?.progressIndicator.isHidden = false
- self?.statusLabel.stringValue = UpdateStatus.extracting.rawValue
+ self?.statusLabel.stringValue = UpdateStatus.extracting
+ .rawValue
case .install:
self?.updateButton.title = "Install"
self?.progressIndicator.isHidden = false
- self?.statusLabel.stringValue = UpdateStatus.install.rawValue
+ self?.statusLabel.stringValue = UpdateStatus.install
+ .rawValue
self?.updateButton.action = #selector(self!.installUpdate)
case .checkFailed:
- self?.statusLabel.stringValue = UpdateStatus.checkFailed.rawValue
+ self?.statusLabel.stringValue = UpdateStatus.checkFailed
+ .rawValue
case .installFailed:
- self?.statusLabel.stringValue = UpdateStatus.installFailed.rawValue
+ self?.statusLabel.stringValue = UpdateStatus.installFailed
+ .rawValue
self?.updateButton.action = #selector(self!.checkForUpdate)
}
}
@@ -241,8 +262,13 @@ class UpdateViewController: NSViewController, UpdateManagerDelegate {
self?.subStatusLabel.isHidden = false
self?.changelogLabel.isHidden = false
for (i, change) in model.changes.enumerated() {
- (self?.changelogLabel.documentView as? NSTextView)?.string += "\u{2022} \(change)"
- if i < model.changes.count-1 { (self?.changelogLabel.documentView as? NSTextView)?.string += "\n" }
+ (self?.changelogLabel.documentView as?
+ NSTextView)?.string +=
+ "\u{2022} \(change)"
+ if i < model.changes.count-1 {
+ (self?.changelogLabel.documentView as?
+ NSTextView)?.string += "\n"
+ }
}
}
}
diff --git a/src/updater/Makefile b/src/updater/Makefile
index db71a7a..804f3bf 100644
--- a/src/updater/Makefile
+++ b/src/updater/Makefile
@@ -20,7 +20,8 @@ FRAMEWORKS = -framework AppKit
$(EXEC): ./arm64/$(EXEC) ./x86_64/$(EXEC)
lipo -create -output $(EXEC) $^ && \
- codesign -s ${DEVELOPER_ID} -f --timestamp -o runtime $(EXEC)
+ codesign -s ${APPLE_DEVELOPER_ID_APPLICATION} -f --timestamp \
+ -o runtime $(EXEC)
all: $(EXEC)