You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Musubi/Packages/MusubiKit/Sources/VideoOutput/OutputWindow.swift

59 lines
2.0 KiB

import AppKit
import AVFoundation
/// A borderless window covering one screen, above the menu bar, that shows a video layer.
@MainActor
public final class OutputWindow: NSWindow {
public let sink: VideoSink
/// Called when the operator presses Esc on the output.
public var onCancel: (() -> Void)?
public init(screen: NSScreen) {
let view = VideoView()
sink = VideoSink(renderer: view.displayLayer.sampleBufferRenderer)
super.init(contentRect: screen.frame, styleMask: .borderless, backing: .buffered, defer: false)
contentView = view
setFrame(screen.frame, display: false)
level = .screenSaver
collectionBehavior = [.canJoinAllSpaces, .stationary, .ignoresCycle, .fullScreenNone]
backgroundColor = .black
isOpaque = true
hasShadow = false
isReleasedWhenClosed = false
animationBehavior = .none
}
public override var canBecomeKey: Bool { true }
public override func cancelOperation(_ sender: Any?) {
onCancel?()
}
}
/// Layer-hosting view backed by `AVSampleBufferDisplayLayer`; hides the cursor while it is inside.
@MainActor
final class VideoView: NSView {
let displayLayer = AVSampleBufferDisplayLayer()
init() {
super.init(frame: .zero)
displayLayer.videoGravity = .resizeAspect
displayLayer.backgroundColor = NSColor.black.cgColor
layer = displayLayer
wantsLayer = true
}
@available(*, unavailable)
required init?(coder: NSCoder) { fatalError() }
override func updateTrackingAreas() {
super.updateTrackingAreas()
trackingAreas.forEach(removeTrackingArea)
addTrackingArea(NSTrackingArea(rect: .zero, options: [.mouseEnteredAndExited, .mouseMoved, .activeAlways, .inVisibleRect], owner: self))
}
override func mouseEntered(with event: NSEvent) { NSCursor.setHiddenUntilMouseMoves(true) }
override func mouseMoved(with event: NSEvent) { NSCursor.setHiddenUntilMouseMoves(true) }
}

Powered by TurnKey Linux.