import Gtk /// A live, order-independent reference to a widget produced elsewhere in the view tree. /// /// Declare a reference with `@WidgetRef`, publish a producing view with ``View/ref(_:)``, /// and pass the projected binding to any modifier that accepts the referenced widget. /// The reference is initially `nil`; publishing another widget replaces the current value. /// When the publishing subtree unmounts, the reference is cleared only if it still points /// at that subtree's widget. @propertyWrapper @MainActor public struct WidgetRef { private let box = StateBox(nil) /// Creates an unset widget reference. public init() {} /// The referenced widget, or `nil` until the view carrying ``View/ref(_:)`` mounts. /// Reads track, so a tracked closure that reads this re-runs when the reference changes. public var wrappedValue: W? { box.get() } /// The read-only binding consumed by reference-taking widget modifiers. /// Writes are ignored; publishing views own the reference value. public var projectedValue: Binding { Binding(readOnly: box) } /// Publishes a mounted widget and clears it when that publishing subtree tears down. /// /// The widget is checked dynamically because Swift cannot express the relationship /// between the publisher's target type and this reference's generic type. Multiple /// publishers are allowed; the latest publisher wins, and an older publisher cannot /// clear a newer value during teardown. @_spi(Portico) public func _publish(_ widget: Gtk.Widget, registry: NodeRegistry) { guard let typed = widget as? W else { preconditionFailure( "WidgetRef<\(W.self)>: .ref() applied to a view whose widget is \(type(of: widget)). Declare the ref at that type, or at a superclass of it." ) } box.set(typed) registry.add(SubscriptionToken { [box] in if box.peek() === typed { box.set(nil) } }) } }