Compare commits

...

No commits in common. "1.2" and "master" have entirely different histories.
1.2 ... master

81 changed files with 1244 additions and 1876 deletions

BIN
.DS_Store vendored

Binary file not shown.

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,38 @@
---
name: Bug Report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**MacBook (please complete the following information):**
- MacBook Model (https://support.apple.com/en-us/HT201608):
- macOS Version (https://support.apple.com/en-us/HT201260):
- Charger Model (Apple, Third Party, Wattage,...):
- Charging Cable (MagSafe 2, MagSafe 3, USB-C, Apple, Third Party,...):
- AlDente Pro or AlDente Free:
- AlDente Version:
- List or add screenshots of all enabled/disabled settings in AlDente:
- Please share a debug file the next time this happens so that we can assess this issue better. You can find a guide on How to generate and share a debug file on our blog(https://apphousekitchen.com/how-to-generate-and-share-a-debug-file/).
- External Monitor connected?
- MacBook used in Clamshell Mode (with the lid closed)?
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected Behavior**
A clear and concise description of what you expected to happen.
**Screenshots and Screen Recordings**
If applicable, add screenshots or screen recordings of the issue to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,10 @@
---
name: Question about AlDente
about: Use Discussions section for questions
title: ''
labels: ''
assignees: ''
---
Hi, if you have a question about AlDente, please use the Discussions section of Github: https://github.com/davidwernhart/AlDente/discussions

View File

@ -3,17 +3,16 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
505E96C92586211600DAA405 /* LaunchAtLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 505E96C82586211600DAA405 /* LaunchAtLogin */; };
9224A08723F1F70600961AC4 /* com.davidwernhart.Helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9283741823F1F34400B8AE7A /* com.davidwernhart.Helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
9240BF2C23FD34E2005A710B /* LaunchAtLogin.framework.dSYM in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9240BF2B23FD34E2005A710B /* LaunchAtLogin.framework.dSYM */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
9240BF2D23FD3547005A710B /* LaunchAtLogin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9286FB4823F84C2B00BEB15B /* LaunchAtLogin.framework */; };
9240BF2E23FD3547005A710B /* LaunchAtLogin.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9286FB4823F84C2B00BEB15B /* LaunchAtLogin.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
927DBFC923F5478E00F8BF0D /* HelperToolProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 927DBFC823F5478E00F8BF0D /* HelperToolProtocol.swift */; };
927DBFCA23F5478E00F8BF0D /* HelperToolProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 927DBFC823F5478E00F8BF0D /* HelperToolProtocol.swift */; };
9283741B23F1F34400B8AE7A /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9283741A23F1F34400B8AE7A /* main.swift */; };
928674C025D07BA300EC79C1 /* PersistanceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 928674BF25D07BA300EC79C1 /* PersistanceManager.swift */; };
92981EDB23F08D9B00C05424 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92981EDA23F08D9B00C05424 /* AppDelegate.swift */; };
92981EDD23F08D9B00C05424 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92981EDC23F08D9B00C05424 /* ContentView.swift */; };
92981EDF23F08D9C00C05424 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 92981EDE23F08D9C00C05424 /* Assets.xcassets */; };
@ -35,59 +34,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
9240BF2F23FD3547005A710B /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
9240BF2E23FD3547005A710B /* LaunchAtLogin.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
9258163B23F5CBD500AB7387 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
9283741623F1F34400B8AE7A /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = "";
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
9286FB4B23F84C2B00BEB15B /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 16;
files = (
9240BF2C23FD34E2005A710B /* LaunchAtLogin.framework.dSYM in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9240BF2923FD3257005A710B /* LaunchAtLogin.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = LaunchAtLogin.framework.dSYM; path = Carthage/Build/Mac/LaunchAtLogin.framework.dSYM; sourceTree = "<group>"; };
9240BF2B23FD34E2005A710B /* LaunchAtLogin.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = LaunchAtLogin.framework.dSYM; path = Carthage/Build/Mac/LaunchAtLogin.framework.dSYM; sourceTree = "<group>"; };
927DBFC623F533FB00F8BF0D /* Helper-Launchd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Helper-Launchd.plist"; sourceTree = "<group>"; };
927DBFC823F5478E00F8BF0D /* HelperToolProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelperToolProtocol.swift; sourceTree = "<group>"; };
927DBFCB23F54C2C00F8BF0D /* HelperTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelperTool.swift; sourceTree = "<group>"; };
9283741823F1F34400B8AE7A /* com.davidwernhart.Helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = com.davidwernhart.Helper; sourceTree = BUILT_PRODUCTS_DIR; };
9283741A23F1F34400B8AE7A /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
9283741F23F1F38100B8AE7A /* Helper-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Helper-Info.plist"; sourceTree = "<group>"; };
9286FB4823F84C2B00BEB15B /* LaunchAtLogin.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LaunchAtLogin.framework; path = Carthage/Build/Mac/LaunchAtLogin.framework; sourceTree = "<group>"; };
928674BF25D07BA300EC79C1 /* PersistanceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistanceManager.swift; sourceTree = "<group>"; };
92981ED723F08D9B00C05424 /* AlDente.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AlDente.app; sourceTree = BUILT_PRODUCTS_DIR; };
92981EDA23F08D9B00C05424 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
92981EDC23F08D9B00C05424 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
@ -95,38 +51,22 @@
92981EE123F08D9C00C05424 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
92981EE423F08D9C00C05424 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
92981EE623F08D9C00C05424 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
92981EE723F08D9C00C05424 /* AlDente.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AlDente.entitlements; sourceTree = "<group>"; };
92ACA12D23F5F861003512DC /* SMC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SMC.swift; sourceTree = "<group>"; };
92E24B4023F6DC0D00BE41ED /* Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helper.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
9283741523F1F34400B8AE7A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
92981ED423F08D9B00C05424 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9240BF2D23FD3547005A710B /* LaunchAtLogin.framework in Frameworks */,
505E96C92586211600DAA405 /* LaunchAtLogin in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9258163723F5CBD400AB7387 /* Frameworks */ = {
isa = PBXGroup;
children = (
9286FB4823F84C2B00BEB15B /* LaunchAtLogin.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
927DBFC723F545AF00F8BF0D /* Common */ = {
isa = PBXGroup;
children = (
@ -150,13 +90,10 @@
92981ECE23F08D9B00C05424 = {
isa = PBXGroup;
children = (
9240BF2923FD3257005A710B /* LaunchAtLogin.framework.dSYM */,
9240BF2B23FD34E2005A710B /* LaunchAtLogin.framework.dSYM */,
927DBFC723F545AF00F8BF0D /* Common */,
92981ED923F08D9B00C05424 /* AlDente */,
9283741923F1F34400B8AE7A /* com.davidwernhart.Helper */,
92981ED823F08D9B00C05424 /* Products */,
9258163723F5CBD400AB7387 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -178,8 +115,8 @@
92981EDE23F08D9C00C05424 /* Assets.xcassets */,
92981EE323F08D9C00C05424 /* Main.storyboard */,
92981EE623F08D9C00C05424 /* Info.plist */,
92981EE723F08D9C00C05424 /* AlDente.entitlements */,
92981EE023F08D9C00C05424 /* Preview Content */,
928674BF25D07BA300EC79C1 /* PersistanceManager.swift */,
);
path = AlDente;
sourceTree = "<group>";
@ -200,9 +137,6 @@
buildConfigurationList = 9283741C23F1F34400B8AE7A /* Build configuration list for PBXNativeTarget "com.davidwernhart.Helper" */;
buildPhases = (
9283741423F1F34400B8AE7A /* Sources */,
9283741523F1F34400B8AE7A /* Frameworks */,
9283741623F1F34400B8AE7A /* CopyFiles */,
9258163B23F5CBD500AB7387 /* Embed Frameworks */,
);
buildRules = (
);
@ -221,15 +155,16 @@
92981ED423F08D9B00C05424 /* Frameworks */,
92981ED523F08D9B00C05424 /* Resources */,
9224A08623F1F6E300961AC4 /* CopyFiles */,
9240BF2F23FD3547005A710B /* Embed Frameworks */,
9286FB4B23F84C2B00BEB15B /* Embed Frameworks */,
92E24B4423F847B500BE41ED /* ShellScript */,
92E24B4423F847B500BE41ED /* LaunchAtLogin */,
);
buildRules = (
);
dependencies = (
);
name = AlDente;
packageProductDependencies = (
505E96C82586211600DAA405 /* LaunchAtLogin */,
);
productName = AlDente;
productReference = 92981ED723F08D9B00C05424 /* AlDente.app */;
productType = "com.apple.product-type.application";
@ -241,7 +176,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1130;
LastUpgradeCheck = 1130;
LastUpgradeCheck = 1220;
ORGANIZATIONNAME = "David Wernhart";
TargetAttributes = {
9283741723F1F34400B8AE7A = {
@ -253,7 +188,7 @@
};
};
buildConfigurationList = 92981ED223F08D9B00C05424 /* Build configuration list for PBXProject "AlDente" */;
compatibilityVersion = "Xcode 9.3";
compatibilityVersion = "Xcode 12.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@ -261,6 +196,9 @@
Base,
);
mainGroup = 92981ECE23F08D9B00C05424;
packageReferences = (
505E96C72586211600DAA405 /* XCRemoteSwiftPackageReference "LaunchAtLogin" */,
);
productRefGroup = 92981ED823F08D9B00C05424 /* Products */;
projectDirPath = "";
projectRoot = "";
@ -285,7 +223,7 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
92E24B4423F847B500BE41ED /* ShellScript */ = {
92E24B4423F847B500BE41ED /* LaunchAtLogin */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -294,13 +232,14 @@
);
inputPaths = (
);
name = LaunchAtLogin;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "exec \"${PROJECT_DIR}/Carthage/Build/Mac/LaunchAtLogin.framework/Resources/copy-helper.sh\"\n";
shellScript = "\"${BUILT_PRODUCTS_DIR}/LaunchAtLogin_LaunchAtLogin.bundle/Contents/Resources/copy-helper-swiftpm.sh\"\n";
};
/* End PBXShellScriptBuildPhase section */
@ -320,6 +259,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
928674C025D07BA300EC79C1 /* PersistanceManager.swift in Sources */,
927DBFC923F5478E00F8BF0D /* HelperToolProtocol.swift in Sources */,
92981EDD23F08D9B00C05424 /* ContentView.swift in Sources */,
92981EDB23F08D9B00C05424 /* AppDelegate.swift in Sources */,
@ -344,15 +284,17 @@
9283741D23F1F34400B8AE7A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 2.0;
ARCHS = "$(ARCHS_STANDARD)";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 10;
DEVELOPMENT_TEAM = 56C2L92EKW;
ENABLE_HARDENED_RUNTIME = YES;
"FRAMEWORK_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/Frameworks";
EXCLUDED_ARCHS = "";
"EXCLUDED_ARCHS[sdk=*]" = "";
INFOPLIST_FILE = "com.davidwernhart.Helper/Helper-Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 2.0;
MACOSX_DEPLOYMENT_TARGET = 11.1;
MARKETING_VERSION = 4.3;
OTHER_LDFLAGS = (
"-sectcreate",
__TEXT,
@ -369,21 +311,22 @@
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Frameworks";
};
name = Debug;
};
9283741E23F1F34400B8AE7A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 2.0;
ARCHS = "$(ARCHS_STANDARD)";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 10;
DEVELOPMENT_TEAM = 56C2L92EKW;
ENABLE_HARDENED_RUNTIME = YES;
EXCLUDED_ARCHS = "";
INFOPLIST_FILE = "com.davidwernhart.Helper/Helper-Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 2.0;
MACOSX_DEPLOYMENT_TARGET = 11.1;
MARKETING_VERSION = 4.3;
OTHER_LDFLAGS = (
"-sectcreate",
__TEXT,
@ -400,7 +343,6 @@
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Frameworks";
};
name = Release;
};
@ -430,6 +372,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@ -441,7 +384,6 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -454,12 +396,11 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MACOSX_DEPLOYMENT_TARGET = 11.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SKIP_INSTALL = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
@ -491,6 +432,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@ -509,11 +451,10 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MACOSX_DEPLOYMENT_TARGET = 11.1;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
SKIP_INSTALL = NO;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
@ -523,30 +464,24 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AlDente/AlDente.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_ASSET_PATHS = "\"AlDente/Preview Content\"";
DEVELOPMENT_TEAM = 56C2L92EKW;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
INFOPLIST_FILE = AlDente/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.2;
MACOSX_DEPLOYMENT_TARGET = 11.1;
MARKETING_VERSION = "2.0 Alpha";
PRODUCT_BUNDLE_IDENTIFIER = com.davidwernhart.AlDente;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = NO;
SWIFT_VERSION = 5.0;
};
name = Debug;
@ -555,30 +490,24 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AlDente/AlDente.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_ASSET_PATHS = "\"AlDente/Preview Content\"";
DEVELOPMENT_TEAM = 56C2L92EKW;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
INFOPLIST_FILE = AlDente/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.2;
MACOSX_DEPLOYMENT_TARGET = 11.1;
MARKETING_VERSION = "2.0 Alpha";
PRODUCT_BUNDLE_IDENTIFIER = com.davidwernhart.AlDente;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = NO;
SWIFT_VERSION = 5.0;
};
name = Release;
@ -614,6 +543,25 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
505E96C72586211600DAA405 /* XCRemoteSwiftPackageReference "LaunchAtLogin" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sindresorhus/LaunchAtLogin";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 4.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
505E96C82586211600DAA405 /* LaunchAtLogin */ = {
isa = XCSwiftPackageProductDependency;
package = 505E96C72586211600DAA405 /* XCRemoteSwiftPackageReference "LaunchAtLogin" */;
productName = LaunchAtLogin;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 92981ECF23F08D9B00C05424 /* Project object */;
}

