mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-28 15:44:32 +00:00
Update HUDs for external display parity
This commit is contained in:
parent
e0da879823
commit
9c044237c1
4 changed files with 100 additions and 34 deletions
|
|
@ -224,7 +224,7 @@ final class BetterDisplayManager: ObservableObject {
|
|||
let category = classifyControlTarget(osd.controlTarget, systemIconID: osd.systemIconID)
|
||||
let normalizedValue = normalizeValue(osd.value, maxValue: osd.maxValue)
|
||||
let targetScreen = resolveScreen(for: osd.displayID)
|
||||
let isExternalDisplay = isExternal(displayID: osd.displayID)
|
||||
let isExternalDisplay = isExternal(displayID: osd.displayID, resolvedScreen: targetScreen)
|
||||
|
||||
NSLog("📺 BetterDisplay OSD: target=\(osd.controlTarget ?? "nil") displayID=\(osd.displayID.map(String.init) ?? "nil") resolvedScreen=\(targetScreen?.localizedName ?? "nil") isExternal=\(isExternalDisplay) value=\(osd.value ?? -1)")
|
||||
|
||||
|
|
@ -266,7 +266,8 @@ final class BetterDisplayManager: ObservableObject {
|
|||
status: true,
|
||||
type: .volume,
|
||||
value: value,
|
||||
icon: ""
|
||||
icon: "",
|
||||
onScreen: targetScreen
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -289,7 +290,8 @@ final class BetterDisplayManager: ObservableObject {
|
|||
status: true,
|
||||
type: .brightness,
|
||||
value: value,
|
||||
icon: icon
|
||||
icon: icon,
|
||||
onScreen: targetScreen
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -302,28 +304,50 @@ final class BetterDisplayManager: ObservableObject {
|
|||
NSLog("📺 BetterDisplay resolveScreen: displayID is nil, falling back to all screens")
|
||||
return nil
|
||||
}
|
||||
|
||||
if let directDisplayID = UInt32(exactly: displayID),
|
||||
let matchedScreen = NSScreen.screens.first(where: { screenNumber(for: $0) == directDisplayID }) {
|
||||
return matchedScreen
|
||||
}
|
||||
|
||||
// Fallback for payloads that use 1-based display indexes (1, 2, ...)
|
||||
if displayID > 0 {
|
||||
let index = displayID - 1
|
||||
if NSScreen.screens.indices.contains(index) {
|
||||
let fallback = NSScreen.screens[index]
|
||||
NSLog("📺 BetterDisplay resolveScreen: displayID=\(displayID) resolved via index fallback to '\(fallback.localizedName)'")
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
|
||||
let target = UInt32(displayID)
|
||||
let availableScreens = NSScreen.screens.map { screen -> (String, UInt32) in
|
||||
let num = (screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber)?.uint32Value ?? 0
|
||||
return (screen.localizedName, num)
|
||||
}
|
||||
NSLog("📺 BetterDisplay resolveScreen: looking for displayID=\(displayID) (UInt32=\(target)) among screens: \(availableScreens)")
|
||||
let matched = NSScreen.screens.first { screen in
|
||||
guard let screenNumber = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber else {
|
||||
return false
|
||||
}
|
||||
return screenNumber.uint32Value == target
|
||||
}
|
||||
if matched == nil {
|
||||
NSLog("📺 BetterDisplay resolveScreen: no match found for displayID=\(displayID), HUD will show on all screens")
|
||||
}
|
||||
return matched
|
||||
NSLog("📺 BetterDisplay resolveScreen: no match found for displayID=\(displayID), HUD will show on all screens")
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Whether the given displayID refers to an external (non-built-in) display.
|
||||
private func isExternal(displayID: Int?) -> Bool {
|
||||
guard let displayID else { return false }
|
||||
return CGDisplayIsBuiltin(UInt32(displayID)) == 0
|
||||
private func isExternal(displayID: Int?, resolvedScreen: NSScreen?) -> Bool {
|
||||
if let resolvedScreen,
|
||||
let resolvedDisplayID = screenNumber(for: resolvedScreen) {
|
||||
return CGDisplayIsBuiltin(resolvedDisplayID) == 0
|
||||
}
|
||||
guard let displayID,
|
||||
let displayIDValue = UInt32(exactly: displayID) else {
|
||||
return false
|
||||
}
|
||||
return CGDisplayIsBuiltin(displayIDValue) == 0
|
||||
}
|
||||
|
||||
private func screenNumber(for screen: NSScreen) -> UInt32? {
|
||||
guard let screenNumber = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber else {
|
||||
return nil
|
||||
}
|
||||
return screenNumber.uint32Value
|
||||
}
|
||||
|
||||
private func classifyControlTarget(_ target: String?, systemIconID: Int?) -> BetterDisplayControlCategory {
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ final class LunarManager: ObservableObject {
|
|||
|
||||
private func routeToHUD(_ data: LunarDisplayData) {
|
||||
let targetScreen = resolveScreen(for: data.display)
|
||||
let isExternal = isExternalDisplay(data.display)
|
||||
let isExternal = isExternalDisplay(data.display, resolvedScreen: targetScreen)
|
||||
|
||||
// Nits-only events are informational (no user-facing HUD needed).
|
||||
let hasActionableChange = data.brightness != nil || data.contrast != nil || data.volume != nil || data.mute != nil
|
||||
|
|
@ -342,7 +342,8 @@ final class LunarManager: ObservableObject {
|
|||
status: true,
|
||||
type: .volume,
|
||||
value: value,
|
||||
icon: ""
|
||||
icon: "",
|
||||
onScreen: targetScreen
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -364,7 +365,8 @@ final class LunarManager: ObservableObject {
|
|||
status: true,
|
||||
type: .brightness,
|
||||
value: value,
|
||||
icon: icon
|
||||
icon: icon,
|
||||
onScreen: targetScreen
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -378,16 +380,42 @@ final class LunarManager: ObservableObject {
|
|||
|
||||
/// Resolve a Lunar display ID (CGDirectDisplayID) to the matching NSScreen.
|
||||
private func resolveScreen(for displayID: Int) -> NSScreen? {
|
||||
let target = UInt32(displayID)
|
||||
return NSScreen.screens.first { screen in
|
||||
guard let num = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber else { return false }
|
||||
return num.uint32Value == target
|
||||
if let directDisplayID = UInt32(exactly: displayID),
|
||||
let matchedScreen = NSScreen.screens.first(where: { screenNumber(for: $0) == directDisplayID }) {
|
||||
return matchedScreen
|
||||
}
|
||||
|
||||
// Fallback for integrations that send 1-based display indexes (e.g. 1, 2)
|
||||
if displayID > 0 {
|
||||
let index = displayID - 1
|
||||
if NSScreen.screens.indices.contains(index) {
|
||||
let fallback = NSScreen.screens[index]
|
||||
NSLog("🌙 Lunar: display=\(displayID) resolved via index fallback to '\(fallback.localizedName)'")
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
|
||||
NSLog("🌙 Lunar: unable to resolve display=\(displayID), HUD will show on all screens")
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Whether the given displayID refers to an external (non-built-in) display.
|
||||
private func isExternalDisplay(_ displayID: Int) -> Bool {
|
||||
CGDisplayIsBuiltin(UInt32(displayID)) == 0
|
||||
private func isExternalDisplay(_ displayID: Int, resolvedScreen: NSScreen?) -> Bool {
|
||||
if let resolvedScreen,
|
||||
let resolvedDisplayID = screenNumber(for: resolvedScreen) {
|
||||
return CGDisplayIsBuiltin(resolvedDisplayID) == 0
|
||||
}
|
||||
if let displayIDValue = UInt32(exactly: displayID) {
|
||||
return CGDisplayIsBuiltin(displayIDValue) == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private func screenNumber(for screen: NSScreen) -> UInt32? {
|
||||
guard let num = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber else {
|
||||
return nil
|
||||
}
|
||||
return num.uint32Value
|
||||
}
|
||||
|
||||
// MARK: - Reconnection
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue