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.
This commit is contained in:
Mitchell Hashimoto
2024-10-05 06:19:07 -10:00
parent 9971d7a93d
commit 1ae9322959
3 changed files with 9 additions and 5 deletions

View File

@ -325,8 +325,7 @@ extension Ghostty {
// When the window changes screens, we need to update libghostty with the screen
// ID. If vsync is enabled, this will be used with the CVDisplayLink to ensure
// the proper refresh rate is going.
let id = (screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as! NSNumber).uint32Value
ghostty_surface_set_display_id(surface, id)
ghostty_surface_set_display_id(surface, screen.displayID ?? 0)
}
// MARK: - NSView

View File

@ -269,7 +269,7 @@ class NonNativeFullscreen: FullscreenStyle {
object == window else { return }
// Our screens must have changed
guard savedState.screen != window.screen else { return }
guard savedState.screenID != window.screen?.displayID else { return }
// When we change screens, we simply exit fullscreen. Changing
// screens shouldn't naturally be possible, it can only happen
@ -337,7 +337,7 @@ class NonNativeFullscreen: FullscreenStyle {
/// The state that must be saved for non-native fullscreen to exit fullscreen.
class SavedState {
weak var screen: NSScreen?
let screenID: UInt32?
let tabGroup: NSWindowTabGroup?
let tabGroupIndex: Int?
let contentFrame: NSRect
@ -347,7 +347,7 @@ class NonNativeFullscreen: FullscreenStyle {
init?(_ window: NSWindow) {
guard let contentView = window.contentView else { return nil }
self.screen = window.screen
self.screenID = window.screen?.displayID
self.tabGroup = window.tabGroup
self.tabGroupIndex = window.tabGroup?.windows.firstIndex(of: window)
self.contentFrame = window.convertToScreen(contentView.frame)

View File

@ -1,6 +1,11 @@
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.