View File

@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "self:AlDente.xcodeproj">
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,16 @@
{
"object": {
"pins": [
{
"package": "LaunchAtLogin",
"repositoryURL": "https://github.com/sindresorhus/LaunchAtLogin",
"state": {
"branch": null,
"revision": "0f39982b9d6993eef253b81219d3c39ba1e680f3",
"version": "4.0.0"
}
}
]
},
"version": 1
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "0B65810B-47FA-44B5-B39C-4D764B29033A"
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "15EAC10E-2093-4C1F-817D-D17853B691FE"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AlDente/ContentView.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "37"
endingLineNumber = "37"
landmarkName = "Settings"
landmarkType = "14">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -4,10 +4,20 @@
<dict>
<key>SchemeUserState</key>
<dict>
<key>AlDente Pro.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>AlDente copy.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>AlDente.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>1</integer>
</dict>
<key>Hall.xcscheme_^#shared#^_</key>
<dict>
@ -22,7 +32,7 @@
<key>com.davidwernhart.Helper.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>0</integer>
</dict>
</dict>
</dict>

BIN
AlDente/.DS_Store vendored

Binary file not shown.

View File

@ -1,10 +0,0 @@
<?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>

View File

@ -6,18 +6,38 @@
// Copyright © 2020 David Wernhart. All rights reserved.
//
import Cocoa
import AppKit
import SwiftUI
import ServiceManagement
import Foundation
import LaunchAtLogin
import Foundation
import IOKit.ps
import IOKit.pwr_mgt
extension ProcessInfo {
/// Returns a `String` representing the machine hardware name or nil if there was an error invoking `uname(_:)` or decoding the response.
///
/// Return value is the equivalent to running `$ uname -m` in shell.
var machineHardwareName: String? {
var sysinfo = utsname()
let result = uname(&sysinfo)
guard result == EXIT_SUCCESS else { return nil }
let data = Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN))
guard let identifier = String(bytes: data, encoding: .ascii) else { return nil }
return identifier.trimmingCharacters(in: .controlCharacters)
}
}
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
final class AppDelegate: NSObject, NSApplicationDelegate {
//var window: NSWindow!
var statusBarItem: NSStatusItem!
var popover: NSPopover!
func applicationWillTerminate(_ aNotification: Notification) {
Helper.instance.enableSleep()
Helper.instance.enableCharging()
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
@ -29,39 +49,85 @@ class AppDelegate: NSObject, NSApplicationDelegate {
popover.behavior = .transient
popover.contentViewController = NSHostingController(rootView: contentView)
self.popover = popover
let statusBar = NSStatusBar.system
statusBarItem = statusBar.statusItem(
withLength: NSStatusItem.squareLength)
statusBarItem = statusBar.statusItem(withLength: NSStatusItem.squareLength)
statusBarItem.button?.image = NSImage(named: "menubaricon")!
//statusBarItem.button?.title = "🍝"
statusBarItem.button?.action = #selector(togglePopover(_:))
if let button = self.statusBarItem.button {
button.action = #selector(togglePopover(_:))
Helper.instance.setPlatformKey()
Helper.instance.checkHelperVersion{(foundHelper) in
if(foundHelper){
print("helper found!")
}
else{
Helper.instance.installHelper()
}
}
Helper.instance.checkHelperVersion()
LaunchAtLogin.isEnabled = true
SMCPresenter.shared.loadValue()
Helper.instance.checkCharging()
var actionMsg:String?
Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { timer in
if(Helper.instance.isInitialized){
Helper.instance.getChargingInfo { (Name, Capacity, IsCharging, MaxCapacity) in
if(!PersistanceManager.instance.oldKey){
if(Capacity < SMCPresenter.shared.value){
actionMsg = "NEED TO CHARGE"
if(Helper.instance.chargeInhibited){
Helper.instance.enableCharging()
}
Helper.instance.disableSleep()
}
else{
actionMsg = "IS PERFECT"
if(!Helper.instance.chargeInhibited){
Helper.instance.disableCharging()
}
Helper.instance.enableSleep()
}
print("TARGET: ",SMCPresenter.shared.value,
" CURRENT: ",String(Capacity),
" ISCHARGING: ",String(IsCharging),
" CHARGE INHIBITED: ",String(Helper.instance.chargeInhibited),
" ACTION: ",actionMsg!)
}
else{
print("BCLM MODE ENABLED")
}
}
DispatchQueue.main.async {
Helper.instance.setStatusString()
}
}
}
}
@objc func togglePopover(_ sender: AnyObject?) {
self.popover.contentViewController?.view.window?.becomeKey()
popover.contentViewController?.view.window?.becomeKey()
Helper.instance.setStatusString()
if let button = self.statusBarItem.button {
if self.popover.isShown {
self.popover.performClose(sender)
if popover.isShown {
popover.performClose(sender)
} else {
self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
popover.show(relativeTo: button.bounds, of: button, preferredEdge: .minY)
}
}
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
}

Binary file not shown.

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@ -1,56 +0,0 @@
{
"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

@ -6,13 +6,10 @@
// Copyright © 2020 David Wernhart. All rights reserved.
//
import SwiftUI
import ServiceManagement
import Foundation
import LaunchAtLogin
import Combine
import SwiftUI
struct BlueButtonStyle: ButtonStyle {
private struct BlueButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? Color.blue : Color.white)
@ -22,7 +19,7 @@ struct BlueButtonStyle: ButtonStyle {
}
}
struct RedButtonStyle: ButtonStyle {
private struct RedButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? Color.red : Color.white)
@ -32,224 +29,231 @@ struct RedButtonStyle: ButtonStyle {
}
}
var osxScale:Bool = true
private var allowDischarge = true
struct settings<Content: View>: View {
var content: () -> Content
@State var launchOnLogin = LaunchAtLogin.isEnabled
@State var osxScaleToggle = osxScale
@ObservedObject var presenter = SMCPresenter.shared
init(@ViewBuilder _ content: @escaping () -> Content) {
self.content = content
//Helper.instance.delegate = self
}
private struct Settings: View {
@State private var launchAtLogin = LaunchAtLogin.isEnabled
@State private var oldKey = PersistanceManager.instance.oldKey
@ObservedObject private var presenter = SMCPresenter.shared
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
VStack {
Spacer().frame(height: 15)
Text(presenter.status)
HStack {
VStack(alignment: .leading) {
Toggle(isOn: Binding(
get: { launchAtLogin },
set: { newValue in
launchAtLogin = newValue
print("Launch at login turned \(newValue ? "on" : "off")!")
LaunchAtLogin.isEnabled = newValue
}
else{
print("launch on login turned off!")
LaunchAtLogin.isEnabled = false
)) {
Text("Launch at login")
}
if(!Helper.instance.appleSilicon!){
Toggle(isOn: Binding(
get: { oldKey },
set: { newValue in
oldKey = newValue
PersistanceManager.instance.oldKey = oldKey
PersistanceManager.instance.save()
Helper.instance.setStatusString()
if(newValue){
Helper.instance.enableCharging()
Helper.instance.enableSleep()
//presenter.writeValue()
}
else{
presenter.setValue(value: 100)
}
}
)) {
Text("Use Classic SMC Key (Intel)")
}
}
)) {
Text("Launch on Login")
}.padding()
Toggle(isOn: Binding(
get: {
self.osxScaleToggle
},
set: {(newValue) in
self.osxScaleToggle = newValue
osxScale = newValue
self.presenter.setValue(value: Float(self.presenter.value))
}
)) {
Text("Use MacOS battery scale")
}.padding()
Spacer()
Button( action: {
Helper.instance.installHelper()
}
) {
Button(action: {
Helper.instance.installHelper()
}) {
Text("Reinstall Helper")
.frame(maxWidth: 120, maxHeight: 30)
}.buttonStyle(BlueButtonStyle())
}
HStack(alignment: .center) {
Spacer()
VStack(alignment: .leading){
Text("AlDente 1.2 🍝").font(.subheadline)
Button(action:{
let url = URL(string: "https://www.github.com/davidwernhart/AlDente")!
if NSWorkspace.shared.open(url) {
print("default browser was successfully opened")
}
}){
Text("github.com/davidwernhart/AlDente").foregroundColor(Color.blue)
HStack {
Spacer().frame(width: 15)
VStack(alignment: .leading) {
let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
Text("AlDente \(version ?? "") 🍝").font(.headline)
let address = "github.com/davidwernhart/AlDente"
Button(action: {
openURL("https://" + address)
}) {
Text(address).foregroundColor(Color(.linkColor))
}.buttonStyle(PlainButtonStyle())
Text("Created with 🤍 by David Wernhart in 2020")
Text("Cooked up in 2021 by AppHouseKitchen")
// 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")
}
openURL("https://apphousekitchen.com/aldente/")
}) {
Text("Donate")
.frame(maxWidth: 60, maxHeight: 50)
Text("Get Pro 🍜")
.frame(maxWidth: 100, maxHeight: 50)
}
.buttonStyle(BlueButtonStyle())
}
}.background(Color("SettingsColor")).cornerRadius(5)
}
.background(Color(.unemphasizedSelectedContentBackgroundColor))
.cornerRadius(5)
}
private func openURL(_ string: String) {
let url = URL(string: string)!
if NSWorkspace.shared.open(url) {
print("default browser was successfully opened")
}
}
}
struct ContentView: View{
@State var adaptableHeight = CGFloat(100)
@State var showSettings = false
@ObservedObject var presenter = SMCPresenter.shared
struct ContentView: View {
@State private var adaptableHeight = CGFloat(100)
@State private var showSettings = false
@ObservedObject private var presenter = SMCPresenter.shared
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
var body: some View {
VStack(alignment: .leading) {
HStack {
Text("Max. Battery Charge:").padding(.leading)
TextField("Number", value: Binding(
get: {
Float(presenter.value)
},
set: { newValue in
if newValue >= 20 && newValue <= 100 {
presenter.setValue(value: newValue)
}
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)
}
}
), formatter: NumberFormatter())
.multilineTextAlignment(.center)
.frame(maxWidth: 50)
.textFieldStyle(RoundedBorderTextFieldStyle())
Spacer()
if(self.showSettings){
//settings{Text("")}
settings({Text("")})
Button(action: {
showSettings.toggle()
adaptableHeight = showSettings ? 275 : 100
}) {
Text("Settings")
.frame(maxWidth: 70, maxHeight: 30)
}.buttonStyle(BlueButtonStyle()).padding(.leading, -30)
Button(action: {
NSApplication.shared.terminate(self)
}) {
Text("Quit")
.frame(maxWidth: 50, maxHeight: 30)
}.buttonStyle(RedButtonStyle()).padding(.leading, -30)
}
Slider(value: Binding(
get: {
Float(presenter.value)
},
set: { newValue in
if newValue >= 20 && newValue <= 100 {
presenter.setValue(value: newValue)
}
}
}.frame(width: 400, height: adaptableHeight)
}
return vstack
), in: 20...100).padding(.horizontal).padding(.top, -20)
Spacer()
if showSettings {
Settings()
}
}.frame(width: 400, height: adaptableHeight)
}
}
class SMCPresenter: ObservableObject, HelperDelegate{
public final class SMCPresenter: ObservableObject, HelperDelegate {
static let shared = SMCPresenter()
@Published var value: UInt8 = 0
@Published var status: String = ""
private var timer: Timer?
func OnMaxBatRead(value: UInt8){
DispatchQueue.main.async {
if(osxScale){
self.value = value + 3
}
else{
private var accuracyTimer: Timer?
func OnMaxBatRead(value: UInt8) {
if(PersistanceManager.instance.oldKey){
DispatchQueue.main.async {
self.value = value
}
}
}
func setValue(value: Float){
func updateStatus(status:String){
DispatchQueue.main.async {
self.status = status
}
}
public func loadValue(){
PersistanceManager.instance.load()
self.value = UInt8(PersistanceManager.instance.chargeVal!)
if(self.value == 0){
self.value = 50
}
print("loaded max charge val: ",self.value," old key:",PersistanceManager.instance.oldKey)
// if(!Helper.instance.appleSilicon!){
// Helper.instance.getSMCCharge(withReply: { (smcval) in
// self.value = UInt8(smcval)
// })
// }
if(PersistanceManager.instance.oldKey){
writeValue()
}
}
func setValue(value: Float) {
DispatchQueue.main.async {
self.value = UInt8(value)
PersistanceManager.instance.chargeVal = Int(value)
PersistanceManager.instance.save()
self.writeValue()
}
timer?.invalidate()
accuracyTimer?.invalidate()
}
func writeValue(){
if(PersistanceManager.instance.oldKey){
print("should write bclm value: ", self.value)
Helper.instance.writeMaxBatteryCharge(setVal: self.value)
}
self.timer?.invalidate()
self.timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false, block: { timer in
var setval = value
if(osxScale){
setval -= 3
}
if(setval >= 20 && setval <= 100){
print("Setting Max Battery To: ",setval)
Helper.instance.writeMaxBatteryCharge(setVal: UInt8(setval))
Helper.instance.readMaxBatteryCharge()
self.timer = nil
}
})
}
}

View File

@ -6,119 +6,289 @@
// Copyright © 2020 David Wernhart. All rights reserved.
//
import Cocoa
import SwiftUI
import ServiceManagement
import Foundation
import ServiceManagement
import IOKit.pwr_mgt
protocol HelperDelegate {
func OnMaxBatRead(value: UInt8)
func updateStatus(status:String)
}
class Helper{
final 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
// // }
// }
// }
// }
private var key: String?
private var preventSleepID: IOPMAssertionID?
public var appleSilicon:Bool?
public var chargeInhibited: Bool = false
public var isInitialized:Bool = false
public var statusString:String = ""
lazy var helperToolConnection: NSXPCConnection = {
let connection = NSXPCConnection(machServiceName: "com.davidwernhart.Helper.mach", options: .privileged)
connection.remoteObjectInterface = NSXPCInterface(with: HelperToolProtocol.self)
connection.resume()
return connection
}()
func setPlatformKey() {
let s:String! = ProcessInfo.init().machineHardwareName
if(s != nil){
if(s.elementsEqual("x86_64")){
print("intel cpu!")
appleSilicon = false;
}
else if(s.elementsEqual("arm64")){
print("arm cpu!")
appleSilicon = true;
}
}
}
func setStatusString(){
checkCharging()
var sleepDisabled:Bool = !(preventSleepID == nil)
statusString = ""
if(PersistanceManager.instance.oldKey){
statusString = "BCLM Key Mode. Final charge value can differ by up to 5%"
}
else{
statusString = "Charge Inhibit: "+String(chargeInhibited)+" | Prevent Sleep: "+String(sleepDisabled)+" | Helper v"+String(helperVersion)+": \(self.isInitialized ? "found" : "not found")"
}
self.delegate?.updateStatus(status: statusString)
}
func enableSleep(){
if(self.preventSleepID != nil){
print("RELEASING PREVENT SLEEP ASSERTION WITH ID: ",preventSleepID!)
releaseAssertion(assertionId: self.preventSleepID!)
self.preventSleepID = nil
}
}
func disableSleep(){
createAssertion(assertion: kIOPMAssertionTypePreventSystemSleep){ id in
if(self.preventSleepID == nil){
print("PREVENT SLEEP ASSERTION CREATED! ID: ",id)
self.preventSleepID = id
}
}
}
func enableCharging(){
if(appleSilicon!){
SMCWriteByte(key: "CH0B", value: 00)
}
SMCWriteByte(key: "CH0B", value: 00)
self.chargeInhibited = false
}
func disableCharging(){
if(appleSilicon!){
SMCWriteByte(key: "CH0B", value: 02)
}
SMCWriteByte(key: "CH0B", value: 02)
self.chargeInhibited = true
}
func checkCharging(){
Helper.instance.SMCReadUInt32(key: "CH0B") { value in
self.chargeInhibited = !(value == 00)
print("CHARGE INHIBITED: "+String(self.chargeInhibited))
}
if(PersistanceManager.instance.oldKey){
Helper.instance.readMaxBatteryCharge()
}
}
func getChargingInfo(withReply reply: (String,Int,Bool,Int) -> Void){
let snapshot = IOPSCopyPowerSourcesInfo().takeRetainedValue()
let sources = IOPSCopyPowerSourcesList(snapshot).takeRetainedValue() as Array
let info = IOPSGetPowerSourceDescription(snapshot, sources[0]).takeUnretainedValue() as! [String: AnyObject]
if let name = info[kIOPSNameKey] as? String,
let capacity = info[kIOPSCurrentCapacityKey] as? Int,
let isCharging = info[kIOPSIsChargingKey] as? Bool,
let max = info[kIOPSMaxCapacityKey] as? Int {
reply(name,capacity,isCharging,max)
}
}
func getSMCCharge(withReply reply: @escaping (Float)->Void){
Helper.instance.SMCReadUInt32(key: "BRSC") { value in
let smcval = Float(value >> 16)
reply(smcval)
}
}
@objc func createAssertion(assertion: String, withReply reply: @escaping (IOPMAssertionID) -> Void){
let helper = helperToolConnection.remoteObjectProxyWithErrorHandler {
let e = $0 as NSError
print("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
} as? HelperToolProtocol
helper?.createAssertion(assertion: assertion, withReply: { id in
reply(id)
})
}
@objc func releaseAssertion(assertionId: IOPMAssertionID){
let helper = helperToolConnection.remoteObjectProxyWithErrorHandler {
let e = $0 as NSError
print("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
} as? HelperToolProtocol
helper?.releaseAssertion(assertionID: assertionId)
}
@objc func installHelper() {
print("trying to install helper!")
var status: OSStatus = noErr
let helperID = "com.davidwernhart.Helper" as CFString//Prefs.helperID as CFString
var status = 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)
var authItem = kSMRightBlessPrivilegedHelper.withCString {
AuthorizationItem(name: $0, valueLength: 0, value: nil, flags: 0)
}
var authRights = withUnsafeMutablePointer(to: &authItem) {
AuthorizationRights(count: 1, items: $0)
}
let authFlags: AuthorizationFlags = [.interactionAllowed, .preAuthorize, .extendRights]
var authRef: AuthorizationRef? = nil
var authRef: AuthorizationRef?
status = AuthorizationCreate(&authRights, nil, authFlags, &authRef)
if status != errAuthorizationSuccess {
print(SecCopyErrorMessageString(status,nil))
print("Error:", String(status))
print(SecCopyErrorMessageString(status, nil) ?? "")
print("Error: \(status)")
}
var error: Unmanaged<CFError>? = nil
var error: Unmanaged<CFError>?
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))
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)
if(error == nil){
print("helper installed successfully!")
restart()
}
}
@objc func readMaxBatteryCharge(){
SMCReadByte(key:"BCLM",withReply: { (value) in
print(String(value))
self.delegate?.OnMaxBatRead(value: value)
})
func restart(){
let url = URL(fileURLWithPath: Bundle.main.resourcePath!)
let path = url.deletingLastPathComponent().deletingLastPathComponent().absoluteString
let task = Process()
task.launchPath = "/usr/bin/open"
task.arguments = [path]
task.launch()
exit(0)
}
@objc func setResetValues(){
let helper = helperToolConnection.remoteObjectProxyWithErrorHandler {
let e = $0 as NSError
print("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
} as? HelperToolProtocol
helper?.setResetVal(key: "CH0B", value: 00)
}
@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 writeMaxBatteryCharge(setVal: UInt8) {
SMCWriteByte(key: "BCLM", value: setVal)
}
@objc func readMaxBatteryCharge() {
SMCReadByte(key: "BCLM") { value in
print("OLD KEY MAX CHARGE: "+String(value))
self.delegate?.OnMaxBatRead(value: value)
}
}
@objc func enableCharging(enabled: Bool) {
if(enabled){
SMCWriteByte(key: "CH0B", value: 00)
}
else{
SMCWriteByte(key: "CH0B", value: 02)
}
@objc func SMCReadByte(key:String, withReply reply: @escaping (UInt8) -> Void){
if let helper = helperToolConnection.remoteObjectProxyWithErrorHandler({ (error) in
let e = error as NSError
}
@objc func checkHelperVersion(withReply reply: @escaping (Bool) -> Void) {
print("checking helper version")
let helper = helperToolConnection.remoteObjectProxyWithErrorHandler {
let e = $0 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)
reply(false)
return()
} as? HelperToolProtocol
helper?.getVersion { version in
print("helperVersion:", helperVersion, " version from helper:", version)
if !helperVersion.elementsEqual(version) {
reply(false)
return()
}
else{
self.isInitialized = true
reply(true)
return()
}
}
}
@objc func SMCWriteByte(key:String,value:UInt8){
if let helper = helperToolConnection.remoteObjectProxyWithErrorHandler({ (error) in
let e = error as NSError
@objc func SMCReadByte(key: String, withReply reply: @escaping (UInt8) -> Void) {
let helper = helperToolConnection.remoteObjectProxyWithErrorHandler {
let e = $0 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)
} as? HelperToolProtocol
helper?.readSMCByte(key: key) {
reply($0)
}
}
@objc func SMCReadUInt32(key: String, withReply reply: @escaping (UInt32) -> Void) {
let helper = helperToolConnection.remoteObjectProxyWithErrorHandler {
let e = $0 as NSError
print("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
} as? HelperToolProtocol
helper?.readSMCUInt32(key: key) {
reply($0)
}
}
@objc func SMCWriteByte(key: String, value: UInt8) {
let helper = helperToolConnection.remoteObjectProxyWithErrorHandler {
let e = $0 as NSError
print("Remote proxy error \(e.code): \(e.localizedDescription) \(e.localizedRecoverySuggestion ?? "---")")
} as? HelperToolProtocol
helper?.setSMCByte(key: key, value: value)
}
}

View File

@ -33,9 +33,9 @@
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticTermination</key>
<true/>
<false/>
<key>NSSupportsSuddenTermination</key>
<true/>
<false/>
<key>SMPrivilegedExecutables</key>
<dict>
<key>com.davidwernhart.Helper</key>

View File

@ -0,0 +1,29 @@
//
// PersistanceManager.swift
// AlDente
//
// Created by David Wernhart on 07.02.21.
// Copyright © 2021 David Wernhart. All rights reserved.
//
import Foundation
class PersistanceManager{
static let instance = PersistanceManager()
public var launchOnLogin: Bool?
public var chargeVal: Int?
public var oldKey: Bool = false
public func load(){
launchOnLogin = UserDefaults.standard.bool(forKey: "launchOnLogin")
oldKey = UserDefaults.standard.bool(forKey: "oldKey")
chargeVal = UserDefaults.standard.integer(forKey: "chargeVal")
}
public func save(){
UserDefaults.standard.set(launchOnLogin, forKey: "launchOnLogin")
UserDefaults.standard.set(chargeVal, forKey: "chargeVal")
UserDefaults.standard.set(oldKey, forKey: "oldKey")
}
}

128
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@ -1,2 +0,0 @@
github "sindresorhus/LaunchAtLogin"

View File

@ -1 +0,0 @@
github "sindresorhus/LaunchAtLogin" "v3.0.0"

BIN
Carthage/.DS_Store vendored

Binary file not shown.

BIN
Carthage/Build/.DS_Store generated vendored

Binary file not shown.

View File

@ -1,10 +0,0 @@
{
"commitish" : "v3.0.0",
"Mac" : [
{
"name" : "LaunchAtLogin",
"hash" : "3e5f8a12d3371e2e67b1cb69491ac112af892603ed2ceb6af78d9727577f3371",
"swiftToolchainVersion" : "5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)"
}
]
}

BIN
Carthage/Build/Mac/.DS_Store generated vendored

Binary file not shown.

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.com.sindresorhus.LaunchAtLogin</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>3.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -1 +0,0 @@
Versions/Current/Headers

View File

@ -1 +0,0 @@
Versions/Current/LaunchAtLogin

View File

@ -1 +0,0 @@
Versions/Current/Modules

View File

@ -1 +0,0 @@
Versions/Current/Resources

View File

@ -1,209 +0,0 @@
// Generated by Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgcc-compat"
#if !defined(__has_include)
# define __has_include(x) 0
#endif
#if !defined(__has_attribute)
# define __has_attribute(x) 0
#endif
#if !defined(__has_feature)
# define __has_feature(x) 0
#endif
#if !defined(__has_warning)
# define __has_warning(x) 0
#endif
#if __has_include(<swift/objc-prologue.h>)
# include <swift/objc-prologue.h>
#endif
#pragma clang diagnostic ignored "-Wauto-import"
#include <Foundation/Foundation.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#if !defined(SWIFT_TYPEDEFS)
# define SWIFT_TYPEDEFS 1
# if __has_include(<uchar.h>)
# include <uchar.h>
# elif !defined(__cplusplus)
typedef uint_least16_t char16_t;
typedef uint_least32_t char32_t;
# endif
typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2)));
typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3)));
typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#endif
#if !defined(SWIFT_PASTE)
# define SWIFT_PASTE_HELPER(x, y) x##y
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
#endif
#if !defined(SWIFT_METATYPE)
# define SWIFT_METATYPE(X) Class
#endif
#if !defined(SWIFT_CLASS_PROPERTY)
# if __has_feature(objc_class_property)
# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
# else
# define SWIFT_CLASS_PROPERTY(...)
# endif
#endif
#if __has_attribute(objc_runtime_name)
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
#else
# define SWIFT_RUNTIME_NAME(X)
#endif
#if __has_attribute(swift_name)
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#else
# define SWIFT_COMPILE_NAME(X)
#endif
#if __has_attribute(objc_method_family)
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
#else
# define SWIFT_METHOD_FAMILY(X)
#endif
#if __has_attribute(noescape)
# define SWIFT_NOESCAPE __attribute__((noescape))
#else
# define SWIFT_NOESCAPE
#endif
#if __has_attribute(ns_consumed)
# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed))
#else
# define SWIFT_RELEASES_ARGUMENT
#endif
#if __has_attribute(warn_unused_result)
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
# define SWIFT_WARN_UNUSED_RESULT
#endif
#if __has_attribute(noreturn)
# define SWIFT_NORETURN __attribute__((noreturn))
#else
# define SWIFT_NORETURN
#endif
#if !defined(SWIFT_CLASS_EXTRA)
# define SWIFT_CLASS_EXTRA
#endif
#if !defined(SWIFT_PROTOCOL_EXTRA)
# define SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_ENUM_EXTRA)
# define SWIFT_ENUM_EXTRA
#endif
#if !defined(SWIFT_CLASS)
# if __has_attribute(objc_subclassing_restricted)
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# else
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# endif
#endif
#if !defined(SWIFT_RESILIENT_CLASS)
# if __has_attribute(objc_class_stub)
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub))
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME)
# else
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME)
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME)
# endif
#endif
#if !defined(SWIFT_PROTOCOL)
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_EXTENSION)
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
#endif
#if !defined(OBJC_DESIGNATED_INITIALIZER)
# if __has_attribute(objc_designated_initializer)
# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
# else
# define OBJC_DESIGNATED_INITIALIZER
# endif
#endif
#if !defined(SWIFT_ENUM_ATTR)
# if defined(__has_attribute) && __has_attribute(enum_extensibility)
# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility)))
# else
# define SWIFT_ENUM_ATTR(_extensibility)
# endif
#endif
#if !defined(SWIFT_ENUM)
# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
# if __has_feature(generalized_swift_name)
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
# else
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility)
# endif
#endif
#if !defined(SWIFT_UNAVAILABLE)
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
#endif
#if !defined(SWIFT_AVAILABILITY)
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
#endif
#if !defined(SWIFT_WEAK_IMPORT)
# define SWIFT_WEAK_IMPORT __attribute__((weak_import))
#endif
#if !defined(SWIFT_DEPRECATED)
# define SWIFT_DEPRECATED __attribute__((deprecated))
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#if __has_feature(attribute_diagnose_if_objc)
# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning")))
#else
# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)
#endif
#if !defined(IBSegueAction)
# define IBSegueAction
#endif
#if __has_feature(modules)
#if __has_warning("-Watimport-in-framework-header")
#pragma clang diagnostic ignored "-Watimport-in-framework-header"
#endif
#endif
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
#if __has_warning("-Wpragma-clang-attribute")
# pragma clang diagnostic ignored "-Wpragma-clang-attribute"
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wnullability"
#if __has_attribute(external_source_symbol)
# pragma push_macro("any")
# undef any
# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="LaunchAtLogin",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol))
# pragma pop_macro("any")
#endif
#if __has_attribute(external_source_symbol)
# pragma clang attribute pop
#endif
#pragma clang diagnostic pop

