Skip to content

Commit 6e91c71

Browse files
reitermarkusthe0neyouseek
authored andcommitted
Various Enhancements (#66)
* Update to Swift 5.0 and run `swiftformat`. * Refactor `MediaKeyTap` start/restart. * Remove useless comments. * Reorder files. * Add German translation. * Switch to Carthage. * Use `DDC.swift`. * Add `NSScreen` extension. * Simplify menu layout. * Hide the display’s built-in OSD. * Fix launch at login helper. * Fix `quitClicked` connection. * Refactor build phases. * Use `os_log` instead of `print`. * Use more specific check for `minReplyDelay`. * Add whitelist.
1 parent 830878e commit 6e91c71

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1275
-1367
lines changed

.gitignore

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,3 @@
1+
Carthage
12

2-
# Created by https://www.gitignore.io/api/macos,xcode,cocoapods
3-
4-
### CocoaPods ###
5-
## CocoaPods GitIgnore Template
6-
7-
# CocoaPods - Only use to conserve bandwidth / Save time on Pushing
8-
# - Also handy if you have a large number of dependant pods
9-
# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE
10-
Pods/
11-
12-
### macOS ###
13-
*.DS_Store
14-
.AppleDouble
15-
.LSOverride
16-
17-
# Icon must end with two \r
18-
Icon
19-
20-
# Thumbnails
21-
._*
22-
23-
# Files that might appear in the root of a volume
24-
.DocumentRevisions-V100
25-
.fseventsd
26-
.Spotlight-V100
27-
.TemporaryItems
28-
.Trashes
29-
.VolumeIcon.icns
30-
.com.apple.timemachine.donotpresent
31-
32-
# Directories potentially created on remote AFP share
33-
.AppleDB
34-
.AppleDesktop
35-
Network Trash Folder
36-
Temporary Items
37-
.apdisk
38-
39-
### Xcode ###
40-
# Xcode
41-
#
42-
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
43-
44-
## Build generated
45-
build/
46-
DerivedData/
47-
48-
## Various settings
49-
*.pbxuser
50-
!default.pbxuser
51-
*.mode1v3
52-
!default.mode1v3
53-
*.mode2v3
54-
!default.mode2v3
55-
*.perspectivev3
56-
!default.perspectivev3
57-
xcuserdata/
58-
59-
## Other
60-
*.moved-aside
61-
*.xccheckout
62-
*.xcscmblueprint
63-
64-
### Xcode Patch ###
65-
*.xcodeproj/*
66-
!*.xcodeproj/project.pbxproj
67-
!*.xcodeproj/xcshareddata/
68-
!*.xcworkspace/contents.xcworkspacedata
69-
/*.gcno
3+
*.xcuserdatad

.gitmodules

Lines changed: 0 additions & 3 deletions
This file was deleted.

.swift-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5.0

.swiftformat

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
--indent 2
2+
--ranges no-space
3+
--self insert
4+
--exponentcase lowercase
5+
--exclude Carthage

.swiftlint.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ disabled_rules:
22
- line_length
33
- function_body_length
44
- identifier_name
5+
- trailing_comma
56
excluded:
6-
- Pods
7+
- Carthage
78
type_body_length: 500
89
file_length: 500

Cartfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github "the0neyouseek/MediaKeyTap" "master"
2+
github "reitermarkus/DDC.swift" "master"
3+
github "rnine/AMCoreAudio"
4+
github "shpakovski/MASPreferences"

Cartfile.resolved

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github "reitermarkus/DDC.swift" "9a6a249b4b222e67b1393eecd7ac9eb35dff34a9"
2+
github "rnine/AMCoreAudio" "3.2.1"
3+
github "shpakovski/MASPreferences" "1.3"
4+
github "the0neyouseek/MediaKeyTap" "abfe09f53ccabb1aa14a0f4ab99cfb8812f41919"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Cocoa
2+
3+
extension CGDirectDisplayID {
4+
public var vendorNumber: UInt32? {
5+
return CGDisplayVendorNumber(self)
6+
}
7+
8+
public var modelNumber: UInt32? {
9+
return CGDisplayModelNumber(self)
10+
}
11+
12+
public var serialNumber: UInt32? {
13+
return CGDisplaySerialNumber(self)
14+
}
15+
}

Extensions/EDID+Extension.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import DDC
2+
3+
extension EDID {
4+
public func displayName() -> String? {
5+
let descriptors = [self.descriptors.0, self.descriptors.1, self.descriptors.2, self.descriptors.3]
6+
7+
for descriptor in descriptors {
8+
switch descriptor {
9+
case let .displayName(name):
10+
return name
11+
default:
12+
continue
13+
}
14+
}
15+
16+
return nil
17+
}
18+
19+
public func serialNumber() -> String? {
20+
let descriptors = [self.descriptors.0, self.descriptors.1, self.descriptors.2, self.descriptors.3]
21+
22+
for descriptor in descriptors {
23+
switch descriptor {
24+
case let .serialNumber(number):
25+
return number
26+
default:
27+
continue
28+
}
29+
}
30+
31+
return String(self.serialNumber)
32+
}
33+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import Cocoa
2+
3+
extension NSScreen {
4+
public var displayID: CGDirectDisplayID {
5+
return (self.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID)!
6+
}
7+
8+
public var vendorNumber: UInt32? {
9+
switch self.displayID.vendorNumber {
10+
case 0xFFFF_FFFF:
11+
return nil
12+
case let vendorNumber:
13+
return vendorNumber
14+
}
15+
}
16+
17+
public var modelNumber: UInt32? {
18+
switch self.displayID.modelNumber {
19+
case 0xFFFF_FFFF:
20+
return nil
21+
case let modelNumber:
22+
return modelNumber
23+
}
24+
}
25+
26+
public var serialNumber: UInt32? {
27+
switch self.displayID.serialNumber {
28+
case 0x0000_0000:
29+
return nil
30+
case let serialNumber:
31+
return serialNumber
32+
}
33+
}
34+
35+
public var displayName: String? {
36+
var servicePortIterator = io_iterator_t()
37+
38+
let status = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IODisplayConnect"), &servicePortIterator)
39+
guard status == KERN_SUCCESS else {
40+
return nil
41+
}
42+
43+
defer {
44+
assert(IOObjectRelease(servicePortIterator) == KERN_SUCCESS)
45+
}
46+
47+
while case let object = IOIteratorNext(servicePortIterator), object != 0 {
48+
let dict = (IODisplayCreateInfoDictionary(object, UInt32(kIODisplayOnlyPreferredName)).takeRetainedValue() as NSDictionary as? [String: AnyObject])!
49+
50+
if dict[kDisplayVendorID] as? UInt32 == self.vendorNumber,
51+
dict[kDisplayProductID] as? UInt32 == self.modelNumber,
52+
dict[kDisplaySerialNumber] as? UInt32 == self.serialNumber {
53+
if let productName = dict["DisplayProductName"] as? [String: String],
54+
let firstKey = Array(productName.keys).first {
55+
return productName[firstKey]!
56+
}
57+
}
58+
}
59+
60+
return nil
61+
}
62+
63+
public var isBuiltin: Bool {
64+
return CGDisplayIsBuiltin(self.displayID) != 0
65+
}
66+
67+
public static func getByDisplayID(displayID: CGDirectDisplayID) -> NSScreen? {
68+
return NSScreen.screens.first { $0.displayID == displayID }
69+
}
70+
}

0 commit comments

Comments
 (0)