Better handling of virtual displays (AirPlay, Sidecar) - these cannot be enabled and no DDC for them.

This commit is contained in:
waydabber 2021-08-01 18:39:37 +02:00
parent 00b4e936b3
commit d7ecf0112f
17 changed files with 100 additions and 27 deletions

View file

@ -128,11 +128,23 @@ class AppDelegate: NSObject, NSApplicationDelegate {
let vendorNumber = CGDisplayVendorNumber(onlineDisplayID)
let modelNumber = CGDisplayVendorNumber(onlineDisplayID)
let display: Display
if CGDisplayIsBuiltin(onlineDisplayID) != 0 {
display = InternalDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber)
} else {
display = ExternalDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber)
var isVirtual: Bool = false
if let dictionary = ((CoreDisplay_DisplayCreateInfoDictionary(onlineDisplayID))?.takeRetainedValue() as NSDictionary?) {
let isVirtualDevice = dictionary["kCGDisplayIsVirtualDevice"] as? Bool
let displayIsAirplay = dictionary["kCGDisplayIsAirPlay"] as? Bool
if isVirtualDevice ?? displayIsAirplay ?? false {
isVirtual = true
}
}
if CGDisplayIsBuiltin(onlineDisplayID) != 0 {
display = InternalDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual)
} else {
display = ExternalDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual)
}
DisplayManager.shared.addDisplay(display: display)
}
@ -290,7 +302,7 @@ extension AppDelegate: MediaKeyTapDelegate {
let delay = isRepeat ? 0.05 : 0
self.keyRepeatTimers[mediaKey] = Timer.scheduledTimer(withTimeInterval: delay, repeats: false, block: { _ in
for display in allDisplays where display.isEnabled {
for display in allDisplays where display.isEnabled && !display.isVirtual {
switch mediaKey {
case .brightnessUp, .brightnessDown:
display.stepBrightness(isUp: mediaKey == .brightnessUp, isSmallIncrement: isSmallIncrement)

View file

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

View file

@ -30,9 +30,11 @@ class Display {
}
}
var isVirtual: Bool = false
private let prefs = UserDefaults.standard
internal init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?) {
internal init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual _: Bool = false) {
self.identifier = identifier
self.name = name
self.vendorNumber = vendorNumber

View file

@ -38,33 +38,37 @@ class ExternalDisplay: Display {
private var audioPlayer: AVAudioPlayer?
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?) {
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual: Bool = false) {
super.init(identifier, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber)
#if arch(arm64)
if !isVirtual {
#if arch(arm64)
// MARK: Should implement proper display matching (this is currently needed for the M1 Mini's HDMI port only as all other M1 Macs support a single external display)
// MARK: Should implement proper display matching (this is currently needed for the M1 Mini's HDMI port only as all other M1 Macs support a single external display)
self.arm64avService = IOAVServiceCreate(kCFAllocatorDefault)?.takeRetainedValue() as IOAVService
self.arm64avService = IOAVServiceCreate(kCFAllocatorDefault)?.takeRetainedValue() as IOAVService
/* We don't need this check as some displays are incompatible with this. We always assume DDC capability.
/* We don't need this check as some displays are incompatible with this. We always assume DDC capability.
var send: [UInt8] = [0xF1]
var reply = [UInt8](repeating: 0, count: 11)
var send: [UInt8] = [0xF1]
var reply = [UInt8](repeating: 0, count: 11)
if arm64ddcComm(send: &send, reply: &reply) {
self.arm64ddc = true
}
if arm64ddcComm(send: &send, reply: &reply) {
self.arm64ddc = true
}
*/
*/
self.arm64ddc = true
self.arm64ddc = true
#else
#else
self.ddc = DDC(for: identifier)
self.ddc = DDC(for: identifier)
#endif
#endif
} else {
self.isVirtual = true
}
}
// On some displays, the display's OSD overlaps the macOS OSD,

View file

@ -15,7 +15,7 @@ class InternalDisplay: Display {
// the queue for dispatching display operations, so they're not performed directly and concurrently
private var displayQueue: DispatchQueue
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?) {
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual _: Bool = false) {
self.displayQueue = DispatchQueue(label: String("displayQueue-\(identifier)"))
super.init(identifier, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber)
}

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "Erweitert";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "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.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "Allgemein";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "Tasten";

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "Advanced";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "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.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "General";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "Keys";

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "Advanced";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "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.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "Général";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "Touches";

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "Advanced";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "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.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "Generale";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "Tasti";

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "詳細設定";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "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.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "一般";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "キー";

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "Zaawansowane";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "Czy na pewno chcesz ustawić większe opóźnienie? Może to skutkować zawieszeniem systemu i koniecznością restartu. Uruchamianie programu podczas logowania zostanie wyłączone.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "Ogólne";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "Klawisze";

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "Дополнительные";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "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.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "Основные";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "Сочетания клавиш";

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "Розширені";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "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.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "Загальні";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "Клавіші";

View file

@ -1,6 +1,9 @@
/* Shown in the main prefs window */
"Advanced" = "进阶设置";
/* Apple Silicon designation (shown after the version number in Preferences) */
"Apple Silicon" = "Apple Silicon";
/* Shown in the alert dialog */
"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." = "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.";
@ -28,6 +31,9 @@
/* Shown in the main prefs window */
"General" = "通用";
/* Intel designation (shown after the version number in Preferences) */
"Intel" = "Intel";
/* Shown in the main prefs window */
"Keys" = "快捷键";

View file

@ -88,7 +88,8 @@ class DisplayPrefsViewController: NSViewController, PreferencePane, NSTableViewD
case .checkbox:
if let cell = tableView.makeView(withIdentifier: tableColumn.identifier, owner: nil) as? ButtonCellView {
cell.display = display
cell.button.state = display.isEnabled ? .on : .off
cell.button.state = display.isEnabled && !display.isVirtual ? .on : .off
cell.button.isEnabled = !display.isVirtual
return cell
}
case .ddc:

View file

@ -85,11 +85,11 @@ class MainPrefsViewController: NSViewController, PreferencePane {
#if arch(arm64)
let arch: String = "Apple Silicon"
let arch: String = NSLocalizedString("Apple Silicon", comment: "Apple Silicon designation (shown after the version number in Preferences)")
#else
let arch: String = "Intel"
let arch: String = NSLocalizedString("Intel", comment: "Intel designation (shown after the version number in Preferences)")
#endif

View file

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