View File

@ -1,4 +0,0 @@
#import <Cocoa/Cocoa.h>
FOUNDATION_EXPORT double LaunchAtLoginVersionNumber;
FOUNDATION_EXPORT const unsigned char LaunchAtLoginVersionString[];

View File

@ -1,11 +0,0 @@
framework module LaunchAtLogin {
umbrella header "LaunchAtLogin.h"
export *
module * { export * }
}
module LaunchAtLogin.Swift {
header "LaunchAtLogin-Swift.h"
requires objc
}

View File

@ -1,44 +0,0 @@
<?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>BuildMachineOSBuild</key>
<string>19F101</string>
<key>CFBundleExecutable</key>
<string>LaunchAtLogin</string>
<key>CFBundleIdentifier</key>
<string>com.sindresorhus.LaunchAtLogin</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>LaunchAtLogin</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.0.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11E608c</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>19E258</string>
<key>DTSDKName</key>
<string>macosx10.15</string>
<key>DTXcode</key>
<string>1150</string>
<key>DTXcodeBuild</key>
<string>11E608c</string>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
<key>NSHumanReadableCopyright</key>
<string>MIT © Sindre Sorhus</string>
</dict>
</plist>

View File

@ -1,48 +0,0 @@
<?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>BuildMachineOSBuild</key>
<string>19F101</string>
<key>CFBundleExecutable</key>
<string>LaunchAtLoginHelper</string>
<key>CFBundleIdentifier</key>
<string>com.sindresorhus.LaunchAtLoginHelper</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>LaunchAtLoginHelper</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11E608c</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>19E258</string>
<key>DTSDKName</key>
<string>macosx10.15</string>
<key>DTXcode</key>
<string>1150</string>
<key>DTXcodeBuild</key>
<string>11E608c</string>
<key>LSBackgroundOnly</key>
<true/>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
<key>NSHumanReadableCopyright</key>
<string>MIT © Sindre Sorhus</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -1,22 +0,0 @@
#!/bin/bash
origin_helper_path="$BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH/LaunchAtLogin.framework/Resources/LaunchAtLoginHelper.app"
helper_dir="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems"
helper_path="$helper_dir/LaunchAtLoginHelper.app"
rm -rf "$helper_path"
mkdir -p "$helper_dir"
cp -rf "$origin_helper_path" "$helper_dir/"
defaults write "$helper_path/Contents/Info" CFBundleIdentifier -string "$PRODUCT_BUNDLE_IDENTIFIER-LaunchAtLoginHelper"
if [[ -n $CODE_SIGN_ENTITLEMENTS ]]; then
codesign --force --entitlements="$CODE_SIGN_ENTITLEMENTS" --options=runtime --sign="$EXPANDED_CODE_SIGN_IDENTITY_NAME" "$helper_path"
else
codesign --force --options=runtime --sign="$EXPANDED_CODE_SIGN_IDENTITY_NAME" "$helper_path"
fi
if [[ $CONFIGURATION == "Release" ]]; then
rm -rf "$origin_helper_path"
rm "$(dirname "$origin_helper_path")/copy-helper.sh"
fi

