first commit

This commit is contained in:
David Wernhart
2020-02-16 03:28:55 +01:00
commit 906cec6cc5
80 changed files with 3984 additions and 0 deletions

BIN
AlDente/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.files.user-selected.read-only</key>
<false/>
</dict>
</plist>

64
AlDente/AppDelegate.swift Normal file
View File

@@ -0,0 +1,64 @@
//
// AppDelegate.swift
// AlDente
//
// Created by David Wernhart on 09.02.20.
// Copyright © 2020 David Wernhart. All rights reserved.
//
import Cocoa
import SwiftUI
import ServiceManagement
import Foundation
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
//var window: NSWindow!
var statusBarItem: NSStatusItem!
var popover: NSPopover!
func applicationDidFinishLaunching(_ aNotification: Notification) {
let contentView = ContentView()
// Create the popover
let popover = NSPopover()
popover.contentSize = NSSize(width: 400, height: 600)
popover.behavior = .transient
popover.contentViewController = NSHostingController(rootView: contentView)
self.popover = popover
let statusBar = NSStatusBar.system
statusBarItem = statusBar.statusItem(
withLength: NSStatusItem.squareLength)
statusBarItem.button?.title = "🍝"
if let button = self.statusBarItem.button {
button.action = #selector(togglePopover(_:))
}
Helper.instance.checkHelperVersion()
}
@objc func togglePopover(_ sender: AnyObject?) {
self.popover.contentViewController?.view.window?.becomeKey()
if let button = self.statusBarItem.button {
if self.popover.isShown {
self.popover.performClose(sender)
} else {
self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
}
}
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
}

BIN
AlDente/Assets.xcassets/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,61 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "spaghetti-2.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "spaghetti-1.png",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "spaghetti.png",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,56 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "1.000",
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.800",
"alpha" : "1.000",
"blue" : "0.800",
"green" : "0.800"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.100",
"alpha" : "1.000",
"blue" : "0.100",
"green" : "0.100"
}
}
}
]
}

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="AlDente" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="AlDente" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About AlDente" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide AlDente" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit AlDente" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Format" id="jxT-CU-nIS">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="AlDente" customModuleProvider="target"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="0.0"/>
</scene>
</scenes>
</document>

213
AlDente/ContentView.swift Normal file
View File

@@ -0,0 +1,213 @@
//
// ContentView.swift
// AlDente
//
// Created by David Wernhart on 09.02.20.
// Copyright © 2020 David Wernhart. All rights reserved.
//
import SwiftUI
import ServiceManagement
import Foundation
import LaunchAtLogin
import Combine
struct BlueButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? Color.blue : Color.white)
.background(configuration.isPressed ? Color.white : Color.blue)
.cornerRadius(6.0)
.padding()
}
}
struct RedButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? Color.red : Color.white)
.background(configuration.isPressed ? Color.white : Color.red)
.cornerRadius(6.0)
.padding()
}
}
struct settings<Content: View>: View {
var content: () -> Content
@State var launchOnLogin = LaunchAtLogin.isEnabled
init(@ViewBuilder _ content: @escaping () -> Content) {
self.content = content
//Helper.instance.delegate = self
}
var body: some View {
VStack(alignment: .center){
HStack(alignment: .center) {
Toggle(isOn: Binding(
get: {
self.launchOnLogin
},
set: {(newValue) in
self.launchOnLogin = newValue
if(newValue){
print("launch on login turned on!")
LaunchAtLogin.isEnabled = true
}
else{
print("launch on login turned off!")
LaunchAtLogin.isEnabled = false
}
}
)) {
Text("Launch on Login")
}.padding()
Spacer()
Button( action: {
Helper.instance.installHelper()
}
) {
Text("Reinstall Helper")
.frame(maxWidth: 120, maxHeight: 30)
}.buttonStyle(BlueButtonStyle())
}
HStack(alignment: .center) {
Spacer()
VStack(alignment: .leading){
Text("AlDente 🍝").font(.subheadline)
Text("github.com/davidwernhart/AlDente").foregroundColor(Color.blue)
Text("Created with 🤍 by David Wernhart in 2020")
// Text("AlDente 🍝").font(.title)
// Text("Keep your battery just right").font(.subheadline)
}
Spacer()
Button(action: {
let url = URL(string: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6PLR7D9ZCZGGC&source=url")!
if NSWorkspace.shared.open(url) {
print("default browser was successfully opened")
}
}) {
Text("Donate")
.frame(maxWidth: 60, maxHeight: 50)
}
.buttonStyle(BlueButtonStyle())
}
}.background(Color("SettingsColor")).cornerRadius(5)
}
}
struct ContentView: View{
@State var adaptableHeight = CGFloat(100)
@State var showSettings = false
@ObservedObject var presenter = SMCPresenter()
init() {
Helper.instance.delegate = presenter
Helper.instance.readMaxBatteryCharge()
}
var body: some View {
let vstack = VStack{
VStack(alignment: .leading) {
//Text("Value is: \(presenter.value)")
HStack(alignment: .center){
Text(" Max. Battery Charge:").padding(.leading)
TextField("Number", value: Binding(
get: {
Float(self.presenter.value)
},
set: {(newValue) in
if(newValue >= 20 && newValue <= 100){
self.presenter.setValue(value: newValue)
}
}
), formatter: NumberFormatter())
.multilineTextAlignment(.center)
.frame(maxWidth:50)
.textFieldStyle(RoundedBorderTextFieldStyle())
Spacer()
Button( action: {
self.showSettings = !self.showSettings
if(self.showSettings){
self.adaptableHeight = 235
}
else{
self.adaptableHeight = 100
}
}) {
Text("Settings")
.frame(maxWidth: 70, maxHeight: 30)
}.buttonStyle(BlueButtonStyle()).padding(.leading,-30)
Button( action: {
NSApplication.shared.terminate(self)
}) {
Text("Exit")
.frame(maxWidth: 50, maxHeight: 30)
}.buttonStyle(RedButtonStyle()).padding(.leading,-30)
}
HStack(alignment: .center){
Slider(value: Binding(
get: {
Float(self.presenter.value)
},
set: {(newValue) in
if(newValue >= 20 && newValue <= 100){
self.presenter.setValue(value: newValue)
}
}
), in: 20...100).padding(.horizontal).padding(.top,-20)
}
Spacer()
if(self.showSettings){
settings{Text("")}
}
}.frame(width: 400, height: adaptableHeight)
}
return vstack
}
}
class SMCPresenter: ObservableObject, HelperDelegate{
@Published var value: UInt8 = 0
private var timer: Timer?
func OnMaxBatRead(value: UInt8){
DispatchQueue.main.async {
self.value = value
}
}
func setValue(value: Float){
DispatchQueue.main.async {
self.value = UInt8(value)
}
self.timer?.invalidate()
self.timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false, block: { timer in
print("Setting Max Battery To: ",value)
Helper.instance.writeMaxBatteryCharge(setVal: UInt8(value))
Helper.instance.readMaxBatteryCharge()
self.timer = nil
})
}
}

