Die Silhouette bestand aus zwei überlappenden Teilpfaden. Gefüllt stimmte die Vereinigung, aber die Kontur zeichnete jeden Teilpfad vollständig nach — auch dort, wo er innen lag. Dazu kippte die Form ab einer Breite in einen anderen Zweig, und die beiden Zweige waren nicht dieselbe Geometrie. Zusammen war das das Flackern an den Rundungen. Jetzt ein durchgehender Umriss, dessen Zweige ineinander übergehen statt zu springen. Neu ist die Wahl zwischen verschmolzen und schwebend. Eine echte Notch **muss** an der Kante kleben und oben eckig sein, sonst klafft ein Spalt zum Gehäuse; eine Insel **muss** Abstand halten und rundum gerundet sein, sonst sieht sie aus wie ein abgeschnittenes Rechteck. Beides zu mischen geht nicht, deshalb eine Wahl und keine zwei Schalter. Ihre Höhe rät Onyx nicht mehr, sondern misst die Menüleiste: 24 Punkte minus Luft oben und unten. Vorher hing ein festes Maß unten heraus. Dazu „nur der Hauptbildschirm" als dritte Anzeigewahl — gemeint ist der mit der Menüleiste, nicht `NSScreen.main`, das mit dem aktiven Fenster mitwandert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
56 lines
2.2 KiB
Swift
56 lines
2.2 KiB
Swift
import AppKit
|
|
|
|
public extension NSScreen {
|
|
|
|
/// Die `CGDirectDisplayID` dieses Bildschirms. Anders als der Index in
|
|
/// `NSScreen.screens` überlebt sie ein Umstecken oder Umsortieren.
|
|
public var displayID: CGDirectDisplayID {
|
|
deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID ?? 0
|
|
}
|
|
|
|
var isBuiltInDisplay: Bool {
|
|
CGDisplayIsBuiltin(displayID) != 0
|
|
}
|
|
|
|
/// Der Bildschirm mit der Menüleiste.
|
|
///
|
|
/// Das ist der **erste** in `NSScreen.screens`, nicht `NSScreen.main` —
|
|
/// letzteres ist der mit dem aktiven Fenster und wandert beim Klicken.
|
|
var isMainDisplay: Bool {
|
|
NSScreen.screens.first?.displayID == displayID
|
|
}
|
|
|
|
/// Reduziert den Bildschirm auf genau die Werte, die die Geometrie braucht.
|
|
/// Alles Weitere bleibt draußen, damit `NotchGeometry` ohne Fenstersystem
|
|
/// prüfbar bleibt.
|
|
var onyxMetrics: ScreenMetrics {
|
|
ScreenMetrics(frame: frame,
|
|
safeAreaTop: safeAreaInsets.top,
|
|
auxiliaryTopLeft: auxiliaryTopLeftArea,
|
|
auxiliaryTopRight: auxiliaryTopRightArea,
|
|
isBuiltIn: isBuiltInDisplay,
|
|
menuBarHeight: onyxMenuBarHeight,
|
|
isMain: isMainDisplay,
|
|
displayID: displayID)
|
|
}
|
|
|
|
/// Die Höhe der Menüleiste auf diesem Bildschirm.
|
|
///
|
|
/// `visibleFrame` lässt sie oben aus — die Differenz *ist* die Leiste.
|
|
/// Bei einem Vollbildfenster ist die Differenz null; dann taugt sie nicht
|
|
/// als Maß, und die Systemdicke tritt an ihre Stelle.
|
|
var onyxMenuBarHeight: CGFloat {
|
|
let measured = frame.maxY - visibleFrame.maxY
|
|
return measured > 1 ? measured : NSStatusBar.system.thickness
|
|
}
|
|
|
|
/// Verdeckt gerade ein Vollbildfenster die Menüleiste?
|
|
///
|
|
/// Es gibt keine öffentliche API, die „hier läuft ein Vollbildvideo" meldet.
|
|
/// Der verlässliche Hinweis ist die verschwundene Menüleiste: bei echtem
|
|
/// Vollbild reicht `visibleFrame` bis an die Oberkante von `frame`.
|
|
var isShowingFullScreenWindow: Bool {
|
|
frame.maxY - visibleFrame.maxY < 1
|
|
}
|
|
}
|