Files
downterm/Downterm/CommandNotch/Extensions/NSScreen+Extensions.swift

84 lines
2.9 KiB
Swift

import AppKit
extension NSScreen {
// MARK: - Stable display identifier
/// Returns a stable UUID string for this screen by querying CoreGraphics.
/// Falls back to the localized name if the CG UUID is unavailable.
var displayUUID: String {
guard let screenNumber = deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID else {
return localizedName
}
guard let uuid = CGDisplayCreateUUIDFromDisplayID(screenNumber) else {
return localizedName
}
return CFUUIDCreateString(nil, uuid.takeUnretainedValue()) as String
}
// MARK: - Notch detection
/// `true` when this screen has a physical camera notch (safe area inset at top > 0).
var hasNotch: Bool {
safeAreaInsets.top > 0
}
// MARK: - Closed notch sizing
/// Computes the closed-state notch size for this screen,
/// respecting the user's height mode and custom height preferences.
func closedNotchSize(using settings: AppSettings.DisplaySettings) -> CGSize {
let height = closedNotchHeight(using: settings)
let width = closedNotchWidth()
return CGSize(width: width, height: height)
}
/// Height of the closed notch bar, determined by the user's chosen mode.
private func closedNotchHeight(using settings: AppSettings.DisplaySettings) -> CGFloat {
if hasNotch {
let mode = NotchHeightMode(rawValue: settings.notchHeightMode)
?? .matchRealNotchSize
switch mode {
case .matchRealNotchSize:
return safeAreaInsets.top
case .matchMenuBar:
return menuBarHeight()
case .custom:
return settings.notchHeight
}
} else {
let mode = NonNotchHeightMode(rawValue: settings.nonNotchHeightMode)
?? .matchMenuBar
switch mode {
case .matchMenuBar:
return menuBarHeight()
case .custom:
return settings.nonNotchHeight
}
}
}
/// Width of the closed notch.
/// On notch screens, spans from one auxiliary top area to the other.
/// On non-notch screens, uses a reasonable fixed width.
private func closedNotchWidth() -> CGFloat {
if hasNotch {
if let topLeft = auxiliaryTopLeftArea,
let topRight = auxiliaryTopRightArea {
// The notch occupies the space between the two menu bar segments
return frame.width - topLeft.width - topRight.width + 4
}
// Fallback for older API approximate from safe area
return 220
} else {
// Non-notch screens: a compact simulated notch
return 220
}
}
/// The effective menu bar height for this screen.
private func menuBarHeight() -> CGFloat {
return frame.maxY - visibleFrame.maxY
}
}