View File

@ -1 +0,0 @@
A

View File

@ -1,8 +0,0 @@
root = true
[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

View File

@ -1 +0,0 @@
* text=auto eol=lf

View File

@ -1,4 +0,0 @@
github: sindresorhus
open_collective: sindresorhus
patreon: sindresorhus
custom: https://sindresorhus.com/donate

View File

@ -1,2 +0,0 @@
xcuserdata
project.xcworkspace

View File

@ -1,494 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
E32E9B681EB87D7B000FEEE9 /* LaunchAtLogin.h in Headers */ = {isa = PBXBuildFile; fileRef = E32E9B661EB87D7B000FEEE9 /* LaunchAtLogin.h */; settings = {ATTRIBUTES = (Public, ); }; };
E32E9B6F1EB87DC5000FEEE9 /* LaunchAtLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E32E9B6E1EB87DC5000FEEE9 /* LaunchAtLogin.swift */; };
E32E9B771EB87EA3000FEEE9 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = E32E9B761EB87EA3000FEEE9 /* main.swift */; };
E32E9B861EB8845E000FEEE9 /* LaunchAtLoginHelper.app in Resources */ = {isa = PBXBuildFile; fileRef = E32E9B741EB87EA3000FEEE9 /* LaunchAtLoginHelper.app */; };
E32E9B931EB889AE000FEEE9 /* copy-helper.sh in Resources */ = {isa = PBXBuildFile; fileRef = E32E9B921EB889AE000FEEE9 /* copy-helper.sh */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
E32E9B871EB88462000FEEE9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = E32E9B5A1EB87D7B000FEEE9 /* Project object */;
proxyType = 1;
remoteGlobalIDString = E32E9B731EB87EA3000FEEE9;
remoteInfo = LaunchAtLoginHelper;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
E32E9B631EB87D7B000FEEE9 /* LaunchAtLogin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LaunchAtLogin.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E32E9B661EB87D7B000FEEE9 /* LaunchAtLogin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = LaunchAtLogin.h; sourceTree = "<group>"; usesTabs = 1; };
E32E9B671EB87D7B000FEEE9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E32E9B6E1EB87DC5000FEEE9 /* LaunchAtLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = LaunchAtLogin.swift; sourceTree = "<group>"; usesTabs = 1; };
E32E9B741EB87EA3000FEEE9 /* LaunchAtLoginHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LaunchAtLoginHelper.app; sourceTree = BUILT_PRODUCTS_DIR; };
E32E9B761EB87EA3000FEEE9 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = main.swift; sourceTree = "<group>"; usesTabs = 1; };
E32E9B7F1EB87EA3000FEEE9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E32E9B921EB889AE000FEEE9 /* copy-helper.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; lineEnding = 0; path = "copy-helper.sh"; sourceTree = "<group>"; usesTabs = 1; };
E3B8C38A20C0003300272EC0 /* LaunchAtLoginHelper.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LaunchAtLoginHelper.entitlements; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
E32E9B5F1EB87D7B000FEEE9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
E32E9B711EB87EA3000FEEE9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
E32E9B591EB87D7B000FEEE9 = {
isa = PBXGroup;
children = (
E32E9B651EB87D7B000FEEE9 /* LaunchAtLogin */,
E32E9B751EB87EA3000FEEE9 /* LaunchAtLoginHelper */,
E32E9B641EB87D7B000FEEE9 /* Products */,
);
sourceTree = "<group>";
usesTabs = 1;
};
E32E9B641EB87D7B000FEEE9 /* Products */ = {
isa = PBXGroup;
children = (
E32E9B631EB87D7B000FEEE9 /* LaunchAtLogin.framework */,
E32E9B741EB87EA3000FEEE9 /* LaunchAtLoginHelper.app */,
);
name = Products;
sourceTree = "<group>";
};
E32E9B651EB87D7B000FEEE9 /* LaunchAtLogin */ = {
isa = PBXGroup;
children = (
E32E9B6E1EB87DC5000FEEE9 /* LaunchAtLogin.swift */,
E32E9B661EB87D7B000FEEE9 /* LaunchAtLogin.h */,
E32E9B921EB889AE000FEEE9 /* copy-helper.sh */,
E32E9B671EB87D7B000FEEE9 /* Info.plist */,
);
path = LaunchAtLogin;
sourceTree = "<group>";
};
E32E9B751EB87EA3000FEEE9 /* LaunchAtLoginHelper */ = {
isa = PBXGroup;
children = (
E32E9B761EB87EA3000FEEE9 /* main.swift */,
E32E9B7F1EB87EA3000FEEE9 /* Info.plist */,
E3B8C38A20C0003300272EC0 /* LaunchAtLoginHelper.entitlements */,
);
path = LaunchAtLoginHelper;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
E32E9B601EB87D7B000FEEE9 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
E32E9B681EB87D7B000FEEE9 /* LaunchAtLogin.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
E32E9B621EB87D7B000FEEE9 /* LaunchAtLogin */ = {
isa = PBXNativeTarget;
buildConfigurationList = E32E9B6B1EB87D7B000FEEE9 /* Build configuration list for PBXNativeTarget "LaunchAtLogin" */;
buildPhases = (
E32E9B5E1EB87D7B000FEEE9 /* Sources */,
E32E9B5F1EB87D7B000FEEE9 /* Frameworks */,
E32E9B601EB87D7B000FEEE9 /* Headers */,
E32E9B611EB87D7B000FEEE9 /* Resources */,
);
buildRules = (
);
dependencies = (
E32E9B881EB88462000FEEE9 /* PBXTargetDependency */,
);
name = LaunchAtLogin;
productName = LaunchAtLogin;
productReference = E32E9B631EB87D7B000FEEE9 /* LaunchAtLogin.framework */;
productType = "com.apple.product-type.framework";
};
E32E9B731EB87EA3000FEEE9 /* LaunchAtLoginHelper */ = {
isa = PBXNativeTarget;
buildConfigurationList = E32E9B801EB87EA3000FEEE9 /* Build configuration list for PBXNativeTarget "LaunchAtLoginHelper" */;
buildPhases = (
E32E9B701EB87EA3000FEEE9 /* Sources */,
E32E9B711EB87EA3000FEEE9 /* Frameworks */,
E32E9B721EB87EA3000FEEE9 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = LaunchAtLoginHelper;
productName = LaunchAtLoginHelper;
productReference = E32E9B741EB87EA3000FEEE9 /* LaunchAtLoginHelper.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
E32E9B5A1EB87D7B000FEEE9 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0830;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Sindre Sorhus";
TargetAttributes = {
E32E9B621EB87D7B000FEEE9 = {
CreatedOnToolsVersion = 8.3.2;
LastSwiftMigration = 1020;
};
E32E9B731EB87EA3000FEEE9 = {
CreatedOnToolsVersion = 8.3.2;
LastSwiftMigration = 1020;
SystemCapabilities = {
com.apple.HardenedRuntime = {
enabled = 1;
};
com.apple.Sandbox = {
enabled = 1;
};
};
};
};
};
buildConfigurationList = E32E9B5D1EB87D7B000FEEE9 /* Build configuration list for PBXProject "LaunchAtLogin" */;
compatibilityVersion = "Xcode 11.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = E32E9B591EB87D7B000FEEE9;
productRefGroup = E32E9B641EB87D7B000FEEE9 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
E32E9B621EB87D7B000FEEE9 /* LaunchAtLogin */,
E32E9B731EB87EA3000FEEE9 /* LaunchAtLoginHelper */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
E32E9B611EB87D7B000FEEE9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E32E9B861EB8845E000FEEE9 /* LaunchAtLoginHelper.app in Resources */,
E32E9B931EB889AE000FEEE9 /* copy-helper.sh in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E32E9B721EB87EA3000FEEE9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
E32E9B5E1EB87D7B000FEEE9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E32E9B6F1EB87DC5000FEEE9 /* LaunchAtLogin.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E32E9B701EB87EA3000FEEE9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E32E9B771EB87EA3000FEEE9 /* main.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
E32E9B881EB88462000FEEE9 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = E32E9B731EB87EA3000FEEE9 /* LaunchAtLoginHelper */;
targetProxy = E32E9B871EB88462000FEEE9 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
E32E9B691EB87D7B000FEEE9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VALID_ARCHS = x86_64;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
E32E9B6A1EB87D7B000FEEE9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
VALID_ARCHS = x86_64;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
E32E9B6C1EB87D7B000FEEE9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = LaunchAtLogin/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.LaunchAtLogin;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
E32E9B6D1EB87D7B000FEEE9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = LaunchAtLogin/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.LaunchAtLogin;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;
};
E32E9B811EB87EA3000FEEE9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = LaunchAtLoginHelper/LaunchAtLoginHelper.entitlements;
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = LaunchAtLoginHelper/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.LaunchAtLoginHelper;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
};
E32E9B821EB87EA3000FEEE9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = LaunchAtLoginHelper/LaunchAtLoginHelper.entitlements;
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = LaunchAtLoginHelper/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.LaunchAtLoginHelper;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
E32E9B5D1EB87D7B000FEEE9 /* Build configuration list for PBXProject "LaunchAtLogin" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E32E9B691EB87D7B000FEEE9 /* Debug */,
E32E9B6A1EB87D7B000FEEE9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
E32E9B6B1EB87D7B000FEEE9 /* Build configuration list for PBXNativeTarget "LaunchAtLogin" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E32E9B6C1EB87D7B000FEEE9 /* Debug */,
E32E9B6D1EB87D7B000FEEE9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
E32E9B801EB87EA3000FEEE9 /* Build configuration list for PBXNativeTarget "LaunchAtLoginHelper" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E32E9B811EB87EA3000FEEE9 /* Debug */,
E32E9B821EB87EA3000FEEE9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = E32E9B5A1EB87D7B000FEEE9 /* Project object */;
}

