Skip to content

Commit

Permalink
Merge pull request #22 from zenangst/various/improvements
Browse files Browse the repository at this point in the history
Various improvements
  • Loading branch information
zenangst authored Oct 3, 2018
2 parents cfec283 + adecc25 commit b8906f9
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 61 deletions.
2 changes: 1 addition & 1 deletion Resources/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.2.1</string>
<string>0.3.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
Expand Down
12 changes: 9 additions & 3 deletions Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, VersionControllerDelegate {
self.window = nil

let contentViewController = ApplicationsViewController()
let windowSize = CGSize(width: 768, height: 640)
let window = NSWindow(contentViewController: contentViewController)
window.setFrameAutosaveName(NSWindow.FrameAutosaveName.init("MainApplicationWindow"))
window.styleMask = [.closable, .miniaturizable, .resizable, .titled]
window.styleMask = [.closable, .miniaturizable, .resizable, .titled,
.fullSizeContentView, .unifiedTitleAndToolbar]
window.titleVisibility = .hidden
window.toolbar = NSToolbar()
if window.frame.size.width == 0 {
window.setFrame(NSRect.init(origin: .zero, size: .init(width: 200, height: 200)),
display: false)
Expand All @@ -29,10 +33,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, VersionControllerDelegate {
if let screen = NSScreen.main, window.frame.origin == .zero {
let origin = NSPoint(x: screen.frame.width / 2 - window.frame.size.width / 2,
y: screen.frame.height / 2 - window.frame.size.height / 2)
window.setFrameOrigin(origin)
window.setFrame(NSRect.init(origin: origin, size: windowSize),
display: true)
}

window.minSize = .init(width: 320, height: 320)
window.minSize = windowSize
window.maxSize = windowSize
window.makeKeyAndOrderFront(nil)
self.window = window
}
Expand Down
46 changes: 24 additions & 22 deletions Sources/Applications/Logic/ApplicationsLogicController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,32 @@ class ApplicationsLogicController {
func toggleAppearance(for application: Application,
newAppearance appearance: Application.Appearance,
then handler: @escaping (ApplicationsViewController.State) -> Void) {
DispatchQueue.global(qos: .utility).async {
DispatchQueue.global(qos: .utility).async { [weak self] in
let shell = Shell()
let newSetting = appearance == .light ? "YES" : "NO"
do {
let shell = Shell()
let applicationIsRunning = !NSRunningApplication.runningApplications(withBundleIdentifier: application.bundleIdentifier).isEmpty
if applicationIsRunning && !application.url.path.contains("CoreServices") {
do {
let script = """
tell application "\(application.name)" to quit
"""
NSAppleScript(source: script)?.executeAndReturnError(nil)
}
}
let applicationIsRunning = !NSRunningApplication.runningApplications(withBundleIdentifier: application.bundleIdentifier).isEmpty
if applicationIsRunning && !application.url.path.contains("CoreServices") {
let script = """
tell application "\(application.name)" to quit
"""
NSAppleScript(source: script)?.executeAndReturnError(nil)
}

try shell.execute(command: "defaults write \(application.bundleIdentifier) NSRequiresAquaSystemAppearance -bool \(newSetting)")
shell.execute(command: """
/usr/bin/killall -u $USER cfprefsd &&
/usr/libexec/PlistBuddy -c \"Set :NSRequiresAquaSystemAppearance \(newSetting)\" \(application.preferencesUrl.path) &&
defaults write \(application.bundleIdentifier) NSRequiresAquaSystemAppearance -bool \(newSetting)
""")

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
if applicationIsRunning && !application.url.path.contains("CoreServices") {
NSWorkspace.shared.launchApplication(application.name)
} else {
try shell.execute(command: "killall", arguments: ["-9", "\(application.name)"])
let shell = Shell()
shell.execute(command: "killall", arguments: ["-9", "\(application.name)"])
}

DispatchQueue.main.async { [weak self] in
self?.load(then: handler)
}
} catch {}
self?.load(then: handler)
})
}
}

Expand All @@ -62,7 +62,6 @@ class ApplicationsLogicController {
in: .userDomainMask,
appropriateFor: nil,
create: false)

for url in appUrls {
let path = url.path
let infoPath = "\(path)/Contents/Info.plist"
Expand Down Expand Up @@ -100,8 +99,11 @@ class ApplicationsLogicController {
fileprivate extension NSDictionary {
func appearance() -> Application.Appearance {
let key = ApplicationsLogicController.PlistKey.requiresAquaSystemAppearance.rawValue
let result = (value(forKey: key) as? Bool) ?? false
return result ? .light : .dark
if let result = (value(forKey: key) as? Bool) {
return result ? .light : .dark
} else {
return .system
}
}

func value(forPlistKey plistKey: ApplicationsLogicController.PlistKey) -> String? {
Expand Down
1 change: 1 addition & 0 deletions Sources/Applications/Models/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ struct Application: Hashable {
enum Appearance: String, Hashable, CaseIterable {
case light = "Light"
case dark = "Dark"
case system = "System"
}

let bundleIdentifier: String
Expand Down
20 changes: 16 additions & 4 deletions Sources/Applications/Views/ApplicationGridView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class ApplicationGridView: NSCollectionViewItem {
super.viewDidLoad()

view.layer?.backgroundColor = NSColor.white.cgColor
view.layer?.borderColor = NSColor.gray.withAlphaComponent(0.25).cgColor
view.layer?.borderWidth = 1.5
view.layer?.cornerRadius = 28
view.layer?.masksToBounds = true

Expand Down Expand Up @@ -66,12 +68,17 @@ class ApplicationGridView: NSCollectionViewItem {
view.animator().layer?.backgroundColor = .black
titleLabel.animator().textColor = .white
subtitleLabel.animator().textColor = .lightGray
subtitleLabel.animator().stringValue = "Dark mode"
subtitleLabel.animator().stringValue = "Dark apperance"
case .system:
view.animator().layer?.backgroundColor = NSColor.gray.cgColor
titleLabel.animator().textColor = .white
subtitleLabel.animator().textColor = .lightGray
subtitleLabel.animator().stringValue = "System apperance"
case .light:
view.animator().layer?.backgroundColor = .white
titleLabel.animator().textColor = .black
subtitleLabel.animator().textColor = .darkGray
subtitleLabel.animator().stringValue = "Light mode"
subtitleLabel.animator().stringValue = "Light apperance"
}
}, completionHandler:{
handler?()
Expand All @@ -82,12 +89,17 @@ class ApplicationGridView: NSCollectionViewItem {
view.layer?.backgroundColor = .black
titleLabel.animator().textColor = .white
subtitleLabel.textColor = .lightGray
subtitleLabel.stringValue = "Dark mode"
subtitleLabel.stringValue = "Dark apperance"
case .system:
view.layer?.backgroundColor = NSColor.gray.cgColor
titleLabel.animator().textColor = .white
subtitleLabel.textColor = .lightGray
subtitleLabel.stringValue = "System apperance"
case .light:
view.layer?.backgroundColor = .white
titleLabel.textColor = .black
subtitleLabel.textColor = .darkGray
subtitleLabel.stringValue = "Light mode"
subtitleLabel.stringValue = "Light apperance"
}
}
}
Expand Down
45 changes: 14 additions & 31 deletions Sources/Utilities/Shell.swift
Original file line number Diff line number Diff line change
@@ -1,46 +1,29 @@
import Foundation

class Shell {
let queue = DispatchQueue(label: "shell-execution")

@discardableResult func execute(command: String,
arguments: [String] = [],
at path: String = ".") throws -> String {
at path: String = ".") -> String {
let process = Process()
let path = path.replacingOccurrences(of: " ", with: "\\ ")
let arguments = arguments.joined(separator: " ")
let command = "cd \(path) && \(command) \(arguments)"

return try launch(process, command: command)
let command = "cd \(path) && \(command) \(arguments) &"
return process.shell(command: command)
}
}

private func launch(_ process: Process,
command: String,
withShell: String = "/bin/bash") throws -> String {
let pipe = Pipe()
var output = Data()

pipe.fileHandleForReading.readabilityHandler = { [weak self] handler in
guard let strongSelf = self else { return }
strongSelf.queue.async {
let data = handler.availableData
output.append(data)
}
}

process.launchPath = withShell
process.arguments = ["-c", command]
process.standardOutput = pipe
process.launch()
process.waitUntilExit()
extension Process {
public func shell(command: String) -> String {
let pipe = Pipe()

return queue.sync {
if let output = String(data: output, encoding: .utf8), output.hasSuffix("\n") {
let endIndex = output.index(before: output.endIndex)
return String(output[..<endIndex])
}
launchPath = "/bin/bash"
arguments = ["-c", command]
standardOutput = pipe

return ""
}
launch()
waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
return String(data: data, encoding: String.Encoding.utf8) ?? ""
}
}

0 comments on commit b8906f9

Please sign in to comment.