From d7ecf0112f63d698abf35c76dbc948c3cff613a4 Mon Sep 17 00:00:00 2001
From: waydabber <37590873+waydabber@users.noreply.github.com>
Date: Sun, 1 Aug 2021 18:39:37 +0200
Subject: [PATCH] Better handling of virtual displays (AirPlay, Sidecar) -
these cannot be enabled and no DDC for them.
---
MonitorControl/AppDelegate.swift | 22 +++++++++---
MonitorControl/Info.plist | 2 +-
MonitorControl/Model/Display.swift | 4 ++-
MonitorControl/Model/ExternalDisplay.swift | 34 +++++++++++--------
MonitorControl/Model/InternalDisplay.swift | 2 +-
.../Support/de.lproj/Localizable.strings | 6 ++++
.../Support/en.lproj/Localizable.strings | 6 ++++
.../Support/fr.lproj/Localizable.strings | 6 ++++
.../Support/it.lproj/Localizable.strings | 6 ++++
.../Support/ja.lproj/Localizable.strings | 6 ++++
.../Support/pl.lproj/Localizable.strings | 6 ++++
.../Support/ru.lproj/Localizable.strings | 6 ++++
.../Support/uk.lproj/Localizable.strings | 6 ++++
.../Support/zh-Hans.lproj/Localizable.strings | 6 ++++
.../DisplayPrefsViewController.swift | 3 +-
.../MainPrefsViewController.swift | 4 +--
MonitorControlHelper/Info.plist | 2 +-
17 files changed, 100 insertions(+), 27 deletions(-)
diff --git a/MonitorControl/AppDelegate.swift b/MonitorControl/AppDelegate.swift
index cd4c7ac..ff489c4 100644
--- a/MonitorControl/AppDelegate.swift
+++ b/MonitorControl/AppDelegate.swift
@@ -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)
diff --git a/MonitorControl/Info.plist b/MonitorControl/Info.plist
index d085038..36baae5 100644
--- a/MonitorControl/Info.plist
+++ b/MonitorControl/Info.plist
@@ -19,7 +19,7 @@
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleVersion
- 1118
+ 1140
LSApplicationCategoryType
public.app-category.utilities
LSMinimumSystemVersion
diff --git a/MonitorControl/Model/Display.swift b/MonitorControl/Model/Display.swift
index 10da136..120232a 100644
--- a/MonitorControl/Model/Display.swift
+++ b/MonitorControl/Model/Display.swift
@@ -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
diff --git a/MonitorControl/Model/ExternalDisplay.swift b/MonitorControl/Model/ExternalDisplay.swift
index ca00e24..a93f58c 100644
--- a/MonitorControl/Model/ExternalDisplay.swift
+++ b/MonitorControl/Model/ExternalDisplay.swift
@@ -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,
diff --git a/MonitorControl/Model/InternalDisplay.swift b/MonitorControl/Model/InternalDisplay.swift
index 26f379d..dd6c1ea 100644
--- a/MonitorControl/Model/InternalDisplay.swift
+++ b/MonitorControl/Model/InternalDisplay.swift
@@ -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)
}
diff --git a/MonitorControl/Support/de.lproj/Localizable.strings b/MonitorControl/Support/de.lproj/Localizable.strings
index a605129..8e4a14b 100644
--- a/MonitorControl/Support/de.lproj/Localizable.strings
+++ b/MonitorControl/Support/de.lproj/Localizable.strings
@@ -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";
diff --git a/MonitorControl/Support/en.lproj/Localizable.strings b/MonitorControl/Support/en.lproj/Localizable.strings
index 9900e94..c9ae3a7 100644
--- a/MonitorControl/Support/en.lproj/Localizable.strings
+++ b/MonitorControl/Support/en.lproj/Localizable.strings
@@ -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";
diff --git a/MonitorControl/Support/fr.lproj/Localizable.strings b/MonitorControl/Support/fr.lproj/Localizable.strings
index 19900e3..41d67b4 100644
--- a/MonitorControl/Support/fr.lproj/Localizable.strings
+++ b/MonitorControl/Support/fr.lproj/Localizable.strings
@@ -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";
diff --git a/MonitorControl/Support/it.lproj/Localizable.strings b/MonitorControl/Support/it.lproj/Localizable.strings
index 7972cf1..b9048f7 100644
--- a/MonitorControl/Support/it.lproj/Localizable.strings
+++ b/MonitorControl/Support/it.lproj/Localizable.strings
@@ -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";
diff --git a/MonitorControl/Support/ja.lproj/Localizable.strings b/MonitorControl/Support/ja.lproj/Localizable.strings
index c47b9de..8b69849 100644
--- a/MonitorControl/Support/ja.lproj/Localizable.strings
+++ b/MonitorControl/Support/ja.lproj/Localizable.strings
@@ -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" = "キー";
diff --git a/MonitorControl/Support/pl.lproj/Localizable.strings b/MonitorControl/Support/pl.lproj/Localizable.strings
index e7cc8c0..88b1879 100644
--- a/MonitorControl/Support/pl.lproj/Localizable.strings
+++ b/MonitorControl/Support/pl.lproj/Localizable.strings
@@ -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";
diff --git a/MonitorControl/Support/ru.lproj/Localizable.strings b/MonitorControl/Support/ru.lproj/Localizable.strings
index a260ab5..6a30728 100644
--- a/MonitorControl/Support/ru.lproj/Localizable.strings
+++ b/MonitorControl/Support/ru.lproj/Localizable.strings
@@ -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" = "Сочетания клавиш";
diff --git a/MonitorControl/Support/uk.lproj/Localizable.strings b/MonitorControl/Support/uk.lproj/Localizable.strings
index 1c5604c..38a636a 100644
--- a/MonitorControl/Support/uk.lproj/Localizable.strings
+++ b/MonitorControl/Support/uk.lproj/Localizable.strings
@@ -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" = "Клавіші";
diff --git a/MonitorControl/Support/zh-Hans.lproj/Localizable.strings b/MonitorControl/Support/zh-Hans.lproj/Localizable.strings
index cb36d6a..da90ee0 100644
--- a/MonitorControl/Support/zh-Hans.lproj/Localizable.strings
+++ b/MonitorControl/Support/zh-Hans.lproj/Localizable.strings
@@ -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" = "快捷键";
diff --git a/MonitorControl/View Controllers/DisplayPrefsViewController.swift b/MonitorControl/View Controllers/DisplayPrefsViewController.swift
index fc1f8cb..c82f415 100644
--- a/MonitorControl/View Controllers/DisplayPrefsViewController.swift
+++ b/MonitorControl/View Controllers/DisplayPrefsViewController.swift
@@ -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:
diff --git a/MonitorControl/View Controllers/MainPrefsViewController.swift b/MonitorControl/View Controllers/MainPrefsViewController.swift
index 6d4136f..dca106f 100644
--- a/MonitorControl/View Controllers/MainPrefsViewController.swift
+++ b/MonitorControl/View Controllers/MainPrefsViewController.swift
@@ -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
diff --git a/MonitorControlHelper/Info.plist b/MonitorControlHelper/Info.plist
index 37fe1d6..bd8022e 100644
--- a/MonitorControlHelper/Info.plist
+++ b/MonitorControlHelper/Info.plist
@@ -19,7 +19,7 @@
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleVersion
- 1118
+ 1140
LSApplicationCategoryType
public.app-category.utilities
LSBackgroundOnly