View File

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E32E9B621EB87D7B000FEEE9"
BuildableName = "LaunchAtLogin.framework"
BlueprintName = "LaunchAtLogin"
ReferencedContainer = "container:LaunchAtLogin.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E32E9B621EB87D7B000FEEE9"
BuildableName = "LaunchAtLogin.framework"
BlueprintName = "LaunchAtLogin"
ReferencedContainer = "container:LaunchAtLogin.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E32E9B621EB87D7B000FEEE9"
BuildableName = "LaunchAtLogin.framework"
BlueprintName = "LaunchAtLogin"
ReferencedContainer = "container:LaunchAtLogin.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E32E9B731EB87EA3000FEEE9"
BuildableName = "LaunchAtLoginHelper.app"
BlueprintName = "LaunchAtLoginHelper"
ReferencedContainer = "container:LaunchAtLogin.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E32E9B731EB87EA3000FEEE9"
BuildableName = "LaunchAtLoginHelper.app"
BlueprintName = "LaunchAtLoginHelper"
ReferencedContainer = "container:LaunchAtLogin.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E32E9B731EB87EA3000FEEE9"
BuildableName = "LaunchAtLoginHelper.app"
BlueprintName = "LaunchAtLoginHelper"
ReferencedContainer = "container:LaunchAtLogin.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E32E9B731EB87EA3000FEEE9"
BuildableName = "LaunchAtLoginHelper.app"
BlueprintName = "LaunchAtLoginHelper"
ReferencedContainer = "container:LaunchAtLogin.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -1,22 +0,0 @@
<?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>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</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>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>MIT © Sindre Sorhus</string>
</dict>
</plist>

View File

@ -1,4 +0,0 @@
#import <Cocoa/Cocoa.h>
FOUNDATION_EXPORT double LaunchAtLoginVersionNumber;
FOUNDATION_EXPORT const unsigned char LaunchAtLoginVersionString[];

View File

@ -1,21 +0,0 @@
import Foundation
import ServiceManagement
public struct LaunchAtLogin {
private static let id = "\(Bundle.main.bundleIdentifier!)-LaunchAtLoginHelper"
public static var isEnabled: Bool {
get {
guard let jobs = (SMCopyAllJobDictionaries(kSMDomainUserLaunchd).takeRetainedValue() as? [[String: AnyObject]]) else {
return false
}
let job = jobs.first { $0["Label"] as! String == id }
return job?["OnDemand"] as? Bool ?? false
}
set {
SMLoginItemSetEnabled(id as CFString, newValue)
}
}
}

View File

@ -1,22 +0,0 @@
#!/bin/bash
origin_helper_path="$BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH/LaunchAtLogin.framework/Resources/LaunchAtLoginHelper.app"
helper_dir="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems"
helper_path="$helper_dir/LaunchAtLoginHelper.app"
rm -rf "$helper_path"
mkdir -p "$helper_dir"
cp -rf "$origin_helper_path" "$helper_dir/"
defaults write "$helper_path/Contents/Info" CFBundleIdentifier -string "$PRODUCT_BUNDLE_IDENTIFIER-LaunchAtLoginHelper"
if [[ -n $CODE_SIGN_ENTITLEMENTS ]]; then
codesign --force --entitlements="$CODE_SIGN_ENTITLEMENTS" --options=runtime --sign="$EXPANDED_CODE_SIGN_IDENTITY_NAME" "$helper_path"
else
codesign --force --options=runtime --sign="$EXPANDED_CODE_SIGN_IDENTITY_NAME" "$helper_path"
fi
if [[ $CONFIGURATION == "Release" ]]; then
rm -rf "$origin_helper_path"
rm "$(dirname "$origin_helper_path")/copy-helper.sh"
fi

