fix: disambiguate SwiftUI State with macOS 27 SDK

Use a file-private ViewState alias for all twelve state properties, including start-screen hover and playback queue state, on current main@origin. Document the standalone Command Line Tools workaround.

Verified: make release; release check-runtime; release CLI --help; dlopen of the release player library and terebi_app_main symbol lookup.
This commit is contained in:
Valdemar Lorenzen
2026-10-19 12:05:38 +02:00
parent 9e4cb05439
commit 997eb144d2
3 changed files with 18 additions and 12 deletions
+2
View File
@@ -15,6 +15,8 @@ make run
The first build downloads pinned dependencies. Build natively on Apple Silicon or Intel; cross-architecture and Rosetta builds are not supported.
With the macOS 27 SDK, the player uses a private `ViewState` alias for the `SwiftUI.State<Value>` property wrapper to avoid selecting the same-named macro, whose `SwiftUIMacros` plugin is absent from standalone Command Line Tools. Full Xcode or an older SDK is not required.
The resulting `.build/terebi.app` is self-contained: copy the whole app to a compatible Mac of the same architecture. No separate FFmpeg, Python, or yt-dlp installation is needed to run it.
### Install
+15 -12
View File
@@ -2068,9 +2068,12 @@ struct PlaybackSurface: NSViewRepresentable {
}
}
// Select the property wrapper, not the macOS 27 macro missing from Command Line Tools.
private typealias ViewState<Value> = SwiftUI.State<Value>
private struct StartScreenButtonStyle: ButtonStyle {
var prominent = false
@State private var hovered = false
@ViewState private var hovered = false
func makeBody(configuration: Configuration) -> some View {
configuration.label
@@ -2089,19 +2092,19 @@ private struct StartScreenButtonStyle: ButtonStyle {
private struct PlayerContent: View {
@ObservedObject var model: PlayerModel
@Environment(\.accessibilityReduceMotion) private var reduceMotion
@State private var showsRemainingTime = false
@State private var dropTargeted = false
@State private var showsYouTubeInput = false
@State private var youTubeURL = ""
@ViewState private var showsRemainingTime = false
@ViewState private var dropTargeted = false
@ViewState private var showsYouTubeInput = false
@ViewState private var youTubeURL = ""
@FocusState private var youTubeInputFocused: Bool
@State private var controlSize = CGSize(width: 440, height: 68)
@State private var queueFrames: [UUID: CGRect] = [:]
@State private var queueDrag: PlaybackQueueDrag?
@ViewState private var controlSize = CGSize(width: 440, height: 68)
@ViewState private var queueFrames: [UUID: CGRect] = [:]
@ViewState private var queueDrag: PlaybackQueueDrag?
@GestureState private var queueDragging = false
@State private var queueScroll = ScrollPosition(y: 0)
@State private var queueScrollOffset: CGFloat = 0
@State private var queueViewportHeight: CGFloat = 0
@State private var queueContentHeight: CGFloat = 0
@ViewState private var queueScroll = ScrollPosition(y: 0)
@ViewState private var queueScrollOffset: CGFloat = 0
@ViewState private var queueViewportHeight: CGFloat = 0
@ViewState private var queueContentHeight: CGFloat = 0
private func compactTitleLabel(progress: String?, constrained: Bool) -> some View {
HStack(spacing: 0) {
+1
View File
@@ -10,5 +10,6 @@
- local seek preroll skips disposable non-reference pictures without sacrificing exact target frames; measured 1080p/10-second-GOP paused seek improved from 541 ms to 400 ms and playing seek from 682 ms to 488 ms; timestamp/pixel checks passed across six decoder formats; long-GOP reference decoding remains necessary, and the originally affected files still need manual verification
- [x] make the sidebar expand/collapse with a nice transition
- synchronized 250 ms sidebar/window reveal, reversible mid-transition, with immediate Reduce Motion changes; top-right controls stay anchored to the moving window corner; native checks passed for rendered controls during transitions, stable video size, reversals, screen-edge fitting, fullscreen and compact restoration; animation feel and Reduce Motion still need manual verification
- [ ] make the window draggable (in all cases/view states) so long as a button/clickable element is not hovered.
- [ ] in the "choose what to play" screen, we should change the youtube button to general streaming
- we can figure out the stream and how to handle it from the url (i.e. if youtube url, handle as youtube stream; if miruro url, handle accordingly)