Mitchell Hashimoto d1c15dbf07 macOS: quick terminal should retain menu if not frontmost
This is a bug I noticed in the following scenario:

  1. Open Ghostty
  2. Fullscreen normal terminal window (native fullscreen)
  3. Open quick terminal
  4. Move spaces, QT follows
  5. Fullscreen the quick terminal

The result was that the menu bar would not disappear since our app is
not frontmost but we set the fullscreen frame such that we expected it.
2025-04-14 11:17:11 -07:00

82 lines
2.5 KiB
Swift

import AppKit
// MARK: - CGS Private API Declarations
typealias CGSConnectionID = Int32
typealias CGSSpaceID = size_t
@_silgen_name("CGSMainConnectionID")
private func CGSMainConnectionID() -> CGSConnectionID
@_silgen_name("CGSGetActiveSpace")
private func CGSGetActiveSpace(_ cid: CGSConnectionID) -> CGSSpaceID
@_silgen_name("CGSSpaceGetType")
private func CGSSpaceGetType(_ cid: CGSConnectionID, _ spaceID: CGSSpaceID) -> CGSSpaceType
@_silgen_name("CGSCopySpacesForWindows")
func CGSCopySpacesForWindows(
_ cid: CGSConnectionID,
_ mask: CGSSpaceMask,
_ windowIDs: CFArray
) -> Unmanaged<CFArray>?
// MARK: - CGS Space
/// https://github.com/NUIKit/CGSInternal/blob/c4f6f559d624dc1cfc2bf24c8c19dbf653317fcf/CGSSpace.h#L40
/// converted to Swift
struct CGSSpaceMask: OptionSet {
let rawValue: UInt32
static let includesCurrent = CGSSpaceMask(rawValue: 1 << 0)
static let includesOthers = CGSSpaceMask(rawValue: 1 << 1)
static let includesUser = CGSSpaceMask(rawValue: 1 << 2)
static let includesVisible = CGSSpaceMask(rawValue: 1 << 16)
static let currentSpace: CGSSpaceMask = [.includesUser, .includesCurrent]
static let otherSpaces: CGSSpaceMask = [.includesOthers, .includesCurrent]
static let allSpaces: CGSSpaceMask = [.includesUser, .includesOthers, .includesCurrent]
static let allVisibleSpaces: CGSSpaceMask = [.includesVisible, .allSpaces]
}
/// Represents a unique identifier for a macOS Space (Desktop, Fullscreen, etc).
struct CGSSpace: Hashable, CustomStringConvertible {
let rawValue: CGSSpaceID
var description: String {
"SpaceID(\(rawValue))"
}
/// Returns the currently active space.
static func active() -> CGSSpace {
let space = CGSGetActiveSpace(CGSMainConnectionID())
return .init(rawValue: space)
}
/// List the spaces for the given window.
static func list(for windowID: CGWindowID, mask: CGSSpaceMask = .allSpaces) -> [CGSSpace] {
guard let spaces = CGSCopySpacesForWindows(
CGSMainConnectionID(),
mask,
[windowID] as CFArray
) else { return [] }
guard let spaceIDs = spaces.takeRetainedValue() as? [CGSSpaceID] else { return [] }
return spaceIDs.map(CGSSpace.init)
}
}
// MARK: - CGS Space Types
enum CGSSpaceType: UInt32 {
case user = 0
case system = 2
case fullscreen = 4
}
extension CGSSpace {
var type: CGSSpaceType {
CGSSpaceGetType(CGSMainConnectionID(), rawValue)
}
}