View File

@ -1,28 +0,0 @@
<?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>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</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>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>MIT © Sindre Sorhus</string>
<key>LSBackgroundOnly</key>
<true/>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -1,8 +0,0 @@
<?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>
<true/>
</dict>
</plist>

View File

@ -1,25 +0,0 @@
import Cocoa
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
let bundleId = Bundle.main.bundleIdentifier!
// TODO: Make this more strict by only replacing at the end
let mainBundleId = bundleId.replacingOccurrences(of: "-LaunchAtLoginHelper", with: "")
// Ensure the app is not already running
guard NSRunningApplication.runningApplications(withBundleIdentifier: mainBundleId).isEmpty else {
NSApp.terminate(nil)
return
}
let pathComponents = (Bundle.main.bundlePath as NSString).pathComponents
let mainPath = NSString.path(withComponents: Array(pathComponents[0...(pathComponents.count - 5)]))
NSWorkspace.shared.launchApplication(mainPath)
NSApp.terminate(nil)
}
}
private let app = NSApplication.shared
private let delegate = AppDelegate()
app.delegate = delegate
app.run()

View File

@ -1,21 +0,0 @@
# Before and after
With `LaunchAtLogin`, you only have to do 2 steps instead of 13!
```diff
- 1. Create a new target that will be the helper app that launches your app
- 2. Set `LSBackgroundOnly` to true in the `Info.plist` file
- 3. Set `Skip Install` to `YES` in the build settings for the helper app
- 4. Enable sandboxing for the helper app
- 5. Add a new `Copy Files` build phase to the main app
- 6. Select `Wrapper` as destination
- 7. Enter `Contents/Library/LoginItems` as subpath
- 8. Add the helper build product to the build phase
- 9. Copy-paste some boilerplate code into the helper app
- 10. Remember to replace `bundleid.of.main.app` and `MainExectuableName` with your own values
- 11. Copy-paste some code to register the helper app into your main app
- 12. Make sure the main app and helper app use the same code signing certificate
- 13. Manually verify that you did everything correctly
+ 1. Install this package
+ 2. Add a new "Run Script Phase"
```

View File

