diff --git a/src/AppDelegate.swift b/src/AppDelegate.swift index 0fe73e2..acfd2f0 100644 --- a/src/AppDelegate.swift +++ b/src/AppDelegate.swift @@ -16,7 +16,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { window.delegate = self // NOTE: Here we check wether the program was launched by the - // system. If it was not, then display the window. + // system (e.g. launch-at-login). If it was not, then display + // the window. if let event = NSAppleEventManager.shared().currentAppleEvent, !(event.eventID == kAEOpenApplication && event.paramDescriptor(forKeyword: keyAEPropData)? diff --git a/src/Makefile b/src/Makefile index e589933..9a49a02 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,8 +12,8 @@ SRCMODULES = Helpers.swift EditableNSTextField.swift EventMonitor.swift \ SettingsViewController.swift HotKeyManager.swift \ KeyDetectorButton.swift PathManager.swift \ PathsTableCellView.swift ProgramsTable.swift ShadowView.swift \ - DirMonitor.swift MenulessWindow.swift AboutViewController.swift \ - AppDelegate.swift main.swift + DirMonitor.swift MenulessWindow.swift \ + AboutViewController.swift AppDelegate.swift main.swift ARMOBJMODULES = $(addprefix ./arm64/,$(SRCMODULES:.swift=.o)) X86OBJMODULES = $(addprefix ./x86_64/,$(SRCMODULES:.swift=.o)) @@ -71,6 +71,7 @@ ifdef UNIVERSAL ./x86_64/main.o $(filter-out ./x86_64/main.o, $(X86OBJMODULES)) -o $@ endif +# TODO: The universal build doesn't seem to compile x86_64. ifdef UNIVERSAL $(EXEC): ./arm64/$(EXEC) ./x86_64/$(EXEC) @lipo -create -output $(EXEC) $^ diff --git a/src/SearchViewController.swift b/src/SearchViewController.swift index 5fe94fc..b415b2e 100644 --- a/src/SearchViewController.swift +++ b/src/SearchViewController.swift @@ -1,9 +1,11 @@ import AppKit import Carbon -// NOTE: This is the corner radius of the backgrounView view that acts as a window frame and an NSViewController's view that clips all elements inside of it. +// NOTE: This is the corner radius of the backgrounView view that acts as +// a window frame. fileprivate let windowCornerRadius = 15.0 +// NOTE: This is the maximum number of elements shown when searching. fileprivate let maxItems = 20 class SearchViewController: NSViewController, NSTextFieldDelegate, @@ -205,10 +207,10 @@ class SearchViewController: NSViewController, NSTextFieldDelegate, override func viewDidLoad() { super.viewDidLoad() - // NOTE: This needs removeObserver on deinit? Well, technically we - // don't care because this view controller will exist - // throughout the whole life of the program. When the - // program gets killed, the OS will clear this. + // NOTE: This needs removeObserver on deinit. However, technically + // it doesn't matter because if this view controller doesn't + // exists, then the whole program is pointless. So, let the OS + // clean it up when the program is killed. DistributedNotificationCenter.default .addObserver(self, selector: #selector(osThemeChanged(sender:)), name: NSNotification @@ -237,7 +239,7 @@ class SearchViewController: NSViewController, NSTextFieldDelegate, if let controller = self { if modsContains(keys: OSCtrl, in: modifiers) && key == kVK_ANSI_P || - modsContainsNone(in: modifiers) && key == kVK_UpArrow + modsContainsNone(in: modifiers) && key == kVK_UpArrow { controller.programsTableViewSelection -= 1 } else if modsContains(keys: OSCtrl, in: modifiers) && @@ -318,7 +320,7 @@ class SearchViewController: NSViewController, NSTextFieldDelegate, centerWindow() view.window?.makeFirstResponder(searchInput) - // searchInput should select all text whenever window appears. + // searchInput select all text whenever window appears. NSApp.sendAction(#selector(NSResponder.selectAll(_:)), to: nil, from: self) } @@ -402,14 +404,12 @@ class SearchViewController: NSViewController, NSTextFieldDelegate, programsList[listIndex].path = prog.path programsList[listIndex].name = prog.name programsList[listIndex].ext = prog.ext - programsList[listIndex].img = - NSWorkspace.shared - .icon(forFile: URL( - fileURLWithPath: prog.path - ) - .appendingPathComponent( - prog.name+prog.ext).path - ) + programsList[listIndex].img = NSWorkspace.shared + .icon(forFile: URL( + fileURLWithPath: prog.path + ).appendingPathComponent( + prog.name+prog.ext).path + ) listIndex += 1 } } diff --git a/src/SettingsViewController.swift b/src/SettingsViewController.swift index 15e0176..d7e4c89 100644 --- a/src/SettingsViewController.swift +++ b/src/SettingsViewController.swift @@ -16,18 +16,7 @@ class SettingsViewController: NSViewController, private var paths: [String] = [] - // PERF: This is very slow to initialize because it creates a new - // process. This also cannot be done on a separate thread. This - // sucks because the program now takes considerably longer to - // launch. - private let dirPicker: NSOpenPanel = { - let panel = NSOpenPanel() - panel.message = "Select a directory to search applications in . . ." - panel.canChooseDirectories = true - panel.canChooseFiles = false - panel.allowsMultipleSelection = false - return panel - }() + private var dirPicker: NSOpenPanel? private var shortcutsLabel: NSTextField = { let textField = NSTextField(labelWithString: "Shortcut") @@ -528,8 +517,7 @@ class SettingsViewController: NSViewController, pathsTableView.scrollRowToVisible(row) pathsTableView.selectRowIndexes(IndexSet(integer: row), byExtendingSelection: false) - ( - pathsTableView + (pathsTableView .view(atColumn: 0, row: row, makeIfNecessary: false ) as? PathsTableCellView)?.startEditing() break @@ -586,6 +574,15 @@ class SettingsViewController: NSViewController, } func titleFieldTextChanged(tag: Int, text: String) { + if let cell = pathsTableView.view(atColumn: 0, row: tag, + makeIfNecessary: false) as? PathsTableCellView + { + if isDirectory(text) { + cell.titleField.textColor = NSColor.green + } else { + cell.titleField.textColor = NSColor.red + } + } } func keyWasSet(to keyCode: Int) { @@ -593,12 +590,27 @@ class SettingsViewController: NSViewController, } func selectionButtonClicked(tag: Int) { + if dirPicker == nil { + dirPicker = NSOpenPanel() + dirPicker!.message = "Select a directory to search applications in..." + dirPicker!.canChooseDirectories = true + dirPicker!.canChooseFiles = false + dirPicker!.allowsMultipleSelection = false + } + + // WARN: + // FIX: THere is a bug where the program crashes when adding a new + // path. This happens because the settings popup is closed before + // displaying the selection modal, as a result the new path item + // is cleared (well, b/c it's empty) and the path gets set into + // non-existent memory which results in segmentation fault. + NSRunningApplication.current.activate(options: .activateAllWindows) delegate.window.level = .normal delegate.aboutWindow.performClose(nil) - if dirPicker.runModal() == .OK { - if let url = dirPicker.url { + if dirPicker!.runModal() == .OK { + if let url = dirPicker!.url { paths[tag] = url.path pathsTableView.reloadData() } diff --git a/src/resources/AppIcon.icns b/src/resources/AppIcon.icns index 9b71d18..6785141 100644 Binary files a/src/resources/AppIcon.icns and b/src/resources/AppIcon.icns differ