Fix DDC reliability on latest Xcode versions, migrate to SPM, more fixes (#453)

This commit is contained in:
Joni Van Roost 2021-06-15 21:55:53 +02:00 committed by GitHub
parent 58eec85aaa
commit 1c611b0012
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 1070 additions and 1065 deletions

BIN
.github/menuadvanced.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 259 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Before After
Before After

BIN
.github/menukeys.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

BIN
.github/menulet.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Before After
Before After

View file

@ -3,9 +3,9 @@ disabled_rules:
- function_body_length
- identifier_name
- trailing_comma
excluded:
- Carthage
type_body_length: 500
file_length: 500
cyclomatic_complexity:
ignores_case_statements: true
ignores_case_statements: true
opening_brace:
allow_multiline_func: true

View file

@ -1,4 +0,0 @@
github "the0neyouseek/MediaKeyTap" "master"
github "reitermarkus/DDC.swift" "master"
github "rnine/AMCoreAudio"
github "shpakovski/MASPreferences"

View file

@ -1,4 +0,0 @@
github "reitermarkus/DDC.swift" "1763870c94c555ff93878caaec8235fd3a9a429d"
github "rnine/AMCoreAudio" "3.4.0"
github "shpakovski/MASPreferences" "1.3"
github "the0neyouseek/MediaKeyTap" "8f85086b22178a243af7ea062711148415f5dc5c"

View file

@ -3,27 +3,14 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
2894D9B82280B30500DF58DA /* CGDirectDisplayID+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2894D9B72280B30500DF58DA /* CGDirectDisplayID+Extension.swift */; };
28D1DDD8227FB7A4004CB494 /* OSD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F0A987D61F77B290009B603D /* OSD.framework */; };
28D1DDE5227FB7D0004CB494 /* MediaKeyTap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D1DDE2227FB7D0004CB494 /* MediaKeyTap.framework */; };
28D1DDE6227FB7D0004CB494 /* MediaKeyTap.framework in [Carthage] Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 28D1DDE2227FB7D0004CB494 /* MediaKeyTap.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
28D1DDE7227FB7D0004CB494 /* AMCoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D1DDE3227FB7D0004CB494 /* AMCoreAudio.framework */; };
28D1DDE8227FB7D0004CB494 /* AMCoreAudio.framework in [Carthage] Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 28D1DDE3227FB7D0004CB494 /* AMCoreAudio.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
28D1DDE9227FB7D0004CB494 /* MASPreferences.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D1DDE4227FB7D0004CB494 /* MASPreferences.framework */; };
28D1DDEA227FB7D0004CB494 /* MASPreferences.framework in [Carthage] Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 28D1DDE4227FB7D0004CB494 /* MASPreferences.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
28D1DDEE227FB944004CB494 /* DDC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D1DDED227FB944004CB494 /* DDC.framework */; };
28D1DDEF227FB944004CB494 /* DDC.framework in [Carthage] Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 28D1DDED227FB944004CB494 /* DDC.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
28D1DDF0227FBD99004CB494 /* EDID+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D1DDEC227FB8F2004CB494 /* EDID+Extension.swift */; };
28D1DDF2227FBE71004CB494 /* NSScreen+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D1DDF1227FBE71004CB494 /* NSScreen+Extension.swift */; };
28D1DDF3227FC8C6004CB494 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 56754EB01D9A4016007BCDC5 /* Assets.xcassets */; };
28D1DE12227FD006004CB494 /* MASPreferences.framework.dSYM in [Carthage] Copy Framework Debug Symbols */ = {isa = PBXBuildFile; fileRef = 28D1DE0E227FD005004CB494 /* MASPreferences.framework.dSYM */; };
28D1DE13227FD006004CB494 /* MediaKeyTap.framework.dSYM in [Carthage] Copy Framework Debug Symbols */ = {isa = PBXBuildFile; fileRef = 28D1DE0F227FD006004CB494 /* MediaKeyTap.framework.dSYM */; };
28D1DE14227FD006004CB494 /* AMCoreAudio.framework.dSYM in [Carthage] Copy Framework Debug Symbols */ = {isa = PBXBuildFile; fileRef = 28D1DE10227FD006004CB494 /* AMCoreAudio.framework.dSYM */; };
28D1DE15227FD006004CB494 /* DDC.framework.dSYM in [Carthage] Copy Framework Debug Symbols */ = {isa = PBXBuildFile; fileRef = 28D1DE11227FD006004CB494 /* DDC.framework.dSYM */; };
56754EAF1D9A4016007BCDC5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56754EAE1D9A4016007BCDC5 /* AppDelegate.swift */; };
56754EB11D9A4016007BCDC5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 56754EB01D9A4016007BCDC5 /* Assets.xcassets */; };
6C0CCB26228F4F720037D2C5 /* AdvancedPrefsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0CCB25228F4F720037D2C5 /* AdvancedPrefsViewController.swift */; };
@ -34,15 +21,21 @@
6C85EFDD22CBAA8F00227EA1 /* PollingModeCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C85EFDC22CBAA8F00227EA1 /* PollingModeCellView.swift */; };
6C85EFDF22CBB54100227EA1 /* PollingCountCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C85EFDE22CBB54100227EA1 /* PollingCountCellView.swift */; };
6C85EFE122CC00AD00227EA1 /* NSNotification+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C85EFE022CC00AD00227EA1 /* NSNotification+Extension.swift */; };
6CB2B64B263EDA6600F0E0EF /* OSD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F0A987D61F77B290009B603D /* OSD.framework */; };
6CBFE27A23DB266000D1BC41 /* Display.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBFE27923DB266000D1BC41 /* Display.swift */; };
6CBFE27C23DB27A200D1BC41 /* InternalDisplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBFE27B23DB27A200D1BC41 /* InternalDisplay.swift */; };
6CC260F6256AD8F900613714 /* Preferences+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CC260F5256AD8F900613714 /* Preferences+Extension.swift */; };
6CCB278622D5315200619B05 /* HideOsdCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CCB278522D5315200619B05 /* HideOsdCellView.swift */; };
6CD35F53264FFFC6001F1344 /* SimplyCoreAudio in Frameworks */ = {isa = PBXBuildFile; productRef = 6CD35F52264FFFC6001F1344 /* SimplyCoreAudio */; };
6CD35F5626500008001F1344 /* MediaKeyTap in Frameworks */ = {isa = PBXBuildFile; productRef = 6CD35F5526500008001F1344 /* MediaKeyTap */; };
6CD35F592650002E001F1344 /* DDC in Frameworks */ = {isa = PBXBuildFile; productRef = 6CD35F582650002E001F1344 /* DDC */; };
6CD35F5C2650003F001F1344 /* Preferences in Frameworks */ = {isa = PBXBuildFile; productRef = 6CD35F5B2650003F001F1344 /* Preferences */; };
6CD444C322D4FBB8005BFD3D /* LongerDelayCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD444C222D4FBB8005BFD3D /* LongerDelayCellView.swift */; };
6CDA0FCF26485A8300F52125 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CDA0FCD26485A8300F52125 /* Main.storyboard */; };
F01B0699228221B7008E64DB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F01B0680228221B6008E64DB /* Localizable.strings */; };
F01B069A228221B7008E64DB /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = F01B0683228221B6008E64DB /* Utils.swift */; };
F01B069E228221B7008E64DB /* ButtonCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F01B068E228221B6008E64DB /* ButtonCellView.swift */; };
F01B069F228221B7008E64DB /* SliderHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F01B068F228221B7008E64DB /* SliderHandler.swift */; };
F01B06A0228221B7008E64DB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F01B0690228221B7008E64DB /* Main.storyboard */; };
F01B06A1228221B7008E64DB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F01B0692228221B7008E64DB /* MainMenu.xib */; };
F03A8DF21FFBAA6F0034DC27 /* ExternalDisplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = F03A8DF11FFBAA6F0034DC27 /* ExternalDisplay.swift */; };
F03FE4C0228DF62B001F59A4 /* FriendlyNameCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F03FE4BF228DF62A001F59A4 /* FriendlyNameCellView.swift */; };
@ -55,34 +48,6 @@
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
28D1DDBE227FB668004CB494 /* [Carthage] Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
28D1DDE8227FB7D0004CB494 /* AMCoreAudio.framework in [Carthage] Embed Frameworks */,
28D1DDEF227FB944004CB494 /* DDC.framework in [Carthage] Embed Frameworks */,
28D1DDEA227FB7D0004CB494 /* MASPreferences.framework in [Carthage] Embed Frameworks */,
28D1DDE6227FB7D0004CB494 /* MediaKeyTap.framework in [Carthage] Embed Frameworks */,
);
name = "[Carthage] Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
28D1DE0B227FCF99004CB494 /* [Carthage] Copy Framework Debug Symbols */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 16;
files = (
28D1DE14227FD006004CB494 /* AMCoreAudio.framework.dSYM in [Carthage] Copy Framework Debug Symbols */,
28D1DE15227FD006004CB494 /* DDC.framework.dSYM in [Carthage] Copy Framework Debug Symbols */,
28D1DE12227FD006004CB494 /* MASPreferences.framework.dSYM in [Carthage] Copy Framework Debug Symbols */,
28D1DE13227FD006004CB494 /* MediaKeyTap.framework.dSYM in [Carthage] Copy Framework Debug Symbols */,
);
name = "[Carthage] Copy Framework Debug Symbols";
runOnlyForDeploymentPostprocessing = 0;
};
F06792F5200A73FA0066C438 /* [Login] Copy Helper to start at Login */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -98,7 +63,6 @@
/* Begin PBXFileReference section */
1E7ECF3F22A4552400E4E701 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = "<group>"; };
1E7ECF4022A4552B00E4E701 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Main.strings; sourceTree = "<group>"; };
1E7ECF4122A4553000E4E701 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/MainMenu.strings; sourceTree = "<group>"; };
2894D9B72280B30500DF58DA /* CGDirectDisplayID+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGDirectDisplayID+Extension.swift"; sourceTree = "<group>"; };
28D1DDE2227FB7D0004CB494 /* MediaKeyTap.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaKeyTap.framework; path = Carthage/Build/Mac/MediaKeyTap.framework; sourceTree = "<group>"; };
@ -111,13 +75,10 @@
28D1DE0F227FD006004CB494 /* MediaKeyTap.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = MediaKeyTap.framework.dSYM; path = Carthage/Build/Mac/MediaKeyTap.framework.dSYM; sourceTree = "<group>"; };
28D1DE10227FD006004CB494 /* AMCoreAudio.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = AMCoreAudio.framework.dSYM; path = Carthage/Build/Mac/AMCoreAudio.framework.dSYM; sourceTree = "<group>"; };
28D1DE11227FD006004CB494 /* DDC.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = DDC.framework.dSYM; path = Carthage/Build/Mac/DDC.framework.dSYM; sourceTree = "<group>"; };
2EAA5B7D24BF9E9A00937821 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Main.strings; sourceTree = "<group>"; };
2EAA5B7E24BF9E9A00937821 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/MainMenu.strings; sourceTree = "<group>"; };
2EAA5B7F24BF9E9A00937821 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
3CCA5F952442EFF800B4DB84 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = "<group>"; };
3CCA5F962442EFF800B4DB84 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/MainMenu.strings; sourceTree = "<group>"; };
3CCA5F972442EFF800B4DB84 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
47A9F59F22ACAFBE00F649BB /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = "<group>"; };
47A9F5A022ACAFBE00F649BB /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; sourceTree = "<group>"; };
47A9F5A122ACAFBE00F649BB /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
56754EAB1D9A4016007BCDC5 /* MonitorControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MonitorControl.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -131,15 +92,26 @@
6C85EFDC22CBAA8F00227EA1 /* PollingModeCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollingModeCellView.swift; sourceTree = "<group>"; };
6C85EFDE22CBB54100227EA1 /* PollingCountCellView.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = PollingCountCellView.swift; sourceTree = "<group>"; tabWidth = 4; };
6C85EFE022CC00AD00227EA1 /* NSNotification+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSNotification+Extension.swift"; sourceTree = "<group>"; };
6CAD134E23624CC1009BD53F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Main.strings; sourceTree = "<group>"; };
6CAD134F23624CC1009BD53F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/MainMenu.strings; sourceTree = "<group>"; };
6CAD135023624CC1009BD53F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
6CBFE27923DB266000D1BC41 /* Display.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Display.swift; sourceTree = "<group>"; };
6CBFE27B23DB27A200D1BC41 /* InternalDisplay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InternalDisplay.swift; sourceTree = "<group>"; };
6CC260F5256AD8F900613714 /* Preferences+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Preferences+Extension.swift"; sourceTree = "<group>"; };
6CC260F9256ADA7400613714 /* Preferences.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Preferences.framework; path = Carthage/Build/Mac/Preferences.framework; sourceTree = "<group>"; };
6CCB278522D5315200619B05 /* HideOsdCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideOsdCellView.swift; sourceTree = "<group>"; };
6CD444C222D4FBB8005BFD3D /* LongerDelayCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongerDelayCellView.swift; sourceTree = "<group>"; };
6CDA0FCB26485A7600F52125 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = MonitorControl/UI/Base.lproj/Main.storyboard; sourceTree = SOURCE_ROOT; };
6CDA0FCE26485A8300F52125 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
6CDA0FD026485AA100F52125 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = "<group>"; };
6CDA0FD126485AA300F52125 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = "<group>"; };
6CDA0FD226485AA700F52125 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Main.strings; sourceTree = "<group>"; };
6CDA0FD326485AA900F52125 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = "<group>"; };
6CDA0FD426485AAA00F52125 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Main.strings; sourceTree = "<group>"; };
6CDA0FD526485AAB00F52125 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = "<group>"; };
6CDA0FD626485AAC00F52125 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Main.strings; sourceTree = "<group>"; };
6CDA0FD726485AAC00F52125 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Main.strings; sourceTree = "<group>"; };
6CDA0FD826485AAE00F52125 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Main.strings; sourceTree = "<group>"; };
B0C4810623357CE500053F91 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
B0C4810723357CE500053F91 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Main.strings; sourceTree = "<group>"; };
B0C4810823357CE500053F91 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MainMenu.strings; sourceTree = "<group>"; };
F01B0681228221B6008E64DB /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
F01B0682228221B6008E64DB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -149,14 +121,10 @@
F01B0686228221B6008E64DB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F01B068E228221B6008E64DB /* ButtonCellView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonCellView.swift; sourceTree = "<group>"; };
F01B068F228221B7008E64DB /* SliderHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderHandler.swift; sourceTree = "<group>"; };
F01B0691228221B7008E64DB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
F01B0693228221B7008E64DB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
F01B06A222822208008E64DB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
F01B06A32282220A008E64DB /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/MainMenu.strings; sourceTree = "<group>"; };
F01B06A42282220D008E64DB /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/MainMenu.strings; sourceTree = "<group>"; };
F01B06A522822215008E64DB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = "<group>"; };
F01B06A622822217008E64DB /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Main.strings; sourceTree = "<group>"; };
F01B06A72282221B008E64DB /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = "<group>"; };
F03A8DF11FFBAA6F0034DC27 /* ExternalDisplay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalDisplay.swift; sourceTree = "<group>"; };
F03FE4BF228DF62A001F59A4 /* FriendlyNameCellView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FriendlyNameCellView.swift; sourceTree = "<group>"; };
F0445D3720023E710025AE82 /* MainPrefsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainPrefsViewController.swift; sourceTree = "<group>"; };
@ -175,11 +143,11 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
28D1DDE7227FB7D0004CB494 /* AMCoreAudio.framework in Frameworks */,
28D1DDEE227FB944004CB494 /* DDC.framework in Frameworks */,
28D1DDE9227FB7D0004CB494 /* MASPreferences.framework in Frameworks */,
28D1DDE5227FB7D0004CB494 /* MediaKeyTap.framework in Frameworks */,
28D1DDD8227FB7A4004CB494 /* OSD.framework in Frameworks */,
6CD35F53264FFFC6001F1344 /* SimplyCoreAudio in Frameworks */,
6CD35F5626500008001F1344 /* MediaKeyTap in Frameworks */,
6CB2B64B263EDA6600F0E0EF /* OSD.framework in Frameworks */,
6CD35F592650002E001F1344 /* DDC in Frameworks */,
6CD35F5C2650003F001F1344 /* Preferences in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -196,6 +164,7 @@
28D1DDD1227FB759004CB494 /* Frameworks */ = {
isa = PBXGroup;
children = (
6CC260F9256ADA7400613714 /* Preferences.framework */,
28D1DDE3227FB7D0004CB494 /* AMCoreAudio.framework */,
28D1DE10227FD006004CB494 /* AMCoreAudio.framework.dSYM */,
28D1DDED227FB944004CB494 /* DDC.framework */,
@ -217,6 +186,7 @@
28D1DDF1227FBE71004CB494 /* NSScreen+Extension.swift */,
6C85EFE022CC00AD00227EA1 /* NSNotification+Extension.swift */,
6C20466B23153E4F00859767 /* Display+Extension.swift */,
6CC260F5256AD8F900613714 /* Preferences+Extension.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -278,6 +248,7 @@
6C85EFDB22CBA77600227EA1 /* Cells */ = {
isa = PBXGroup;
children = (
6CDA0FCA26485A7600F52125 /* Main.storyboard */,
F03FE4BF228DF62A001F59A4 /* FriendlyNameCellView.swift */,
F01B068E228221B6008E64DB /* ButtonCellView.swift */,
6C85EFDC22CBAA8F00227EA1 /* PollingModeCellView.swift */,
@ -305,7 +276,7 @@
isa = PBXGroup;
children = (
6C85EFDB22CBA77600227EA1 /* Cells */,
F01B0690228221B7008E64DB /* Main.storyboard */,
6CDA0FCD26485A8300F52125 /* Main.storyboard */,
F01B0692228221B7008E64DB /* MainMenu.xib */,
F01B068F228221B7008E64DB /* SliderHandler.swift */,
);
@ -347,14 +318,18 @@
56754EA81D9A4016007BCDC5 /* Frameworks */,
56754EA91D9A4016007BCDC5 /* Resources */,
F06792F5200A73FA0066C438 /* [Login] Copy Helper to start at Login */,
28D1DDBE227FB668004CB494 /* [Carthage] Embed Frameworks */,
28D1DE0B227FCF99004CB494 /* [Carthage] Copy Framework Debug Symbols */,
);
buildRules = (
);
dependencies = (
);
name = MonitorControl;
packageProductDependencies = (
6CD35F52264FFFC6001F1344 /* SimplyCoreAudio */,
6CD35F5526500008001F1344 /* MediaKeyTap */,
6CD35F582650002E001F1344 /* DDC */,
6CD35F5B2650003F001F1344 /* Preferences */,
);
productName = MonitorControl.OSX;
productReference = 56754EAB1D9A4016007BCDC5 /* MonitorControl.app */;
productType = "com.apple.product-type.application";
@ -385,8 +360,8 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = "Guillaume Broder";
LastUpgradeCheck = 1250;
ORGANIZATIONNAME = MonitorControl;
TargetAttributes = {
56754EAA1D9A4016007BCDC5 = {
CreatedOnToolsVersion = 8.0;
@ -419,6 +394,12 @@
pl,
);
mainGroup = 56754EA21D9A4016007BCDC5;
packageReferences = (
6CD35F51264FFFC6001F1344 /* XCRemoteSwiftPackageReference "SimplyCoreAudio" */,
6CD35F5426500008001F1344 /* XCRemoteSwiftPackageReference "MediaKeyTap" */,
6CD35F572650002E001F1344 /* XCRemoteSwiftPackageReference "DDC" */,
6CD35F5A2650003F001F1344 /* XCRemoteSwiftPackageReference "Preferences" */,
);
productRefGroup = 56754EAC1D9A4016007BCDC5 /* Products */;
projectDirPath = "";
projectRoot = "";
@ -435,8 +416,8 @@
buildActionMask = 2147483647;
files = (
56754EB11D9A4016007BCDC5 /* Assets.xcassets in Resources */,
6CDA0FCF26485A8300F52125 /* Main.storyboard in Resources */,
F01B0699228221B7008E64DB /* Localizable.strings in Resources */,
F01B06A0228221B7008E64DB /* Main.storyboard in Resources */,
F01B06A1228221B7008E64DB /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -553,6 +534,7 @@
6C2EA1CD228F644B00060E3F /* OnlyIntegerValueFormatter.swift in Sources */,
2894D9B82280B30500DF58DA /* CGDirectDisplayID+Extension.swift in Sources */,
6CCB278622D5315200619B05 /* HideOsdCellView.swift in Sources */,
6CC260F6256AD8F900613714 /* Preferences+Extension.swift in Sources */,
6CD444C322D4FBB8005BFD3D /* LongerDelayCellView.swift in Sources */,
F03FE4C0228DF62B001F59A4 /* FriendlyNameCellView.swift in Sources */,
6C2EA1CF228F7DFB00060E3F /* PollingMode.swift in Sources */,
@ -584,6 +566,31 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
6CDA0FCA26485A7600F52125 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
6CDA0FCB26485A7600F52125 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
6CDA0FCD26485A8300F52125 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
6CDA0FCE26485A8300F52125 /* Base */,
6CDA0FD026485AA100F52125 /* en */,
6CDA0FD126485AA300F52125 /* zh-Hans */,
6CDA0FD226485AA700F52125 /* fr */,
6CDA0FD326485AA900F52125 /* de */,
6CDA0FD426485AAA00F52125 /* it */,
6CDA0FD526485AAB00F52125 /* ja */,
6CDA0FD626485AAC00F52125 /* pl */,
6CDA0FD726485AAC00F52125 /* ru */,
6CDA0FD826485AAE00F52125 /* uk */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
F01B0680228221B6008E64DB /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
@ -600,23 +607,6 @@
name = Localizable.strings;
sourceTree = "<group>";
};
F01B0690228221B7008E64DB /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
F01B0691228221B7008E64DB /* Base */,
F01B06A72282221B008E64DB /* de */,
F01B06A522822215008E64DB /* en */,
F01B06A622822217008E64DB /* fr */,
1E7ECF4022A4552B00E4E701 /* uk */,
47A9F59F22ACAFBE00F649BB /* zh-Hans */,
B0C4810723357CE500053F91 /* ru */,
6CAD134E23624CC1009BD53F /* it */,
3CCA5F952442EFF800B4DB84 /* ja */,
2EAA5B7D24BF9E9A00937821 /* pl */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
F01B0692228221B7008E64DB /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
@ -662,6 +652,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;
@ -722,6 +713,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;
@ -745,7 +737,8 @@
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
@ -759,14 +752,11 @@
CURRENT_PROJECT_VERSION = 631;
DEVELOPMENT_TEAM = CYC8C8R4K9;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
"$(PROJECT_DIR)/Carthage/Build",
"$(PROJECT_DIR)",
);
INFOPLIST_FILE = MonitorControl/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.1.0;
PRODUCT_BUNDLE_IDENTIFIER = me.guillaumeb.MonitorControl;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -786,14 +776,11 @@
CURRENT_PROJECT_VERSION = 631;
DEVELOPMENT_TEAM = CYC8C8R4K9;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
"$(PROJECT_DIR)/Carthage/Build",
"$(PROJECT_DIR)",
);
INFOPLIST_FILE = MonitorControl/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.1.0;
PRODUCT_BUNDLE_IDENTIFIER = me.guillaumeb.MonitorControl;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -819,7 +806,10 @@
ENABLE_HARDENED_RUNTIME = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = MonitorControlHelper/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.1.0;
PRODUCT_BUNDLE_IDENTIFIER = me.guillaumeb.MonitorControlHelper;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -844,7 +834,10 @@
ENABLE_HARDENED_RUNTIME = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = MonitorControlHelper/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.1.0;
PRODUCT_BUNDLE_IDENTIFIER = me.guillaumeb.MonitorControlHelper;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -884,6 +877,64 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
6CD35F51264FFFC6001F1344 /* XCRemoteSwiftPackageReference "SimplyCoreAudio" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/rnine/SimplyCoreAudio";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 4.0.1;
};
};
6CD35F5426500008001F1344 /* XCRemoteSwiftPackageReference "MediaKeyTap" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/MonitorControl/MediaKeyTap";
requirement = {
branch = master;
kind = branch;
};
};
6CD35F572650002E001F1344 /* XCRemoteSwiftPackageReference "DDC" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/reitermarkus/DDC.swift";
requirement = {
branch = master;
kind = branch;
};
};
6CD35F5A2650003F001F1344 /* XCRemoteSwiftPackageReference "Preferences" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sindresorhus/Preferences";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.3.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
6CD35F52264FFFC6001F1344 /* SimplyCoreAudio */ = {
isa = XCSwiftPackageProductDependency;
package = 6CD35F51264FFFC6001F1344 /* XCRemoteSwiftPackageReference "SimplyCoreAudio" */;
productName = SimplyCoreAudio;
};
6CD35F5526500008001F1344 /* MediaKeyTap */ = {
isa = XCSwiftPackageProductDependency;
package = 6CD35F5426500008001F1344 /* XCRemoteSwiftPackageReference "MediaKeyTap" */;
productName = MediaKeyTap;
};
6CD35F582650002E001F1344 /* DDC */ = {
isa = XCSwiftPackageProductDependency;
package = 6CD35F572650002E001F1344 /* XCRemoteSwiftPackageReference "DDC" */;
productName = DDC;
};
6CD35F5B2650003F001F1344 /* Preferences */ = {
isa = XCSwiftPackageProductDependency;
package = 6CD35F5A2650003F001F1344 /* XCRemoteSwiftPackageReference "Preferences" */;
productName = Preferences;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 56754EA31D9A4016007BCDC5 /* Project object */;
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1100"
LastUpgradeVersion = "1250"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -1,10 +1,10 @@
import AMCoreAudio
import Cocoa
import DDC
import Foundation
import MASPreferences
import MediaKeyTap
import os.log
import Preferences
import SimplyCoreAudio
var app: AppDelegate!
let prefs = UserDefaults.standard
@ -12,21 +12,35 @@ let prefs = UserDefaults.standard
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var statusMenu: NSMenu!
@IBOutlet var window: NSWindow!
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
var monitorItems: [NSMenuItem] = []
var mediaKeyTap: MediaKeyTap?
var prefsController: NSWindowController?
var keyRepeatTimers: [MediaKey: Timer] = [:]
let coreAudio = SimplyCoreAudio()
var accessibilityObserver: NSObjectProtocol!
lazy var preferencesWindowController: PreferencesWindowController = {
let storyboard = NSStoryboard(name: "Main", bundle: Bundle.main)
let mainPrefsVc = storyboard.instantiateController(withIdentifier: "MainPrefsVC") as? MainPrefsViewController
let keyPrefsVc = storyboard.instantiateController(withIdentifier: "KeysPrefsVC") as? KeysPrefsViewController
let displayPrefsVc = storyboard.instantiateController(withIdentifier: "DisplayPrefsVC") as? DisplayPrefsViewController
let advancedPrefsVc = storyboard.instantiateController(withIdentifier: "AdvancedPrefsVC") as? AdvancedPrefsViewController
return PreferencesWindowController(
preferencePanes: [
mainPrefsVc!,
keyPrefsVc!,
displayPrefsVc!,
advancedPrefsVc!,
],
animated: false // causes glitchy animations
)
}()
func applicationDidFinishLaunching(_: Notification) {
app = self
self.setupViewControllers()
self.subscribeEventListeners()
self.setDefaultPrefs()
self.updateMediaKeyTap()
@ -41,12 +55,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
NSApplication.shared.terminate(self)
}
@IBAction func prefsClicked(_ sender: AnyObject) {
if let prefsController = prefsController {
prefsController.showWindow(sender)
NSApp.activate(ignoringOtherApps: true)
prefsController.window?.makeKeyAndOrderFront(sender)
}
@IBAction func prefsClicked(_: AnyObject) {
self.preferencesWindowController.show()
}
/// Set the default prefs of the app
@ -151,21 +161,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}
private func setupViewControllers() {
let storyboard: NSStoryboard = NSStoryboard(name: "Main", bundle: Bundle.main)
let mainPrefsVc = storyboard.instantiateController(withIdentifier: "MainPrefsVC")
let keyPrefsVc = storyboard.instantiateController(withIdentifier: "KeysPrefsVC")
let displayPrefsVc = storyboard.instantiateController(withIdentifier: "DisplayPrefsVC")
let advancedPrefsVc = storyboard.instantiateController(withIdentifier: "AdvancedPrefsVC")
let views = [
mainPrefsVc,
keyPrefsVc,
displayPrefsVc,
advancedPrefsVc,
]
prefsController = MASPreferencesWindowController(viewControllers: views, title: NSLocalizedString("Preferences", comment: "Shown in Preferences window"))
}
private func subscribeEventListeners() {
// subscribe KeyTap event listener
NotificationCenter.default.addObserver(self, selector: #selector(handleListenForChanged), name: .listenFor, object: nil)
@ -173,8 +168,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
NotificationCenter.default.addObserver(self, selector: #selector(handleFriendlyNameChanged), name: .friendlyName, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handlePreferenceReset), name: .preferenceReset, object: nil)
// subscribe Audio output detector (AMCoreAudio)
AMCoreAudio.NotificationCenter.defaultCenter.subscribe(self, eventType: AudioHardwareEvent.self, dispatchQueue: DispatchQueue.main)
// subscribe Audio output detector (SimplyCoreAudio)
NotificationCenter.default.addObserver(self, selector: #selector(audioDeviceChanged), name: Notification.Name.defaultOutputDeviceChanged, object: nil)
// listen for accessibility status changes
_ = DistributedNotificationCenter.default().addObserver(forName: .accessibilityApi, object: nil, queue: nil) { _ in
@ -322,11 +317,12 @@ extension AppDelegate: MediaKeyTapDelegate {
keys = [.brightnessUp, .brightnessDown, .mute, .volumeUp, .volumeDown]
}
if let audioDevice = AudioDevice.defaultOutputDevice(), audioDevice.canSetVirtualMasterVolume(direction: .playback) {
if self.coreAudio.defaultOutputDevice?.canSetVirtualMasterVolume(scope: .output) == true {
// Remove volume related keys.
let keysToDelete: [MediaKey] = [.volumeUp, .volumeDown, .mute]
keys.removeAll { keysToDelete.contains($0) }
}
self.mediaKeyTap?.stop()
// returning an empty array listens for all mediakeys in MediaKeyTap
if keys.count > 0 {
@ -334,17 +330,14 @@ extension AppDelegate: MediaKeyTapDelegate {
self.mediaKeyTap?.start()
}
}
}
extension AppDelegate: EventSubscriber {
/// Fires off when the default audio device changes.
func eventReceiver(_ event: Event) {
if case let .defaultOutputDeviceChanged(audioDevice)? = event as? AudioHardwareEvent {
#if DEBUG
os_log("Default output device changed to “%{public}@”.", type: .info, audioDevice.name)
os_log("Can device set its own volume? %{public}@", type: .info, audioDevice.canSetVirtualMasterVolume(direction: .playback).description)
#endif
self.updateMediaKeyTap()
}
@objc private func audioDeviceChanged() {
#if DEBUG
if let defaultDevice = self.coreAudio.defaultOutputDevice {
os_log("Default output device changed to “%{public}@”.", type: .info, defaultDevice.name)
os_log("Can device set its own volume? %{public}@", type: .info, defaultDevice.canSetVirtualMasterVolume(scope: .output).description)
}
#endif
self.updateMediaKeyTap()
}
}

View file

@ -1,15 +1,15 @@
import Cocoa
extension CGDirectDisplayID {
public var vendorNumber: UInt32? {
public extension CGDirectDisplayID {
var vendorNumber: UInt32? {
return CGDisplayVendorNumber(self)
}
public var modelNumber: UInt32? {
var modelNumber: UInt32? {
return CGDisplayModelNumber(self)
}
public var serialNumber: UInt32? {
var serialNumber: UInt32? {
return CGDisplaySerialNumber(self)
}
}

View file

@ -1,7 +1,7 @@
import DDC
extension EDID {
public func displayName() -> String? {
public extension EDID {
func displayName() -> String? {
let descriptors = [self.descriptors.0, self.descriptors.1, self.descriptors.2, self.descriptors.3]
for descriptor in descriptors {
@ -16,7 +16,7 @@ extension EDID {
return nil
}
public func serialNumber() -> String? {
func serialNumber() -> String? {
let descriptors = [self.descriptors.0, self.descriptors.1, self.descriptors.2, self.descriptors.3]
for descriptor in descriptors {

View file

@ -1,11 +1,11 @@
import Cocoa
extension NSScreen {
public var displayID: CGDirectDisplayID {
public extension NSScreen {
var displayID: CGDirectDisplayID {
return (self.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID)!
}
public var vendorNumber: UInt32? {
var vendorNumber: UInt32? {
switch self.displayID.vendorNumber {
case 0xFFFF_FFFF:
return nil
@ -14,7 +14,7 @@ extension NSScreen {
}
}
public var modelNumber: UInt32? {
var modelNumber: UInt32? {
switch self.displayID.modelNumber {
case 0xFFFF_FFFF:
return nil
@ -23,7 +23,7 @@ extension NSScreen {
}
}
public var serialNumber: UInt32? {
var serialNumber: UInt32? {
switch self.displayID.serialNumber {
case 0x0000_0000:
return nil
@ -32,7 +32,7 @@ extension NSScreen {
}
}
public var displayName: String? {
var displayName: String? {
var servicePortIterator = io_iterator_t()
let status = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IODisplayConnect"), &servicePortIterator)
@ -48,10 +48,12 @@ extension NSScreen {
let dict = (IODisplayCreateInfoDictionary(object, UInt32(kIODisplayOnlyPreferredName)).takeRetainedValue() as NSDictionary as? [String: AnyObject])!
if dict[kDisplayVendorID] as? UInt32 == self.vendorNumber,
dict[kDisplayProductID] as? UInt32 == self.modelNumber,
dict[kDisplaySerialNumber] as? UInt32 == self.serialNumber {
dict[kDisplayProductID] as? UInt32 == self.modelNumber,
dict[kDisplaySerialNumber] as? UInt32 == self.serialNumber
{
if let productName = dict["DisplayProductName"] as? [String: String],
let firstKey = Array(productName.keys).first {
let firstKey = Array(productName.keys).first
{
return productName[firstKey]!
}
}
@ -60,11 +62,11 @@ extension NSScreen {
return nil
}
public var isBuiltin: Bool {
var isBuiltin: Bool {
return CGDisplayIsBuiltin(self.displayID) != 0
}
public static func getByDisplayID(displayID: CGDirectDisplayID) -> NSScreen? {
static func getByDisplayID(displayID: CGDirectDisplayID) -> NSScreen? {
return NSScreen.screens.first { $0.displayID == displayID }
}
}

View file

@ -0,0 +1,16 @@
//
// Preferences+Extension.swift
// MonitorControl
//
// Created by Joni Van Roost on 22/11/2020.
// Copyright © 2020 MonitorControl. All rights reserved.
//
import Preferences
extension Preferences.PaneIdentifier {
static let main = Self("Main")
static let keys = Self("Keys")
static let advanced = Self("Advanced")
static let display = Self("Display")
}

View file

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>721</string>
<string>946</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>

View file

@ -22,7 +22,7 @@ class DisplayManager {
}
func getDdcCapableDisplays() -> [ExternalDisplay] {
return self.displays.compactMap { (display) -> ExternalDisplay? in
return self.displays.compactMap { display -> ExternalDisplay? in
if let externalDisplay = display as? ExternalDisplay, externalDisplay.ddc != nil {
return externalDisplay
} else { return nil }

View file

@ -3,7 +3,7 @@
// MonitorControl
//
// Created by Joni Van Roost on 24/01/2020.
// Copyright © 2020 Guillaume Broder. All rights reserved.
// Copyright © 2020 MonitorControl. All rights reserved.
//
import DDC

View file

@ -331,8 +331,9 @@ class ExternalDisplay: Display {
// Check if user has enabled "Play feedback when volume is changed" in Sound Preferences
guard let preferences = Utils.getSystemPreferences(),
let hasSoundEnabled = preferences["com.apple.sound.beep.feedback"] as? Int,
hasSoundEnabled == 1 else {
let hasSoundEnabled = preferences["com.apple.sound.beep.feedback"] as? Int,
hasSoundEnabled == 1
else {
os_log("sound not enabled", type: .info)
return
}

View file

@ -3,7 +3,7 @@
// MonitorControl
//
// Created by Joni Van Roost on 24/01/2020.
// Copyright © 2020 Guillaume Broder. All rights reserved.
// Copyright © 2020 MonitorControl. All rights reserved.
//
// Most of the code in this file was sourced from:
// https://github.com/fnesveda/ExternalDisplayBrightness

View file

@ -3,7 +3,7 @@
// MonitorControl
//
// Created by Victor Chabbert on 19/06/2020.
// Copyright © 2020 Guillaume Broder. All rights reserved.
// Copyright © 2020 MonitorControl. All rights reserved.
//
import Cocoa

View file

@ -104,7 +104,6 @@ class Utils: NSObject {
alert.alertStyle = .warning
alert.runModal()
}
return
}
static func readPrivileges(prompt: Bool) -> Bool {

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@ -36,5 +36,6 @@
</items>
<point key="canvasLocation" x="-1180" y="-1189"/>
</menu>
<sliderCell controlSize="small" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="above" sliderType="linear" id="JEl-jP-rdy"/>
</objects>
</document>

View file

@ -19,7 +19,8 @@ class FriendlyNameCellView: NSTableCellView {
}
if newValue != originalValue,
!newValue.isEmpty {
!newValue.isEmpty
{
display.setFriendlyName(newValue)
NotificationCenter.default.post(name: Notification.Name(Utils.PrefKeys.friendlyName.rawValue), object: nil)
#if DEBUG

View file

@ -14,7 +14,7 @@ class LongerDelayCellView: NSTableCellView {
if let display = self.display {
switch sender.state {
case .on:
let alert: NSAlert = NSAlert()
let alert = NSAlert()
alert.messageText = NSLocalizedString("Enable Longer Delay?", comment: "Shown in the alert dialog")
alert.informativeText = NSLocalizedString("Are you sure you want to enable a longer delay? Doing so may freeze your system and require a restart. Start at login will be disabled as a safety measure.", comment: "Shown in the alert dialog")
alert.addButton(withTitle: NSLocalizedString("Yes", comment: "Shown in the alert dialog"))

View file

@ -14,8 +14,9 @@ class PollingCountCellView: NSTableCellView {
}
if newValue != originalValue,
!newValue.isEmpty,
let newValue = Int(newValue) {
!newValue.isEmpty,
let newValue = Int(newValue)
{
display.setPollingCount(newValue)
os_log("Value changed for polling count: %{public}@", type: .info, "from `\(originalValue)` to `\(newValue)`")
}

View file

@ -4,9 +4,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "Einstellungen zurücksetzen";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "Erweitert";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "Aktiv";
@ -16,24 +13,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "Eigene";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "Tasten";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "ID";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "Anzeigename";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "Allgemein";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "Minimal";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "Monitor";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "Kontrast nach Helligkeit verringern";

View file

@ -4,9 +4,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "Reset Preferences";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "Advanced";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "Enabled";
@ -16,24 +13,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "Custom";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "Keys";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "ID";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "Display Name";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "General";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "Minimal";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "Display";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "Lower contrast after brightness";

View file

@ -4,9 +4,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "Reset Preferences";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "Advanced";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "Activé";
@ -16,24 +13,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "Custom";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "Touches";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "Identifiant";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "Display Name";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "Général";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "Minimal";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "Écrans";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "Diminuer le contraste après la luminosité";

View file

@ -4,9 +4,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "Reset Preferences";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "Advanced";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "Abilitato";
@ -16,24 +13,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "Custom";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "Tasti";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "ID";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "Display Name";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "Generale";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "Minimal";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "Monitor";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "Abbassa il contrasto dopo la luminosità";

View file

@ -7,9 +7,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "初期設定に戻す";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "詳細設定";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "有効";
@ -25,24 +22,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "カスタム";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "キー";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "ID";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "ディスプレイの名称";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "一般";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "低頻度";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "ディスプレイ";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "画面輝度変更後、コントラストを下げる";

View file

@ -4,9 +4,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "Resetowanie ustawień";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "Zaawansowane";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "Aktywne";
@ -19,24 +16,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "Niestandardowy";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "Klawisze";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "ID";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "Nazwa wyświetlacza";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "Ogólne";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "Minimalny";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "Wyświetlacz";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "Obniż kontrast po jasności.";

View file

@ -4,9 +4,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "Сброс настроек";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "Дополнительные";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "Включено";
@ -16,24 +13,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "Другое";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "Сочетания клавиш";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "ID";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "Название монитора";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "Основные";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "Редко";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "Мониторы";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "Уменьшать контрастность после яркости";

View file

@ -4,9 +4,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "Відновлення налаштувань";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "Розширені";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "Актив.";
@ -16,24 +13,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "Власне";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "Клавіші";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "ID";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "Назва дісплею";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "Загальне";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "Мінім.";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "Дісплеї";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "Зменшувати Контраст після Яскравості";

View file

@ -4,9 +4,6 @@
/* Class = "NSButtonCell"; title = "Reset Preferences"; ObjectID = "4Pj-3t-PJr"; */
"4Pj-3t-PJr.title" = "重置偏好设置";
/* Class = "NSTextFieldCell"; title = "Advanced"; ObjectID = "5wk-Dy-0fG"; */
"5wk-Dy-0fG.title" = "进阶设置";
/* Class = "NSTableColumn"; headerCell.title = "Enabled"; ObjectID = "8U8-ec-Zbv"; */
"8U8-ec-Zbv.headerCell.title" = "启用";
@ -16,24 +13,15 @@
/* Class = "NSMenuItem"; title = "Custom"; ObjectID = "Cle-DD-vR7"; */
"Cle-DD-vR7.title" = "自定义";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "快捷键";
/* Class = "NSTableColumn"; headerCell.title = "ID"; ObjectID = "dgp-q7-cBK"; */
"dgp-q7-cBK.headerCell.title" = "ID";
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "dNl-I0-hcg"; */
"dNl-I0-hcg.headerCell.title" = "显示器名字";
/* Class = "NSTextFieldCell"; title = "General"; ObjectID = "ENU-js-huy"; */
"ENU-js-huy.title" = "通用";
/* Class = "NSMenuItem"; title = "Minimal"; ObjectID = "Eq3-z9-yIo"; */
"Eq3-z9-yIo.title" = "少量";
/* Class = "NSTextFieldCell"; title = "Display"; ObjectID = "ExD-7P-6XI"; */
"ExD-7P-6XI.title" = "显示器";
/* Class = "NSButtonCell"; title = "Lower Contrast after Brightness"; ObjectID = "fhy-Er-0aI"; */
"fhy-Er-0aI.title" = "对比度与亮度同时降低";

View file

@ -1,12 +1,21 @@
import Cocoa
import DDC
import MASPreferences
import os.log
import Preferences
class AdvancedPrefsViewController: NSViewController, PreferencePane, NSTableViewDataSource, NSTableViewDelegate {
var preferencePaneIdentifier = Preferences.PaneIdentifier.advanced
var preferencePaneTitle: String = NSLocalizedString("Advanced", comment: "Shown in the main prefs window")
var toolbarItemIcon: NSImage {
if #available(macOS 11.0, *) {
return NSImage(systemSymbolName: "gearshape", accessibilityDescription: "Advanced")!
} else {
// Fallback on earlier versions
return NSImage(named: NSImage.advancedName)!
}
}
class AdvancedPrefsViewController: NSViewController, MASPreferencesViewController, NSTableViewDataSource, NSTableViewDelegate {
var viewIdentifier: String = "Advanced"
var toolbarItemLabel: String? = NSLocalizedString("Advanced", comment: "Shown in the main prefs window")
var toolbarItemImage: NSImage? = NSImage(named: NSImage.advancedName)
let prefs = UserDefaults.standard
var displays: [ExternalDisplay] = []
@ -33,7 +42,7 @@ class AdvancedPrefsViewController: NSViewController, MASPreferencesViewControlle
}
@IBAction func resetPrefsClicked(_: NSButton) {
let alert: NSAlert = NSAlert()
let alert = NSAlert()
alert.messageText = NSLocalizedString("Reset Preferences?", comment: "Shown in the alert dialog")
alert.informativeText = NSLocalizedString("Are you sure you want to reset all preferences?", comment: "Shown in the alert dialog")
alert.addButton(withTitle: NSLocalizedString("Yes", comment: "Shown in the alert dialog"))
@ -70,8 +79,9 @@ class AdvancedPrefsViewController: NSViewController, MASPreferencesViewControlle
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
guard let tableColumn = tableColumn,
let columnIndex = tableView.tableColumns.firstIndex(of: tableColumn),
let column = DisplayColumn(rawValue: columnIndex) else {
let columnIndex = tableView.tableColumns.firstIndex(of: tableColumn),
let column = DisplayColumn(rawValue: columnIndex)
else {
return nil
}
let display = self.displays[row]

View file

@ -1,12 +1,21 @@
import Cocoa
import DDC
import MASPreferences
import os.log
import Preferences
class DisplayPrefsViewController: NSViewController, PreferencePane, NSTableViewDataSource, NSTableViewDelegate {
var preferencePaneIdentifier = Preferences.PaneIdentifier.display
var preferencePaneTitle: String = NSLocalizedString("Display", comment: "Shown in the main prefs window")
var toolbarItemIcon: NSImage {
if #available(macOS 11.0, *) {
return NSImage(systemSymbolName: "display", accessibilityDescription: "Display")!
} else {
// Fallback on earlier versions
return NSImage(named: NSImage.computerName)!
}
}
class DisplayPrefsViewController: NSViewController, MASPreferencesViewController, NSTableViewDataSource, NSTableViewDelegate {
var viewIdentifier: String = "Display"
var toolbarItemLabel: String? = NSLocalizedString("Display", comment: "Shown in the main prefs window")
var toolbarItemImage: NSImage? = NSImage(named: NSImage.computerName)
let prefs = UserDefaults.standard
var displays: [Display] = []
@ -68,8 +77,9 @@ class DisplayPrefsViewController: NSViewController, MASPreferencesViewController
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
guard let tableColumn = tableColumn,
let columnIndex = tableView.tableColumns.firstIndex(of: tableColumn),
let column = DisplayColumn(rawValue: columnIndex) else {
let columnIndex = tableView.tableColumns.firstIndex(of: tableColumn),
let column = DisplayColumn(rawValue: columnIndex)
else {
return nil
}
let display = self.displays[row]

View file

@ -1,11 +1,20 @@
import Cocoa
import MASPreferences
import os.log
import Preferences
class KeysPrefsViewController: NSViewController, PreferencePane {
var preferencePaneIdentifier = Preferences.PaneIdentifier.keys
var preferencePaneTitle: String = NSLocalizedString("Keys", comment: "Shown in the main prefs window")
var toolbarItemIcon: NSImage {
if #available(macOS 11.0, *) {
return NSImage(systemSymbolName: "keyboard", accessibilityDescription: "Keys")!
} else {
// Fallback on earlier versions
return NSImage(named: "KeyboardPref")!
}
}
class KeysPrefsViewController: NSViewController, MASPreferencesViewController {
var viewIdentifier: String = "Keys"
var toolbarItemLabel: String? = NSLocalizedString("Keys", comment: "Shown in the main prefs window")
var toolbarItemImage: NSImage? = NSImage(named: "KeyboardPref")
let prefs = UserDefaults.standard
@IBOutlet var listenFor: NSPopUpButton!

View file

@ -1,12 +1,21 @@
import Cocoa
import MASPreferences
import os.log
import Preferences
import ServiceManagement
class MainPrefsViewController: NSViewController, MASPreferencesViewController {
var viewIdentifier: String = "Main"
var toolbarItemLabel: String? = NSLocalizedString("General", comment: "Shown in the main prefs window")
var toolbarItemImage: NSImage? = NSImage(named: NSImage.preferencesGeneralName)
class MainPrefsViewController: NSViewController, PreferencePane {
let preferencePaneIdentifier = Preferences.PaneIdentifier.main
let preferencePaneTitle: String = NSLocalizedString("General", comment: "Shown in the main prefs window")
var toolbarItemIcon: NSImage {
if #available(macOS 11.0, *) {
return NSImage(systemSymbolName: "switch.2", accessibilityDescription: "Display")!
} else {
// Fallback on earlier versions
return NSImage(named: NSImage.preferencesGeneralName)!
}
}
let prefs = UserDefaults.standard
@IBOutlet var versionLabel: NSTextField!

View file

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>721</string>
<string>946</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSBackgroundOnly</key>

View file

@ -37,13 +37,15 @@ Control your external monitor brightness, contrast or volume directly from a men
<br/>
<div align="center">
<img src="./.github/menulet.png" alt="menulet screenshot"/>
<img src="./.github/menulet.png" width="200" alt="menulet screenshot"/>
<br/><br/>
<img src="./.github/menugeneral.png" width="299" alt="general screenshot"/><img src="./.github/menukeys.png" width="299" alt="keys screenshot"/><img src="./.github/menudisplay.png" width="299" alt="display screenshot"/>
<img src="./.github/menugeneral.png" width="299" alt="general screenshot"/><img src="./.github/menukeys.png" width="299" alt="keys screenshot"/>
<img src="./.github/menudisplay.png" width="299" alt="display screenshot"/>
<img src="./.github/menuadvanced.png" width="299" alt="advanced screenshot"/>
<br/>
*Bonus: Using keyboard keys displays the native osd*
_Bonus: Using keyboard keys displays the native osd_
<img src="./.github/osd.jpg" width="500" align="center" alt="osd screenshot"/>
</div>
@ -69,39 +71,42 @@ Open [issues](https://github.com/MonitorControl/MonitorControl/issues) if you ha
### Required
- Xcode
- [Carthage](https://github.com/Carthage/Carthage)
- [Swiftlint](https://github.com/realm/SwiftLint)
- [SwiftFormat](https://github.com/nicklockwood/SwiftFormat)
- [BartyCrouch](https://github.com/Flinesoft/BartyCrouch) (for updating localizations)
Clone the project
```sh
$ git clone https://github.com/MonitorControl/MonitorControl.git
```
Then download the dependencies with Carthage
```sh
$ carthage bootstrap --platform macOS
git clone https://github.com/MonitorControl/MonitorControl.git
```
Then dependencies will automatically get downloaded when opening the project, if they don't:
`File > Swift Packages > Resolve Package Versions`
You're all set ! Now open the `MonitorControl.xcodeproj` with Xcode
### Third party dependencies
- [MediaKeyTap](https://github.com/the0neyouseek/MediaKeyTap)
- [MASPreferences](https://github.com/shpakovski/MASPreferences)
- [MediaKeyTap](https://github.com/MonitorControl/MediaKeyTap)
- [Preferences](https://github.com/sindresorhus/Preferences)
- [DDC.swift](https://github.com/reitermarkus/DDC.swift)
- [AMCoreAudio](https://github.com/rnine/AMCoreAudio)
- [SimplyCoreAudio](https://github.com/rnine/SimplyCoreAudio)
## Support
- macOS Sierra (`10.12`) and up.
- Works with monitors controllable via [DDC](https://en.wikipedia.org/wiki/Display_Data_Channel).
## Contributors
- [@the0neyouseek](https://github.com/the0neyouseek)
- [@reitermarkus](https://github.com/reitermarkus)
- [@JoniVR](https://github.com/JoniVR)
## Thanks
- [@bluejamesbond](https://github.com/bluejamesbond/) (Original developer)
- [@Tyilo](https://github.com/Tyilo/) (Fork)
- [@Bensge](https://github.com/Bensge/) - (Used some code from his project [NativeDisplayBrightness](https://github.com/Bensge/NativeDisplayBrightness))