124
AlDente/Helper.swift Normal file
View File

@@ -0,0 +1,124 @@
//
// Helper.swift
// AlDente
//
// Created by David Wernhart on 14.02.20.
// Copyright © 2020 David Wernhart. All rights reserved.
//
import Cocoa
import SwiftUI
import ServiceManagement
import Foundation
protocol HelperDelegate {
func OnMaxBatRead(value: UInt8)
}
class Helper{
static let instance = Helper()
public var delegate: HelperDelegate?
// var receiveMessage = "" {
// didSet {
// DispatchQueue.main.async {
// print(self.receiveMessage)
// // if self.receiveMessage.isEmpty {
// // self.clearButton.isEnabled = false
// // } else {
// // self.clearButton.isEnabled = true
// // }
// }
// }
// }
lazy var helperToolConnection: NSXPCConnection = {
let connection = NSXPCConnection(machServiceName: "com.davidwernhart.Helper.mach", options: .privileged)
connection.remoteObjectInterface = NSXPCInterface(with: HelperToolProtocol.self)
connection.resume()
return connection
}()
@objc func installHelper() {
print("trying to install helper!")
var status: OSStatus = noErr
let helperID = "com.davidwernhart.Helper" as CFString//Prefs.helperID as CFString
var authItem = AuthorizationItem(name: kSMRightBlessPrivilegedHelper, valueLength: 0, value: nil, flags: 0)
var authRights = AuthorizationRights(count: 1, items: &authItem)
let authFlags: AuthorizationFlags = [.interactionAllowed, .preAuthorize, .extendRights]
var authRef: AuthorizationRef? = nil
status = AuthorizationCreate(&authRights, nil, authFlags, &authRef)
if status != errAuthorizationSuccess {
print(SecCopyErrorMessageString(status,nil))
print("Error:", String(status))
}
var error: Unmanaged<CFError>? = nil
SMJobBless(kSMDomainSystemLaunchd, helperID, authRef, &error)
if let e = error?.takeRetainedValue() {
print("Domain:", CFErrorGetDomain(e))
print("Code:", CFErrorGetCode(e))
print("UserInfo:", CFErrorCopyUserInfo(e))
print("Description:", CFErrorCopyDescription(e))
print("Reason:", CFErrorCopyFailureReason(e))
print("Suggestion:", CFErrorCopyRecoverySuggestion(e))
}
}
@objc func writeMaxBatteryCharge(setVal: UInt8){
SMCWriteByte(key: "BCLM", value: setVal)
}
@objc func readMaxBatteryCharge(){
SMCReadByte(key:"BCLM",withReply: { (value) in
print(String(value))
self.delegate?.OnMaxBatRead(value: value)
})
}
@objc func checkHelperVersion() {
print("checking helper version")
if let helper = helperToolConnection.remoteObjectProxyWithErrorHandler({ (error) in
let e = error as NSError
print("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
self.installHelper()
//self.receiveMessage.append("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
}) as? HelperToolProtocol {
helper.getVersion(withReply: { (version) in
print("helperVersion:", helperVersion, " version from helper:",version)
if(!helperVersion.elementsEqual(version)){
self.installHelper()
}
//self.receiveMessage.append("Version: \(version)\n")
})
}
}
@objc func SMCReadByte(key:String, withReply reply: @escaping (UInt8) -> Void){
if let helper = helperToolConnection.remoteObjectProxyWithErrorHandler({ (error) in
let e = error as NSError
print("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
//self.receiveMessage.append("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
}) as? HelperToolProtocol {
helper.readSMCByte(key: key) { (value) in
reply (value)
}
}
}
@objc func SMCWriteByte(key:String,value:UInt8){
if let helper = helperToolConnection.remoteObjectProxyWithErrorHandler({ (error) in
let e = error as NSError
print("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
//self.receiveMessage.append("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
}) as? HelperToolProtocol {
helper.setSMCByte(key: key,value: value)
}
}
}

43
AlDente/Info.plist Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>
<false/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2020 David Wernhart. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticTermination</key>
<true/>
<key>NSSupportsSuddenTermination</key>
<true/>
<key>SMPrivilegedExecutables</key>
<dict>
<key>com.davidwernhart.Helper</key>
<string>identifier &quot;com.davidwernhart.Helper&quot; and anchor apple generic and certificate leaf[subject.CN] = &quot;Apple Development: david.wernhart96@gmail.com (GSDX9BQ584)&quot; and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}