- Code rework
- Native OSD
- Change default shortcuts for problems with apps
- Codesign app

Signed-off-by: Guillaume Broder <iamnotheoneyouseek@gmail.com>
This commit is contained in:
Guillaume Broder 2017-09-24 15:25:46 +02:00
parent 38137e84e9
commit 036a29d4bc
No known key found for this signature in database
GPG key ID: 66FB02D063D9E08F
33 changed files with 689 additions and 158 deletions

BIN
.github/menulet.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
.github/osd.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

21
License.txt Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright © 2017
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,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:MonitorControl.OSX.xcodeproj">
</FileRef>
</Workspace>

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>SchemeUserState</key>
<dict>
<key>MonitorControl.OSX.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>56754EAA1D9A4016007BCDC5</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View file

@ -1,2 +0,0 @@
#import <Foundation/Foundation.h>
#include "../ddcctl/DDC.h"

View file

@ -12,6 +12,10 @@
56754EAF1D9A4016007BCDC5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56754EAE1D9A4016007BCDC5 /* AppDelegate.swift */; };
56754EB11D9A4016007BCDC5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 56754EB01D9A4016007BCDC5 /* Assets.xcassets */; };
56754EB41D9A4016007BCDC5 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56754EB21D9A4016007BCDC5 /* MainMenu.xib */; };
F091C9B31F6EA6110096FD65 /* SliderHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F091C9B21F6EA6110096FD65 /* SliderHandler.swift */; };
F091C9B81F6EA79B0096FD65 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = F091C9B71F6EA79B0096FD65 /* Utils.swift */; };
F0A987E81F77B40E009B603D /* OSD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F0A987D61F77B290009B603D /* OSD.framework */; };
F0EB972F1F6ED7C800686D2A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F091C9C11F6EB8660096FD65 /* Localizable.strings */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -21,12 +25,30 @@
55359E361E2737EC002671BC /* ddcctl.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ddcctl.sh; sourceTree = "<group>"; };
55359E371E2737EC002671BC /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
55359E381E2737EC002671BC /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
55359E3E1E27380B002671BC /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = "<group>"; };
56754EAB1D9A4016007BCDC5 /* MonitorControl.OSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MonitorControl.OSX.app; sourceTree = BUILT_PRODUCTS_DIR; };
56754EAE1D9A4016007BCDC5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
56754EAB1D9A4016007BCDC5 /* MonitorControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MonitorControl.app; sourceTree = BUILT_PRODUCTS_DIR; };
56754EAE1D9A4016007BCDC5 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AppDelegate.swift; sourceTree = "<group>"; };
56754EB01D9A4016007BCDC5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
56754EB31D9A4016007BCDC5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
56754EB51D9A4016007BCDC5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F091C9B21F6EA6110096FD65 /* SliderHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderHandler.swift; sourceTree = "<group>"; };
F091C9B71F6EA79B0096FD65 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
F091C9B91F6EB43B0096FD65 /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; lineEnding = 0; name = fr; path = fr.lproj/MainMenu.strings; sourceTree = "<group>"; };
F091C9C21F6EB8660096FD65 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; lineEnding = 0; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
F091C9C31F6EB8720096FD65 /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; lineEnding = 0; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
F091C9C41F6EBA5A0096FD65 /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = "<group>"; };
F0A987D51F77A823009B603D /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; lineEnding = 0; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
F0A987D61F77B290009B603D /* OSD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OSD.framework; sourceTree = "<group>"; };
F0A987DA1F77B404009B603D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
F0A987DC1F77B404009B603D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
F0A987DD1F77B404009B603D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F0A987DF1F77B404009B603D /* SliderHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderHandler.swift; sourceTree = "<group>"; };
F0A987E11F77B404009B603D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
F0A987E21F77B404009B603D /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
F0A987E31F77B404009B603D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/MainMenu.strings; sourceTree = "<group>"; };
F0A987E41F77B404009B603D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
F0A987E51F77B404009B603D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F0A987E61F77B404009B603D /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = "<group>"; };
F0A987E71F77B404009B603D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -34,6 +56,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F0A987E81F77B40E009B603D /* OSD.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -56,38 +79,83 @@
56754EA21D9A4016007BCDC5 = {
isa = PBXGroup;
children = (
56754EAD1D9A4016007BCDC5 /* MonitorControl.OSX */,
56754EAD1D9A4016007BCDC5 /* MonitorControl */,
F0A987D61F77B290009B603D /* OSD.framework */,
55359E321E2737EC002671BC /* ddcctl */,
56754EAC1D9A4016007BCDC5 /* Products */,
F0A987D71F77B404009B603D /* Frameworks */,
);
sourceTree = "<group>";
};
56754EAC1D9A4016007BCDC5 /* Products */ = {
isa = PBXGroup;
children = (
56754EAB1D9A4016007BCDC5 /* MonitorControl.OSX.app */,
56754EAB1D9A4016007BCDC5 /* MonitorControl.app */,
);
name = Products;
sourceTree = "<group>";
};
56754EAD1D9A4016007BCDC5 /* MonitorControl.OSX */ = {
56754EAD1D9A4016007BCDC5 /* MonitorControl */ = {
isa = PBXGroup;
children = (
56754EAE1D9A4016007BCDC5 /* AppDelegate.swift */,
F091C9B71F6EA79B0096FD65 /* Utils.swift */,
F091C9B41F6EA6180096FD65 /* Objects */,
F091C9C41F6EBA5A0096FD65 /* Bridging-Header.h */,
56754EB01D9A4016007BCDC5 /* Assets.xcassets */,
56754EB21D9A4016007BCDC5 /* MainMenu.xib */,
F091C9C11F6EB8660096FD65 /* Localizable.strings */,
56754EB51D9A4016007BCDC5 /* Info.plist */,
55359E3E1E27380B002671BC /* Bridging-Header.h */,
);
path = MonitorControl.OSX;
path = MonitorControl;
sourceTree = "<group>";
};
F091C9B41F6EA6180096FD65 /* Objects */ = {
isa = PBXGroup;
children = (
F091C9B21F6EA6110096FD65 /* SliderHandler.swift */,
);
path = Objects;
sourceTree = "<group>";
};
F0A987D71F77B404009B603D /* Frameworks */ = {
isa = PBXGroup;
children = (
F0A987D81F77B404009B603D /* MonitorControl */,
);
name = Frameworks;
sourceTree = "<group>";
};
F0A987D81F77B404009B603D /* MonitorControl */ = {
isa = PBXGroup;
children = (
F0A987D91F77B404009B603D /* MainMenu.strings */,
F0A987DB1F77B404009B603D /* Localizable.strings */,
F0A987DD1F77B404009B603D /* Assets.xcassets */,
F0A987DE1F77B404009B603D /* Objects */,
F0A987E01F77B404009B603D /* MainMenu.xib */,
F0A987E21F77B404009B603D /* Utils.swift */,
F0A987E51F77B404009B603D /* AppDelegate.swift */,
F0A987E61F77B404009B603D /* Bridging-Header.h */,
F0A987E71F77B404009B603D /* Info.plist */,
);
path = MonitorControl;
sourceTree = "<group>";
};
F0A987DE1F77B404009B603D /* Objects */ = {
isa = PBXGroup;
children = (
F0A987DF1F77B404009B603D /* SliderHandler.swift */,
);
path = Objects;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
56754EAA1D9A4016007BCDC5 /* MonitorControl.OSX */ = {
56754EAA1D9A4016007BCDC5 /* MonitorControl */ = {
isa = PBXNativeTarget;
buildConfigurationList = 56754EB81D9A4016007BCDC5 /* Build configuration list for PBXNativeTarget "MonitorControl.OSX" */;
buildConfigurationList = 56754EB81D9A4016007BCDC5 /* Build configuration list for PBXNativeTarget "MonitorControl" */;
buildPhases = (
56754EA71D9A4016007BCDC5 /* Sources */,
56754EA81D9A4016007BCDC5 /* Frameworks */,
@ -97,9 +165,9 @@
);
dependencies = (
);
name = MonitorControl.OSX;
name = MonitorControl;
productName = MonitorControl.OSX;
productReference = 56754EAB1D9A4016007BCDC5 /* MonitorControl.OSX.app */;
productReference = 56754EAB1D9A4016007BCDC5 /* MonitorControl.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@ -109,29 +177,31 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0800;
LastUpgradeCheck = 0820;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Mathew Kurian";
TargetAttributes = {
56754EAA1D9A4016007BCDC5 = {
CreatedOnToolsVersion = 8.0;
LastSwiftMigration = 0900;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 56754EA61D9A4016007BCDC5 /* Build configuration list for PBXProject "MonitorControl.OSX" */;
buildConfigurationList = 56754EA61D9A4016007BCDC5 /* Build configuration list for PBXProject "MonitorControl" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
fr,
);
mainGroup = 56754EA21D9A4016007BCDC5;
productRefGroup = 56754EAC1D9A4016007BCDC5 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
56754EAA1D9A4016007BCDC5 /* MonitorControl.OSX */,
56754EAA1D9A4016007BCDC5 /* MonitorControl */,
);
};
/* End PBXProject section */
@ -142,6 +212,7 @@
buildActionMask = 2147483647;
files = (
56754EB11D9A4016007BCDC5 /* Assets.xcassets in Resources */,
F0EB972F1F6ED7C800686D2A /* Localizable.strings in Resources */,
55359E3B1E2737EC002671BC /* ddcctl.sh in Resources */,
56754EB41D9A4016007BCDC5 /* MainMenu.xib in Resources */,
);
@ -154,8 +225,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F091C9B31F6EA6110096FD65 /* SliderHandler.swift in Sources */,
56754EAF1D9A4016007BCDC5 /* AppDelegate.swift in Sources */,
55359E391E2737EC002671BC /* DDC.c in Sources */,
F091C9B81F6EA79B0096FD65 /* Utils.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -166,6 +239,43 @@
isa = PBXVariantGroup;
children = (
56754EB31D9A4016007BCDC5 /* Base */,
F091C9B91F6EB43B0096FD65 /* fr */,
F0A987D51F77A823009B603D /* en */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
F091C9C11F6EB8660096FD65 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
F091C9C21F6EB8660096FD65 /* en */,
F091C9C31F6EB8720096FD65 /* fr */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
F0A987D91F77B404009B603D /* MainMenu.strings */ = {
isa = PBXVariantGroup;
children = (
F0A987DA1F77B404009B603D /* en */,
F0A987E31F77B404009B603D /* fr */,
);
name = MainMenu.strings;
sourceTree = "<group>";
};
F0A987DB1F77B404009B603D /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
F0A987DC1F77B404009B603D /* en */,
F0A987E41F77B404009B603D /* fr */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
F0A987E01F77B404009B603D /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
F0A987E11F77B404009B603D /* Base */,
);
name = MainMenu.xib;
sourceTree = "<group>";
@ -177,12 +287,15 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
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_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
@ -190,7 +303,11 @@
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_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_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
@ -200,6 +317,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/**";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@ -227,12 +345,15 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
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_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
@ -240,7 +361,11 @@
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_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_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
@ -250,6 +375,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/**";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -269,13 +395,18 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = MonitorControl.OSX/Info.plist;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/**";
INFOPLIST_FILE = "$(SRCROOT)/MonitorControl/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "bluejamesbond.MonitorControl-OSX";
PRODUCT_BUNDLE_IDENTIFIER = me.guillaumeb.MonitorControl;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "MonitorControl.OSX/Bridging-Header.h";
SWIFT_VERSION = 3.0;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "MonitorControl/Bridging-Header.h";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -283,20 +414,25 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = MonitorControl.OSX/Info.plist;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/**";
INFOPLIST_FILE = "$(SRCROOT)/MonitorControl/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "bluejamesbond.MonitorControl-OSX";
PRODUCT_BUNDLE_IDENTIFIER = me.guillaumeb.MonitorControl;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "MonitorControl.OSX/Bridging-Header.h";
SWIFT_VERSION = 3.0;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "MonitorControl/Bridging-Header.h";
SWIFT_VERSION = 4.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
56754EA61D9A4016007BCDC5 /* Build configuration list for PBXProject "MonitorControl.OSX" */ = {
56754EA61D9A4016007BCDC5 /* Build configuration list for PBXProject "MonitorControl" */ = {
isa = XCConfigurationList;
buildConfigurations = (
56754EB61D9A4016007BCDC5 /* Debug */,
@ -305,7 +441,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
56754EB81D9A4016007BCDC5 /* Build configuration list for PBXNativeTarget "MonitorControl.OSX" */ = {
56754EB81D9A4016007BCDC5 /* Build configuration list for PBXNativeTarget "MonitorControl" */ = {
isa = XCConfigurationList;
buildConfigurations = (
56754EB91D9A4016007BCDC5 /* Debug */,

View file

@ -1,9 +1,10 @@
//
// AppDelegate.swift
// MonitorControl.OSX
// MonitorControl
//
// Created by Mathew Kurian on 9/26/16.
// Copyright © 2016 Mathew Kurian. All rights reserved.
// Last edited by Guillaume Broder on 9/17/2017
// MIT Licensed. 2017.
//
import Cocoa
@ -18,47 +19,13 @@ struct Display {
var app: AppDelegate! = nil
let prefs = UserDefaults.standard
func ddcctl(monitor: CGDirectDisplayID, command: Int32, value: Int) {
var wrcmd = DDCWriteCommand(control_id: UInt8(command), new_value: UInt8(value))
DDCWrite(monitor, &wrcmd)
print(value)
}
class SliderHandler : NSObject {
var display : Display
var command : Int32 = 0
public init(display: Display, command: Int32) {
self.display = display
self.command = command
}
func valueChanged(slider: NSSlider) {
let snapInterval = 25
let snapThreshold = 3
var value = slider.integerValue
let closest = (value + snapInterval / 2) / snapInterval * snapInterval
if abs(closest - value) <= snapThreshold {
value = closest
slider.integerValue = value
}
ddcctl(monitor: display.id, command: command, value: value)
prefs.setValue(value, forKey: "\(command)-\(display.serial)")
prefs.synchronize()
}
}
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var statusMenu: NSMenu!
@IBOutlet weak var window: NSWindow!
let statusItem = NSStatusBar.system().statusItem(withLength: NSVariableStatusItemLength)
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
var monitorItems: [NSMenuItem] = []
var displays: [Display] = []
@ -68,14 +35,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
var defaultBrightnessSlider: NSSlider! = nil
var defaultVolumeSlider: NSSlider! = nil
let step = 100/16;
@IBAction func quitClicked(_ sender: AnyObject) {
NSApplication.shared().terminate(self)
NSApplication.shared.terminate(self)
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
app = self
statusItem.title = ""
statusItem.image = NSImage.init(named: NSImage.Name(rawValue: "status"))
statusItem.menu = statusMenu
acquirePrivileges()
@ -84,39 +53,63 @@ class AppDelegate: NSObject, NSApplicationDelegate {
updateDisplays()
NSEvent.addGlobalMonitorForEvents(
matching: NSEventMask.keyDown, handler: {(event: NSEvent) in
matching: NSEvent.EventTypeMask.keyDown, handler: {(event: NSEvent) in
if self.defaultDisplay == nil {
return
}
let modifiers = NSEventModifierFlags.init(rawValue: NSEventModifierFlags.command.rawValue |
NSEventModifierFlags.control.rawValue |
NSEventModifierFlags.option.rawValue |
NSEventModifierFlags.shift.rawValue)
var flags = event.modifierFlags.intersection(modifiers)
// Keyboard shortcut only for main screen
let currentDisplayId = NSScreen.main?.deviceDescription[NSDeviceDescriptionKey.init("NSScreenNumber")] as! CGDirectDisplayID
if (self.defaultDisplay.id != currentDisplayId) {
return
}
if !flags.contains(NSEventModifierFlags.command) {
return
}
flags.subtract(NSEventModifierFlags.command)
// Brightness -> Shift + Control + Alt + Command + (Up/Down)
// Volume -> Shift + Control + Alt + Command + (Left/Right)
// Mute -> Minus
var rel = 0
if event.keyCode == 27 {
rel = -5
} else if event.keyCode == 24 {
rel = +5
} else {
// Capture keys
let modifiers = NSEvent.ModifierFlags.init(rawValue: NSEvent.ModifierFlags.shift.rawValue | NSEvent.ModifierFlags.command.rawValue | NSEvent.ModifierFlags.control.rawValue | NSEvent.ModifierFlags.option.rawValue)
let flags = event.modifierFlags.intersection(modifiers)
// Only do something if all modifiers are active
if !flags.contains(NSEvent.ModifierFlags.shift) || !flags.contains(NSEvent.ModifierFlags.command) || !flags.contains(NSEvent.ModifierFlags.control) || !flags.contains(NSEvent.ModifierFlags.option) {
return
}
var brightnessRel = 0
var volumeRel = 0
var rel = 0
// Down key
if event.keyCode == Utils.key.keyDownArrow.rawValue {
brightnessRel = -self.step
// Up key
} else if event.keyCode == Utils.key.keyUpArrow.rawValue {
brightnessRel = +self.step
// Left key
} else if event.keyCode == Utils.key.keyLeftArrow.rawValue {
volumeRel = -self.step
// Right key
} else if event.keyCode == Utils.key.keyRightArrow.rawValue {
volumeRel = +self.step
// M key
} else if event.keyCode == Utils.key.keyMute.rawValue {
volumeRel = -100
} else {
return
}
var command = Int32()
var slider: NSSlider! = nil
if flags == NSEventModifierFlags.option {
if brightnessRel == 0 {
command = AUDIO_SPEAKER_VOLUME
slider = self.defaultVolumeSlider
} else if flags == NSEventModifierFlags.shift {
rel = volumeRel
} else if volumeRel == 0 {
command = BRIGHTNESS
slider = self.defaultBrightnessSlider
rel = brightnessRel
} else {
return
}
@ -128,30 +121,27 @@ class AppDelegate: NSObject, NSApplicationDelegate {
prefs.synchronize()
slider.intValue = Int32(value)
ddcctl(monitor: self.defaultDisplay.id, command: command, value: value)
Utils.ddcctl(monitor: self.defaultDisplay.id, command: command, value: value)
// OSD
let manager : OSDManager = OSDManager.sharedManager() as! OSDManager
var osdImage : Int = 1 // Brightness Image
if brightnessRel == 0 {
osdImage = 3 // Speaker image
if value == 0 {
osdImage = 4 // Mute speaker
}
}
manager.showImage(Int64(osdImage), onDisplayID: self.defaultDisplay.id, priority: 0x1f4, msecUntilFade: 2000, filledChiclets: UInt32(value/self.step), totalChiclets: UInt32(100/self.step), locked: false)
})
}
func makeLabel(text: String, frame: NSRect) -> NSTextField {
let label = NSTextField(frame: frame)
label.stringValue = text
label.isBordered = false
label.isBezeled = false
label.isEditable = false
label.drawsBackground = false
return label
}
func addSliderItem(menu: NSMenu, isDefaultDisplay: Bool, display: Display, command: Int32, title: String, shortcut: String) -> NSSlider {
func addSliderItem(menu: NSMenu, isDefaultDisplay: Bool, display: Display, command: Int32, title: String) -> NSSlider {
let item = NSMenuItem()
let view = NSView(frame: NSRect(x: 0, y: 5, width: 250, height: 40))
let label = makeLabel(text: title, frame: NSRect(x: 20, y: 19, width: 130, height: 20))
let labelKeyCode = makeLabel(text: shortcut, frame: NSRect(x: 120, y: 19, width: 100, height: 20))
labelKeyCode.isHidden = !isDefaultDisplay
labelKeyCode.alignment = NSTextAlignment.right
let label = Utils.makeLabel(text: title, frame: NSRect(x: 20, y: 19, width: 130, height: 20))
let handler = SliderHandler(display: display, command: command)
sliderHandlers.append(handler)
@ -161,14 +151,13 @@ class AppDelegate: NSObject, NSApplicationDelegate {
slider.minValue = 0
slider.maxValue = 100
slider.integerValue = prefs.integer(forKey: "\(command)-\(display.serial)")
slider.action = #selector(SliderHandler.valueChanged)
slider.action = #selector(SliderHandler.valueChanged)
view.addSubview(label)
view.addSubview(labelKeyCode)
view.addSubview(slider)
item.view = view
menu.addItem(item)
menu.addItem(NSMenuItem.separator())
@ -183,14 +172,15 @@ class AppDelegate: NSObject, NSApplicationDelegate {
for m in monitorItems {
statusMenu.removeItem(m)
}
monitorItems = []
displays = []
sliderHandlers = []
sleep(1)
for s in NSScreen.screens()! {
let id = s.deviceDescription["NSScreenNumber"] as! CGDirectDisplayID
for s in NSScreen.screens {
let id = s.deviceDescription[NSDeviceDescriptionKey.init("NSScreenNumber")] as! CGDirectDisplayID
if CGDisplayIsBuiltin(id) != 0 {
continue
}
@ -211,17 +201,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
let monitorMenuItem = NSMenuItem()
let monitorSubMenu = NSMenu()
let brightnessSlider = addSliderItem(menu: monitorSubMenu, isDefaultDisplay: isDefaultDisplay, display: d, command: BRIGHTNESS, title: "Brightness", shortcut: "⇧⌘- / ⇧⌘+")
let _ = addSliderItem(menu: monitorSubMenu, isDefaultDisplay: isDefaultDisplay, display: d, command: CONTRAST, title: "Contrast", shortcut: "")
let volumeSlider = addSliderItem(menu: monitorSubMenu, isDefaultDisplay: isDefaultDisplay, display: d, command: AUDIO_SPEAKER_VOLUME, title: "Volume", shortcut: "⌥⌘- / ⌥⌘+")
let brightnessSlider = addSliderItem(menu: monitorSubMenu, isDefaultDisplay: isDefaultDisplay, display: d, command: BRIGHTNESS, title: NSLocalizedString("Brightness", comment: "Sown in menu"))
let _ = addSliderItem(menu: monitorSubMenu, isDefaultDisplay: isDefaultDisplay, display: d, command: CONTRAST, title: NSLocalizedString("Contrast", comment: "Shown in menu"))
let volumeSlider = addSliderItem(menu: monitorSubMenu, isDefaultDisplay: isDefaultDisplay, display: d, command: AUDIO_SPEAKER_VOLUME, title: NSLocalizedString("Volume", comment: "Shown in menu"))
let defaultMonitorItem = NSMenuItem()
let defaultMonitorView = NSView(frame: NSRect(x: 0, y: 5, width: 250, height: 25))
let defaultMonitorSelectButtom = NSButton(frame: NSRect(x: 25, y: 0, width: 200, height: 25))
defaultMonitorSelectButtom.title = isDefaultDisplay ? "Default" : "Set as default"
defaultMonitorSelectButtom.bezelStyle = NSRoundRectBezelStyle
defaultMonitorSelectButtom.title = isDefaultDisplay ? NSLocalizedString("Default", comment: "Shown in menu") : NSLocalizedString("Set as default", comment: "Shown in menu")
defaultMonitorSelectButtom.bezelStyle = NSButton.BezelStyle.rounded
defaultMonitorSelectButtom.isEnabled = !isDefaultDisplay
defaultMonitorView.addSubview(defaultMonitorSelectButtom)
@ -246,19 +235,19 @@ class AppDelegate: NSObject, NSApplicationDelegate {
if defaultDisplay == nil {
// If no DDC capable display was detected
let item = NSMenuItem()
item.title = "No supported display found"
item.title = NSLocalizedString("No supported display found", comment: "Shown in menu")
item.isEnabled = false
monitorItems.append(item)
statusMenu.insertItem(item, at: 0)
}
}
func acquirePrivileges() {
let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true]
let accessibilityEnabled = AXIsProcessTrustedWithOptions(options)
if !accessibilityEnabled {
print("You need to enable the keylogger in the System Prefrences")
print(NSLocalizedString("You need to enable the keylogger in the System Prefrences for the keyboard shortcuts to work", comment: ""))
}
return
@ -293,10 +282,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
func getDisplayName(_ edid: EDID) -> String {
return getDescriptorString(edid, 0xFC) ?? "Display"
return getDescriptorString(edid, 0xFC) ?? NSLocalizedString("Display", comment: "")
}
func getDisplaySerial(_ edid: EDID) -> String {
return getDescriptorString(edid, 0xFF) ?? "Unknown"
return getDescriptorString(edid, 0xFF) ?? NSLocalizedString("Unknown", comment: "")
}
}

View file

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

View file

@ -0,0 +1,25 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "status.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "status@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13196" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@ -12,7 +12,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="LG_Monitor_Control_Menulet" customModuleProvider="target">
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="MonitorControl" customModuleProvider="target">
<connections>
<outlet property="quitClicked" destination="JTa-2I-AsI" id="pCf-S9-cfs"/>
<outlet property="statusMenu" destination="lCi-vw-mwp" id="iBf-iw-RcA"/>

View file

@ -0,0 +1,16 @@
//
// Bridging-Header.h
// MonitorControl
//
// Created by Guillaume BRODER on 17/09/2017.
// MIT Licensed. 2017.
//
#ifndef Bridging_Header_h
#define Bridging_Header_h
#import <Foundation/Foundation.h>
#include "../ddcctl/DDC.h"
#import <OSD/OSDManager.h>
#endif /* Bridging_Header_h */

View file

@ -20,15 +20,17 @@
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Mathew Kurian. All rights reserved.</string>
<string>MIT Licensed. 2017.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>LSUIElement</key>
<true/>
</dict>
</plist>

View file

@ -0,0 +1,37 @@
//
// SliderHandler.swift
// MonitorControl
//
// Created by Guillaume BRODER on 9/17/2017.
// MIT Licensed. 2017.
//
import Cocoa
class SliderHandler: NSObject {
var display : Display
var command : Int32 = 0
public init(display: Display, command: Int32) {
self.display = display
self.command = command
}
@objc func valueChanged(slider: NSSlider) {
let snapInterval = 25
let snapThreshold = 3
var value = slider.integerValue
let closest = (value + snapInterval / 2) / snapInterval * snapInterval
if abs(closest - value) <= snapThreshold {
value = closest
slider.integerValue = value
}
Utils.ddcctl(monitor: display.id, command: command, value: value)
prefs.setValue(value, forKey: "\(command)-\(display.serial)")
prefs.synchronize()
}
}

View file

@ -0,0 +1,55 @@
//
// Utils.swift
// MonitorControl
//
// Created by Guillaume BRODER on 9/17/2017.
// MIT Licensed.
//
import Cocoa
class Utils: NSObject {
/// Send command to ddcctl
///
/// - Parameters:
/// - monitor: The id of the Monitor to send the command to
/// - command: The command to send
/// - value: the value of the command
static func ddcctl(monitor: CGDirectDisplayID, command: Int32, value: Int) {
var wrcmd = DDCWriteCommand(control_id: UInt8(command), new_value: UInt8(value))
DDCWrite(monitor, &wrcmd)
print(value)
}
/// Create a label
///
/// - Parameters:
/// - text: The text of the label
/// - frame: The frame of the label
/// - Returns: An `NSTextField` label
static func makeLabel(text: String, frame: NSRect) -> NSTextField {
let label = NSTextField(frame: frame)
label.stringValue = text
label.isBordered = false
label.isBezeled = false
label.isEditable = false
label.drawsBackground = false
return label
}
/// Enum for hardware independent keyCode
///
/// - keyLeftArrow: keyCode for the left arrow
/// - keyRightArrow: keyCode for the right arrow
/// - keyDownArrow: keyCode for the down arrow
/// - keyUpArrow: keyCode for the up arrow
enum key : Int {
case keyLeftArrow = 123
case keyRightArrow = 124
case keyDownArrow = 125
case keyUpArrow = 126
case keyMute = 24
}
}

Binary file not shown.

View file

@ -0,0 +1,3 @@
/* Class = "NSMenuItem"; title = "Quit"; ObjectID = "JTa-2I-AsI"; */
"JTa-2I-AsI.title" = "Quit";

Binary file not shown.

View file

@ -0,0 +1,3 @@
/* Class = "NSMenuItem"; title = "Quit"; ObjectID = "JTa-2I-AsI"; */
"JTa-2I-AsI.title" = "Quitter";

View file

@ -0,0 +1,21 @@
#import "OSDUIHelperProtocol.h"
@class NSXPCConnection;
@interface OSDManager : NSObject <OSDUIHelperProtocol>
{
id <OSDUIHelperProtocol> _proxyObject;
NSXPCConnection *connection;
}
+ (id)sharedManager;
@property(retain) NSXPCConnection *connection; // @synthesize connection;
- (void)showFullScreenImage:(long long)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecToAnimate:(unsigned int)arg4;
- (void)fadeClassicImageOnDisplay:(unsigned int)arg1;
- (void)showImageAtPath:(id)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecUntilFade:(unsigned int)arg4 withText:(id)arg5;
- (void)showImage:(long long)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecUntilFade:(unsigned int)arg4 filledChiclets:(unsigned int)arg5 totalChiclets:(unsigned int)arg6 locked:(BOOL)arg7;
- (void)showImage:(long long)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecUntilFade:(unsigned int)arg4 withText:(id)arg5;
- (void)showImage:(long long)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecUntilFade:(unsigned int)arg4;
@property(readonly) id <OSDUIHelperProtocol> remoteObjectProxy; // @dynamic remoteObjectProxy;
@end

View file

@ -0,0 +1,11 @@
@class NSString;
@protocol OSDUIHelperProtocol
- (void)showFullScreenImage:(long long)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecToAnimate:(unsigned int)arg4;
- (void)fadeClassicImageOnDisplay:(unsigned int)arg1;
- (void)showImageAtPath:(NSString *)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecUntilFade:(unsigned int)arg4 withText:(NSString *)arg5;
- (void)showImage:(long long)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecUntilFade:(unsigned int)arg4 filledChiclets:(unsigned int)arg5 totalChiclets:(unsigned int)arg6 locked:(BOOL)arg7;
- (void)showImage:(long long)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecUntilFade:(unsigned int)arg4 withText:(NSString *)arg5;
- (void)showImage:(long long)arg1 onDisplayID:(unsigned int)arg2 priority:(unsigned int)arg3 msecUntilFade:(unsigned int)arg4;
@end

1
OSD.framework/OSD Symbolic link
View file

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

1
OSD.framework/Resources Symbolic link
View file

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

BIN
OSD.framework/Versions/A/OSD Executable file

Binary file not shown.

View file

@ -0,0 +1,46 @@
<?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>16B2657</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>OSD</string>
<key>CFBundleIdentifier</key>
<string>com.apple.OSD</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>OSD</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</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>9L173x</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>17A317</string>
<key>DTSDKName</key>
<string>macosx10.13internal</string>
<key>DTXcode</key>
<string>0900</string>
<key>DTXcodeBuild</key>
<string>9L173x</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015 Apple Inc. All rights reserved.</string>
</dict>
</plist>

View file

@ -0,0 +1,18 @@
<?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>BuildAliasOf</key>
<string>OSDFramework</string>
<key>BuildVersion</key>
<string>487</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>ProjectName</key>
<string>OSDFramework</string>
<key>SourceVersion</key>
<string>27000000000000</string>
</dict>
</plist>

View file

@ -0,0 +1,139 @@
<?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>files</key>
<dict>
<key>Resources/Info.plist</key>
<data>
bTy7OXKIr2tY7ToPw28ekz1xUXU=
</data>
<key>Resources/version.plist</key>
<data>
d0I/dBV8v16urCBanZt9RaZvG1E=
</data>
</dict>
<key>files2</key>
<dict>
<key>Resources/Info.plist</key>
<dict>
<key>hash2</key>
<data>
uEmRq0D23jBsIWK+0+UH3bCcn16eQdAwKWglrQbTfQc=
</data>
</dict>
<key>Resources/version.plist</key>
<dict>
<key>hash2</key>
<data>
f4xR2tymy1G7xEyxX1+yXJmSgOrrndsypu67avrQ8Ss=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View file

@ -0,0 +1 @@
A

1
OSD.framework/XPCServices Symbolic link
View file

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

View file

@ -1,10 +1,40 @@
# MonitorControl.OSX
A menu let to control your monitor (brightness, contrast, volume)
# MonitorControl
![image](https://cloud.githubusercontent.com/assets/376453/18903896/5a8ad950-8510-11e6-85d0-c95170a76fb8.png)
Control your external monitor brightness, contrast or volume directly from a menulet or with keyboard shortcuts :
Compatible with most Dell monitors and LG including 27UD68
- Brightness: `⇧` + `⌃` + `⌥` + `⌘` + `↑/↓` (Shift + Control + Alt + Command + Up/Down arrows)
- Volume: `⇧` + `⌃` + `⌥` + `⌘` + `←/→` (Shift + Control + Alt + Command + Left/Right arrows)
- Mute: `⇧` + `⌃` + `⌥` + `⌘` + `-` (Shift + Control + Alt + Command + Minus)
(Ps. The keyboard shortcut only work for the default screen)
![MonitorControl menulet](./.github/menulet.png)
## Download
Go to [Release](./) and download the latest `.dmg`
## Brightness/Volume default key
You can use [Karabiner Elements](https://github.com/tekezo/Karabiner-Elements/) to use the default mac key (`F1`, `F2` for brightness and `F10`, `F11`, `F12` for volume) with this set of custom rules : [Karabiner rules for MonitorControl](karabiner://karabiner/assets/complex_modifications/import?url=https%3A%2F%2Fraw.githubusercontent.com%2Fthe0neyouseek%2FMonitorControl%2Fmaster%2F.github%2Frules.json)
---
Powered by [@kfix/ddcctl](https://github.com/kfix/ddcctl)
Bonus: Using keyboard shortcuts display the native osd :
![MonitorControl OSD](./.github/osd.png)
## TODO
- [ ] Hande multiple screen for keyboard shortcut (Possibly the choice to have all screen brightness/volume increase/decrease at the same time or separatly)
- [ ] Skip Karabiner use for keyboard shortcut
- [ ] Option to start app at login
- [ ] Add [SwiftLint](https://github.com/realm/SwiftLint)
## Support
- macOS Sierra (`10.12`) and up.
- Works with monitors comptaible with [@kfix/ddcctl](https://github.com/kfix/ddcctl)
## Thanks
- @bluejamesbond (Original developer)
- @Tyilo (Fork)
- @Bensge - (Used some code from his project [NativeDisplayBrightness](https://github.com/Bensge/NativeDisplayBrightness))