ghostty/macos/Sources/Helpers/NSScreen+Extension.swift
Mitchell Hashimoto 1ae9322959 macos: non-native fs keeps track of screen number for change screen comp
Fixes #2370

Comparing NSScreens directly was fragile. It appears that AppKit/Cocoa
can return different instances of NSScreen for the same screen for
unknown reasons between calls to windowDidChangeScreen. I don't fully
understand why this happens.

In any case, our comparison was not safe. Instad, we now keep track of
of the CGDirectDisplayID for each screen and compare those instead.
2024-10-05 06:21:30 -10:00

42 lines
1.7 KiB
Swift

import Cocoa
extension NSScreen {
/// The unique CoreGraphics display ID for this screen.
var displayID: UInt32? {
deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? UInt32
}
// Returns true if the given screen has a visible dock. This isn't
// point-in-time visible, this is true if the dock is always visible
// AND present on this screen.
var hasDock: Bool {
// If the dock autohides then we don't have a dock ever.
if let dockAutohide = UserDefaults.standard.persistentDomain(forName: "com.apple.dock")?["autohide"] as? Bool {
if (dockAutohide) { return false }
}
// There is no public API to directly ask about dock visibility, so we have to figure it out
// by comparing the sizes of visibleFrame (the currently usable area of the screen) and
// frame (the full screen size). We also need to account for the menubar, any inset caused
// by the notch on macbooks, and a little extra padding to compensate for the boundary area
// which triggers showing the dock.
// If our visible width is less than the frame we assume its the dock.
if (visibleFrame.width < frame.width) {
return true
}
// We need to see if our visible frame height is less than the full
// screen height minus the menu and notch and such.
let menuHeight = NSApp.mainMenu?.menuBarHeight ?? 0
let notchInset: CGFloat = if #available(macOS 12, *) {
safeAreaInsets.top
} else {
0
}
let boundaryAreaPadding = 5.0
return visibleFrame.height < (frame.height - max(menuHeight, notchInset) - boundaryAreaPadding)
}
}