@ -1,9 +0,0 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,88 +0,0 @@
# LaunchAtLogin
> Add “Launch at Login” functionality to your macOS app in seconds
It's usually quite a [convoluted and error-prone process](before-after.md) to add this. **No more!**
This package works with both sandboxed and non-sandboxed apps and it's App Store compatible and used in apps like [Plash](https://github.com/sindresorhus/Plash), [Dato](https://sindresorhus.com/dato), [Lungo](https://sindresorhus.com/lungo), and [Battery Indicator](https://sindresorhus.com/battery-indicator).
## Requirements
- macOS 10.12+
- Xcode 11+
- Swift 5+
## Install
#### Carthage
```
github "sindresorhus/LaunchAtLogin"
```
## Usage
Add a new ["Run Script Phase"](http://stackoverflow.com/a/39633955/64949) below "Embed Frameworks" in "Build Phases" with the following:
```sh
"${PROJECT_DIR}/Carthage/Build/Mac/LaunchAtLogin.framework/Resources/copy-helper.sh"
```
Use it in your app:
```swift
import LaunchAtLogin
print(LaunchAtLogin.isEnabled)
//=> false
LaunchAtLogin.isEnabled = true
print(LaunchAtLogin.isEnabled)
//=> true
```
No need to store any state to UserDefaults.
*Note that the [Mac App Store guidelines](https://developer.apple.com/app-store/review/guidelines/) requires “launch at login” functionality to be enabled in response to a user action. This is usually solved by making it a preference that is disabled by default. Many apps also let the user activate it in a welcome screen.*
## How does it work?
The framework bundles the helper app needed to launch your app and copies it into your app at build time.
## FAQ
#### My app doesn't show up in “System Preferences Users & Groups Login Items”
[This is the expected behavior](https://stackoverflow.com/a/15104481/64949), unfortunately.
#### My app doesn't launch at login when testing
This is usually caused by having one or more older builds of your app laying around somewhere on the system, and macOS picking one of those instead, which doesn't have the launch helper, and thus fails to start.
Some things you can try:
- Bump the version & build of your app so macOS is more likely to pick it.
- Delete the [`DerivedData` directory](https://mgrebenets.github.io/mobile%20ci/2015/02/01/xcode-derived-data).
- Ensure you don't have any other builds laying around somewhere.
Some helpful Stack Overflow answers:
- https://stackoverflow.com/a/43281810/64949
- https://stackoverflow.com/a/51683190/64949
- https://stackoverflow.com/a/53110832/64949
- https://stackoverflow.com/a/53110852/64949
#### Can you support CocoaPods?
CocoaPods used to be supported, but [it did not work well](https://github.com/sindresorhus/LaunchAtLogin/issues/22) and there was no easy way to fix it, so support was dropped. Even though you mainly use CocoaPods, you can still use Carthage just for this package without any problems.
#### I'm getting a `'SMCopyAllJobDictionaries' was deprecated in OS X 10.10` warning
Apple deprecated that API without providing an alternative. Apple engineers have [stated that it's still the preferred API to use](https://github.com/alexzielenski/StartAtLoginController/issues/12#issuecomment-307525807). I plan to use it as long as it's available. There are workarounds I can implement if Apple ever removes the API, so rest assured, this module will be made to work even then. If you want to see this resolved, submit a [Feedback Assistant](https://feedbackassistant.apple.com) report with [the following text](https://github.com/feedback-assistant/reports/issues/16). There's unfortunately still [no way to suppress warnings in Swift](https://stackoverflow.com/a/32861678/64949).
## Related
- [Defaults](https://github.com/sindresorhus/Defaults) - Swifty and modern UserDefaults
- [Preferences](https://github.com/sindresorhus/Preferences) - Add a preferences window to your macOS app in minutes
- [DockProgress](https://github.com/sindresorhus/DockProgress) - Show progress in your app's Dock icon
- [create-dmg](https://github.com/sindresorhus/create-dmg) - Create a good-looking DMG for your macOS app in seconds
- [More…](https://github.com/search?q=user%3Asindresorhus+language%3Aswift)

View File

@ -7,15 +7,21 @@
//
import Foundation
import IOKit.pwr_mgt
let helperVersion: String = "4" //for some reason the integrated version check does not work, so I use this one
let helperVersion: String = "10" //for some reason the integrated version check does not work, so I use this one
@objc(HelperToolProtocol) protocol HelperToolProtocol {
//protocol HelperToolProtocol {
func getVersion(withReply reply: @escaping (String) -> Void)
//TODO: more functions for other data types, altough this is sufficient for battery max charge level
func setSMCByte(key: String, value: UInt8)
func readSMCByte(key: String, withReply reply: @escaping (UInt8) -> Void)
func readSMCUInt32(key: String, withReply reply: @escaping (UInt32) -> Void)
func createAssertion(assertion:String, withReply reply: @escaping (IOPMAssertionID) -> Void)
func releaseAssertion(assertionID:IOPMAssertionID)
func setResetVal(key:String, value: UInt8)
}

180
LICENSE Normal file
View File

@ -0,0 +1,180 @@
1. Preamble
The AppHouseKitchenOG, owner: David Wernhart and Matthias Kerbl, located in Obersdorfer Straße 31/5/11, 2120 Wolkerdorf, Austria (hereinafter referred to as "COMPANY") offers the “All-In-One charge limiter app for MacBooks” “AlDente”.
The licence agreement regulates the use of the software "AlDente" (hereinafter referred to as "SOFTWARE") for free if the evaluation license has been selected.
This licence agreement is addressed to persons who wish to use the services for professional purposes, i.e. entrepreneurs in the sense of section 1 Abs 1 Z 1 KSchG („Austrian Customer Protection Act“) but also private customers (consumers in the sense of section 1 Abs Z 2 KSchG) (both together hereinafter referred to as "USER").
For the purpose of better readability, no gender-specific differentiation is made. This is done without any intention of discrimination. All genders are equally addressed.
2. Scope of application
This Evaluation Licence Agreement defines and regulates the procurement, use and commercial exploitation of the SOFTWARE as well as the related business and administrative activities if the USER uses the SOFTWARE free of charge for the purpose of evaluating the SOFTWARE. However, if the USER concludes a legal transaction against payment, a separate licence agreement shall apply.
3. Conditions of use
The USER is obliged to provide truthful, comprehensive and correct information within the framework of the business relationship and to keep the specific information up to date at all times. The USER shall treat all data confidentially (this applies in particular to log-in data and passwords). If the USER suspects misuse by third parties, he must inform the COMPANY of this immediately.
The USER shall refrain from all actions which may endanger or impair the technical functionality of the SOFTWARE (including cyber attacks). Such behaviour will be prosecuted.
The USER shall take reasonable precautions to protect the SOFTWARE from unauthorised access by third parties. The USER shall inform its employees or persons similar to employees that the creation of copies beyond the scope of this evaluation licence agreement is not permitted.
The USER is responsible for setting up the necessary infrastructure to ensure the intended operation of the SOFTWARE. The COMPANY is not obliged to provide any further information or advice in this respect.
It is the USER's responsibility to check the compatibility (i.e. the ability to interact with the USER's existing software and hardware infrastructure) and the functional scope of the SOFTWARE before using it against payment.
4. Copyright
The COMPANY shall provide the USER with the SOFTWARE on a non-exclusive basis and for a unlimited period of time, content and territory, however, only for the evaluation purposes (within the meaning of section 24 (1) sentence 1 of the Austrian Copyright Act "Werknutzungsbewilligung"). The objective purpose of the business relationship is the evaluation of the SOFTWARE for the purpose of trial. Unless expressly agreed otherwise, the SOFTWARE may also be used for commercial purposes. The exclusive right to use and exploit the SOFTWARE (within the meaning of section 24 (1) sentence 2 UrhG "Werknutzungsrecht") shall in any case remain with the COMPANY.
The USER is permitted to use the SOFTWARE exclusively for the evaluation purposes intended by the COMPANY.
Please note that the evaluation license does not grant the USER the right to use the SOFTWARE in its entirety.
Sub-licensing or further licensing is only permitted with the express consent of the COMPANY.
The right to decompile the SOFTWARE is excluded.
Markings of the SOFTWARE, in particular copyright notices, trademarks, serial numbers or similar may not be removed, changed or made unrecognisable.
The surrender of the source code of the SOFTWARE is not owed. Neither is a user manual owed, nor the performance of training courses.
5. Use of open source components
The SOFTWARE developed and provided by the COMPANY contains components that are licensed as Open Source Software. The OSS components may only be used under the respective OSS licence conditions. The OSS components are listed in Annex I. The source code of the OSS components (see „Readme“ in Annex I), the respective licence texts, any copyright notices and their disclaimers shall be made available to the CUSTOMER via link in Annex I.
Upon request by the CUSTOMER, the open source code can also be transmitted on a permanent data carrier (e.g. USB stick).
Attention: With regard to the OSS components used, the contractual partner of the CUSTOMER is not the COMPANY, but the respective open source licensor.
Attention: The COMPANY draws attention to the fact that risks are associated with the use of OSS components. As - demonstrative - examples are to be mentioned: Because the source code of the OSS components is public, it is susceptible to security incidents; furthermore, permanent maintenance and use of the OSS components is not ensured; warranty and damage claims are largely excluded.
6. Restriction of the duty to make available
Since no paid version is owed, the COMPANY is in no way obliged to make the SOFTWARE available. The COMPANY reserves the right to discontinue the SOFTWARE without notice.
7. Limitation of liability and warranty
Since no paid version is owed, all warranty and liability claims against the COMPANY are excluded in their entirety. This shall not apply in the event of intentional damage.
8. Right to amend the evaluation licence
The COMPANY shall be entitled to amend this Evaluation Licence Agreement at any time. The COMPANY shall inform the USER of such amendments by sending the amended Evaluation Licence Agreement to the contact details last provided by the USER. The USER shall have the right to object to the amendments. If the USER does not object within 14 days after notification of the amendments, it shall be assumed that the USER has tacitly agreed to the amended evaluation licence agreement.
9. Data protection and protection of business and trade secrets
The disclosure of data and information to the respective required business partners is permitted to the extent necessary for the fulfilment of the contractual relationship (Art 6 para 1 lit b GDPR). Otherwise, the COMPANY and the USER shall be mutually obliged to maintain secrecy with regard to the circumstances and data relating to the other of which they become aware as a result of the present business relationship and, in particular, to observe data secrecy. These obligations regarding data and business secrecy shall also apply beyond the contractual relationship. The COMPANY and the USER further undertake to instruct and instruct their employees and vicarious agents in this sense.
The contracting parties further undertake to protect mutually disclosed business and trade secrets appropriately within the meaning of section 26b (1) no. 3 of the Austrian UWG.
A violation of the confidentiality obligations may (among other things) result in consequences under criminal law and damages law.
It is pointed out that the source code programmed by the COMPANY constitutes a trade and business secret within the meaning of section 26b UWG.
The COMPANY informs that data of the USER may be processed for advertising purposes on the basis of legitimate interests (Art 6 para 1 lit f DSGVO). The USER is entitled to object to the processing of his/her data for advertising purposes (Art 21 (2) GDPR).
10. Reference-Clause
The COMPANY shall be entitled to indicate the fact of the business relationship with the USER by means of a reference on its homepage or business papers. The COMPANY shall be entitled to use the USER's logo in this context. This right to name references also extends beyond the contractual relationship.
11. Participation in evaluations
For the purpose of evaluating the SOFTWARE, the USER undertakes to provide the COMPANY with information on the user-friendliness and performance of the SOFTWARE to a reasonable extent free of charge upon request by the COMPANY and, if necessary, to communicate any suggestions for improvement.
12. Blocking access to the SOFTWARE
If the COMPANY has reasonable grounds to believe that the USER or one of its end users is using the SOFTWARE in an unlawful manner, the COMPANY shall be entitled to block access to the SOFTWARE immediately and without prior notice. This shall not affect the possibility of further legal remedies.
13. Jurisdiction and applicable law
This contractual relationship shall be governed by and construed in accordance with Austrian law. The application of the United Nations Convention on Contracts for the International Sale of Goods (CISG) and of conflict-of-law rules is excluded.
The exclusive place of jurisdiction is the competent court in Korneuburg, Austria.
14. Further issues
If any part of this Evaluation Licence Agreement should be invalid, the validity of the remaining conditions shall not be affected thereby. The invalid provision shall be replaced by a valid provision which comes as close as possible to the economic intent of both contracting parties as discernible from the agreement.
The COMPANY recommends the USER to save this licence agreement permanently.
ANNEX I Open Source:
sindresorhus/Defaults:
Function Library to persist user settings
Licence MIT-License: https://github.com/sindresorhus/Defaults/blob/main/license
Readme https://github.com/sindresorhus/Defaults
Disclaimer THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyrights Sindre Sorhus
sindresorhus/LaunchAtLogin:
Function Provides launch at login functionality
Licence MIT-License: https://github.com/sindresorhus/LaunchAtLogin/blob/main/license
Readme https://github.com/sindresorhus/LaunchAtLogin
Disclaimer THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyrights Sindre Sorhus
sindresorhus/Preferences:
Function Preference window library
Licence MIT-License: https://github.com/sindresorhus/Preferences/blob/main/license
Readme https://github.com/sindresorhus/Preferences
Disclaimer THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyrights Sindre Sorhus
sparkle-project/Sparkle
Function Framework for automatic app updates
Licence https://github.com/sparkle-project/Sparkle/blob/2.x/LICENSE
Readme https://github.com/sparkle-project/Sparkle
Disclaimer THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyrights Copyright (c) 2006-2013 Andy Matuschak.
Copyright (c) 2009-2013 Elgato Systems GmbH.
Copyright (c) 2011-2014 Kornel Lesiński.
Copyright (c) 2015-2017 Mayur Pawashe.
Copyright (c) 2014 C.W. Betts.
Copyright (c) 2014 Petroules Corporation.
Copyright (c) 2014 Big Nerd Ranch.
=================
EXTERNAL LICENSES
=================
bspatch.c and bsdiff.c, from bsdiff 4.3
Copyright (c) 2003-2005 Colin Percival.
sais.c and sais.c, from sais-lite (2010/08/07)
Copyright (c) 2008-2010 Yuta Mori.
SUSignatureVerifier.m:
Copyright (c) 2011 Mark Hamlin.
Beltex/SMCKit
Function Interface to access the System Management Controller
Licence MIT-License: https://github.com/beltex/SMCKit/blob/master/LICENSE
Readme https://github.com/beltex/SMCKit
Disclaimer THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Copyrights beltex

View File

@ -1,48 +1,49 @@
# AlDente 🍝
# AlDente - Charge Limiter🍝
_MacOS menu bar tool to limit maximum charging percentage_
#### Don't overcook your battery! Keep it fresh and chewy with AlDente.
## Why do I need this?
Li-ion and polymer batteries (like the one in your MacBook) last the longest when operating between 30 and 80 percent. Keeping your battery at 100% at all times can shorten the lifespan of your notebook significantly.
More information can be found here:
<https://batteryuniversity.com/learn/article/how_to_charge_when_to_charge_table>
Li-Ion batteries (like the one in your MacBook) last the longest when operating between 20 and 80 percent. Keeping your battery at 100% at all times can shorten the lifespan of your MacBook significantly.
More information can be found at [Battery University](https://batteryuniversity.com/article/bu-415-how-to-charge-and-when-to-charge).
## How does it work?
The tool writes the desired value to your MacBooks SMC (System Management Controller), which handles the rest.
For everyone that is curious, the modified SMC key is called "BCLM" (Presumably "Battery Charge Level Max")
## Whats AlDente Pro?
AlDente Pro is our paid version of AlDente. It has many more features such as Heat Protection, Sailing Mode, Top Up, Calibration Mode,... It offers a better design and has live status icons. If you are interested in getting the most out of your battery, check out our [website](https://apphousekitchen.com/).
## AlDente is tested and working on:
* 2019 MacBook Pro 16"
* 2017 Macbook Pro 13" without TouchBar
* 2017 MacBook Air 13"
* 2013 MacBook Pro 13"
AlDente Pro is now available on [Setapp](https://apphousekitchen.com/pricing/) too.
## Features of AlDente Free
* Charge Limiter allows you to set your maximum charging percentage between 20 and 100 percent. You can either set it by using the slide bar or by typing in the desired percentage in the field above and pressing enter afterwards. Read more about the Charge Limiter feature in this article ["Feature Explanation: Charge Limiter"](https://apphousekitchen.com/feature-explanation-charge-limiter/).
* Discharge - This feature allows your MacBook to run completely on Battery even if it is plugged in. Therefore, you can actively discharge your MacBook to a more healthy percentage. Unfortunately, while Discharge is activated, clamshell mode is not supported due to technical limitations. Read more about the Discharge feature in this article ["Feature Explanation: Discharge"](https://apphousekitchen.com/feature-explanation-discharge/).
## Download:
<https://github.com/davidwernhart/AlDente/releases>
## Supported MacBook Models (macOS 11 Big Sur or later required)
## How to use:
Simply open AlDente_Installer.dmg and drag the App to your Applications Folder.
On the first start, the application is going to ask you to allow installing a helper tool. This is necessary, since writing SMC Keys requires root privileges.
Once finished, enter your desired max. charging percentage by clicking on the 🍝 icon on your
menu bar.
Check out if your MacBook is supported on our [FAQ page](https://apphousekitchen.com/faq/).
For some reason, MacOS will always try to squeeze in a few more percent than specified by the SMC. For example, if you set yours to 80% it will stop charging at around 83%, so be patient. Strangely, this is not the case using Windows with bootcamp, therefore I have chosen not to correct this inaccuracy in code for now.
## Download
You can download the app from GitHub: <https://github.com/davidwernhart/AlDente/releases>
Usually, the operating system will take a minute or two registering the changes, so be patient. You can check if it's working by setting the max. percentage to e.g.: 70%. After a while, clicking on your battery icon will report "Battery is not charging" if you have more than ≈73% left, even tough your charger is connected. Notice that in this state, your MacBook is still powered by the charger, but the battery is not charging anymore.
## Installation Guide
An installation guide can be found on our website:[Installation Guide](https://apphousekitchen.com/installation-guide/)
## Other tools I used in this project:
## How to use
When the installation is finished, enter your desired max. charging percentage by clicking on the 🍝 icon on your menu bar. Usually, the operating system will take a minute or two registering the changes, so be patient. You can check if it's working by setting the max. percentage to e.g.: 80%. After a while, clicking on your battery icon will report "Battery is not charging" if you have more than ≈73% left, even though your charger is connected. Notice that in this state, your MacBook is still powered by the charger, but the battery is not charging anymore.
IMPORTANT: Keeping your battery at a lower percentage, such as under 80%, over weeks without doing full cycles (100%-0%) can result in a disturbed battery calibration. When this happens, your Macbook might turn off with 40-50% left or your battery capacity will drop significantly. However, this is only due to a disturbed battery calibration and not because of a faulty or degraded battery. To avoid this issue, we recommend doing at least one full cycle (0%-100%) every two weeks. Even if your battery calibration gets disturbed, doing 4+ full cycles will recalibrate your battery and the capacity will go up again.
## Support
* Most questions are already answered on our [FAQ page](https://apphousekitchen.com/faq/) or on our [blog](https://apphousekitchen.com/blog/). Check them out!
* E-mail support is only available for AlDente Pro customers. Check out our [support page](https://apphousekitchen.com/support/) if you want to contact us.
* Due to limited recourses, we are not able providing support to AlDente Free users or here in Github.
## Other tools used in this project:
* <https://github.com/beltex/SMCKit>
* <https://github.com/sindresorhus/LaunchAtLogin>
* <https://github.com/andreyvit/create-dmg>
## Disclaimer:
I do not take any responsibility for any sort of damage in result of using this tool! Alltough this had no negative side effects for me, AlDente still taps in some very low level system functions that are not ment to be tampered with. Use it at your own risk!
I do not take any responsibility for any sort of damage in result of using this tool! Although this had no negative side effects for me and thousands of others, AlDente still taps in some very low level system functions that are not meant to be tampered with. Use it at your own risk!
Copyright(c) 2020 David Wernhart
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Copyright(c) 2021 AppHouseKitchen
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -9,10 +9,10 @@
<key>CFBundleName</key>
<string>com.davidwernhart.Helper</string>
<key>CFBundleVersion</key>
<string>4</string>
<string>10</string>
<key>SMAuthorizedClients</key>
<array>
<string>identifier &quot;com.davidwernhart.AlDente&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>
<string>identifier "com.davidwernhart.AlDente" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: david.wernhart96@gmail.com (GSDX9BQ584)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</array>
</dict>
</plist>

View File

@ -7,8 +7,15 @@
//
import Foundation
import IOKit.pwr_mgt
class HelperTool: NSObject, HelperToolProtocol {
final class HelperTool: NSObject, HelperToolProtocol {
static let instance = HelperTool()
var modifiedKeys: [String: UInt8] = [:]
var openAssertions: [IOPMAssertionID] = []
func getVersion(withReply reply: (String) -> Void) {
// let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString" as String) as? String ?? "(unknown version)"
// let build = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String ?? "(unknown build)"
@ -16,16 +23,15 @@ class HelperTool: NSObject, HelperToolProtocol {
reply(helperVersion)
}
func setSMCByte(key: String, value: UInt8){
func setSMCByte(key: String, value: UInt8) {
do {
try SMCKit.open()
} catch {
print(error)
exit(EX_UNAVAILABLE)
}
var key = SMCKit.getKey(key, type: DataTypes.UInt8)
let smcKey = SMCKit.getKey(key, type: DataTypes.UInt8)
let bytes: SMCBytes = (value, UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
@ -33,25 +39,88 @@ class HelperTool: NSObject, HelperToolProtocol {
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0))
do {
let status = try SMCKit.writeData(key,data: bytes)
} catch {
if(self.modifiedKeys[key] == nil){
readSMCByte(key: key) { (originalValue) in
self.modifiedKeys[key] = originalValue
_ = try? SMCKit.writeData(smcKey, data: bytes)
}
}
else{
_ = try? SMCKit.writeData(smcKey, data: bytes)
}
}
func readSMCByte(key: String, withReply reply: @escaping (UInt8) -> Void){
func readSMCByte(key: String, withReply reply: @escaping (UInt8) -> Void) {
do {
try SMCKit.open()
} catch {
print(error)
exit(EX_UNAVAILABLE)
}
var key = SMCKit.getKey(key, type: DataTypes.UInt8)
let smcKey = SMCKit.getKey(key, type: DataTypes.UInt8)
do {
let status = try SMCKit.readData(key).0
let status = try SMCKit.readData(smcKey).0
reply(status)
} catch {
reply(0)
}
}
func readSMCUInt32(key: String, withReply reply: @escaping (UInt32) -> Void) {
do {
try SMCKit.open()
} catch {
print(error)
exit(EX_UNAVAILABLE)
}
let smcKey = SMCKit.getKey(key, type: DataTypes.UInt32)
do {
let data = try SMCKit.readData(smcKey)
reply(UInt32(fromBytes: (data.0, data.1, data.2, data.3)))
} catch {
reply(0)
}
}
func createAssertion(assertion:String, withReply reply: @escaping (IOPMAssertionID) -> Void){
var assertionID : IOPMAssertionID = IOPMAssertionID(0)
let reason:CFString = "AlDente" as NSString
let cfAssertion:CFString = assertion as NSString
let success = IOPMAssertionCreateWithName(cfAssertion,
IOPMAssertionLevel(kIOPMAssertionLevelOn),
reason,
&assertionID)
if success == kIOReturnSuccess {
openAssertions.append(assertionID)
reply(assertionID)
}
else{
reply (UInt32(kCFNumberNaN))
}
}
func releaseAssertion(assertionID:IOPMAssertionID){
IOPMAssertionRelease(assertionID)
openAssertions.remove(at: openAssertions.firstIndex(of: assertionID)!)
}
func setResetVal(key:String, value: UInt8){
modifiedKeys[key]=value
}
func reset(){
for (key, value) in modifiedKeys{
setSMCByte(key: key, value: value)
}
for assertionID in openAssertions{
releaseAssertion(assertionID: assertionID)
}
modifiedKeys.removeAll()
openAssertions.removeAll()
}
}

View File

@ -26,6 +26,7 @@
import IOKit
import Foundation
import os
//------------------------------------------------------------------------------
// MARK: Type Aliases
@ -183,7 +184,8 @@ public struct SMCParamStruct {
public struct SMCKeyInfoData {
/// How many bytes written to SMCParamStruct.bytes
var dataSize: IOByteCount = 0
//var dataSize: IOByteCount = 0
var dataSize:UInt32 = 0
/// Type of data written to SMCParamStruct.bytes. This lets us know how
/// to interpret it (translate it to human readable)
@ -254,7 +256,7 @@ public struct SMCKey {
public struct DataType: Equatable {
let type: FourCharCode
let size: UInt32
let size: IOByteCount
}
public func ==(lhs: DataType, rhs: DataType) -> Bool {
@ -325,7 +327,7 @@ public struct SMCKit {
let outputStruct = try callDriver(&inputStruct)
return DataType(type: outputStruct.keyInfo.dataType,
size: outputStruct.keyInfo.dataSize)
size: IOByteCount(outputStruct.keyInfo.dataSize))
}
/// Get information about the key at index
@ -340,9 +342,9 @@ public struct SMCKit {
return outputStruct.key
}
public static func getKey(_ code:String,type:DataType) -> SMCKey{
let key = SMCKey(code: FourCharCode(fromString: code),info: type)
public static func getKey(_ code: String, type: DataType) -> SMCKey {
let key = SMCKey(code: FourCharCode(fromString: code), info: type)
return key
}
@ -351,7 +353,7 @@ public struct SMCKit {
var inputStruct = SMCParamStruct()
inputStruct.key = key.code
inputStruct.keyInfo.dataSize = UInt32(key.info.size)
inputStruct.keyInfo.dataSize = UInt32(IOByteCount(key.info.size))
inputStruct.data8 = SMCParamStruct.Selector.kSMCReadKey.rawValue
let outputStruct = try callDriver(&inputStruct)
@ -365,7 +367,7 @@ public struct SMCKit {
inputStruct.key = key.code
inputStruct.bytes = data
inputStruct.keyInfo.dataSize = UInt32(key.info.size)
inputStruct.keyInfo.dataSize = UInt32(IOByteCount(key.info.size))
inputStruct.data8 = SMCParamStruct.Selector.kSMCWriteKey.rawValue
_ = try callDriver(&inputStruct)
@ -375,6 +377,7 @@ public struct SMCKit {
public static func callDriver(_ inputStruct: inout SMCParamStruct,
selector: SMCParamStruct.Selector = .kSMCHandleYPCEvent)
throws -> SMCParamStruct {
os_log("SMCPARAMSTRUCT SIZE: %d", MemoryLayout<SMCParamStruct>.stride)
assert(MemoryLayout<SMCParamStruct>.stride == 80, "SMCParamStruct size is != 80")
var outputStruct = SMCParamStruct()
@ -528,35 +531,35 @@ public struct TemperatureSensors {
public static let THUNDERBOLT_1 = TemperatureSensor(name: "THUNDERBOLT_1",
code: FourCharCode(fromStaticString: "TI1P"))
public static let all = [AMBIENT_AIR_0.code : AMBIENT_AIR_0,
AMBIENT_AIR_1.code : AMBIENT_AIR_1,
CPU_0_DIE.code : CPU_0_DIE,
CPU_0_DIODE.code : CPU_0_DIODE,
CPU_0_HEATSINK.code : CPU_0_HEATSINK,
CPU_0_PROXIMITY.code : CPU_0_PROXIMITY,
ENCLOSURE_BASE_0.code : ENCLOSURE_BASE_0,
ENCLOSURE_BASE_1.code : ENCLOSURE_BASE_1,
ENCLOSURE_BASE_2.code : ENCLOSURE_BASE_2,
ENCLOSURE_BASE_3.code : ENCLOSURE_BASE_3,
GPU_0_DIODE.code : GPU_0_DIODE,
GPU_0_HEATSINK.code : GPU_0_HEATSINK,
GPU_0_PROXIMITY.code : GPU_0_PROXIMITY,
HDD_PROXIMITY.code : HDD_PROXIMITY,
HEATSINK_0.code : HEATSINK_0,
HEATSINK_1.code : HEATSINK_1,
HEATSINK_2.code : HEATSINK_2,
MEM_SLOT_0.code : MEM_SLOT_0,
public static let all = [AMBIENT_AIR_0.code: AMBIENT_AIR_0,
AMBIENT_AIR_1.code: AMBIENT_AIR_1,
CPU_0_DIE.code: CPU_0_DIE,
CPU_0_DIODE.code: CPU_0_DIODE,
CPU_0_HEATSINK.code: CPU_0_HEATSINK,
CPU_0_PROXIMITY.code: CPU_0_PROXIMITY,
ENCLOSURE_BASE_0.code: ENCLOSURE_BASE_0,
ENCLOSURE_BASE_1.code: ENCLOSURE_BASE_1,
ENCLOSURE_BASE_2.code: ENCLOSURE_BASE_2,
ENCLOSURE_BASE_3.code: ENCLOSURE_BASE_3,
GPU_0_DIODE.code: GPU_0_DIODE,
GPU_0_HEATSINK.code: GPU_0_HEATSINK,
GPU_0_PROXIMITY.code: GPU_0_PROXIMITY,
HDD_PROXIMITY.code: HDD_PROXIMITY,
HEATSINK_0.code: HEATSINK_0,
HEATSINK_1.code: HEATSINK_1,
HEATSINK_2.code: HEATSINK_2,
MEM_SLOT_0.code: MEM_SLOT_0,
MEM_SLOTS_PROXIMITY.code: MEM_SLOTS_PROXIMITY,
PALM_REST.code : PALM_REST,
LCD_PROXIMITY.code : LCD_PROXIMITY,
MISC_PROXIMITY.code : MISC_PROXIMITY,
NORTHBRIDGE.code : NORTHBRIDGE,
NORTHBRIDGE_DIODE.code : NORTHBRIDGE_DIODE,
NORTHBRIDGE_PROXIMITY.code : NORTHBRIDGE_PROXIMITY,
ODD_PROXIMITY.code : ODD_PROXIMITY,
PWR_SUPPLY_PROXIMITY.code : PWR_SUPPLY_PROXIMITY,
THUNDERBOLT_0.code : THUNDERBOLT_0,
THUNDERBOLT_1.code : THUNDERBOLT_1]
PALM_REST.code: PALM_REST,
LCD_PROXIMITY.code: LCD_PROXIMITY,
MISC_PROXIMITY.code: MISC_PROXIMITY,
NORTHBRIDGE.code: NORTHBRIDGE,
NORTHBRIDGE_DIODE.code: NORTHBRIDGE_DIODE,
NORTHBRIDGE_PROXIMITY.code: NORTHBRIDGE_PROXIMITY,
ODD_PROXIMITY.code: ODD_PROXIMITY,
PWR_SUPPLY_PROXIMITY.code: PWR_SUPPLY_PROXIMITY,
THUNDERBOLT_0.code: THUNDERBOLT_0,
THUNDERBOLT_1.code: THUNDERBOLT_1]
}
public struct TemperatureSensor {

View File

@ -7,11 +7,12 @@
//
import Foundation
import AppKit
class HelperDelegate: NSObject, NSXPCListenerDelegate {
final class HelperDelegate: NSObject, NSXPCListenerDelegate {
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
newConnection.exportedInterface = NSXPCInterface(with: HelperToolProtocol.self)
newConnection.exportedObject = HelperTool()
newConnection.exportedObject = HelperTool.instance
newConnection.resume()
return true
}
@ -21,5 +22,23 @@ let delegate = HelperDelegate()
let listener = NSXPCListener(machServiceName: "com.davidwernhart.Helper.mach")
listener.delegate = delegate
listener.resume()
var hasChecked = false
Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { timer in
let workspace = NSWorkspace.shared
let applications = workspace.runningApplications
var foundApp = false
for app in applications {
if(app.bundleIdentifier?.elementsEqual("com.davidwernhart.AlDente") == true){
foundApp = true
}
}
if(foundApp && hasChecked){
hasChecked = false
}
else if(!foundApp && !hasChecked){
hasChecked = true
HelperTool.instance.reset()
exit(0)
}
}
RunLoop.current.run()