@@ -20,7 +20,11 @@ use objc2::{
2020use once_cell:: { sync:: Lazy as SyncLazy , unsync:: Lazy } ;
2121use std:: { collections:: HashMap , ffi:: c_void, sync:: Mutex } ;
2222
23- use crate :: { appkit:: NSView , event:: QueuedEvents , Adapter } ;
23+ use crate :: {
24+ appkit:: { NSView , NSWindow } ,
25+ event:: QueuedEvents ,
26+ Adapter ,
27+ } ;
2428
2529static SUBCLASSES : SyncLazy < Mutex < HashMap < & ' static Class , & ' static Class > > > =
2630 SyncLazy :: new ( || Mutex :: new ( HashMap :: new ( ) ) ) ;
@@ -116,13 +120,22 @@ impl SubclassingAdapter {
116120 ) -> Self {
117121 let view = view as * mut NSView ;
118122 let retained_view = unsafe { Id :: retain ( view) } . unwrap ( ) ;
123+ Self :: new_internal ( retained_view, source, action_handler)
124+ }
125+
126+ fn new_internal (
127+ retained_view : Id < NSView , Shared > ,
128+ source : impl ' static + FnOnce ( ) -> TreeUpdate ,
129+ action_handler : Box < dyn ActionHandler > ,
130+ ) -> Self {
119131 let adapter: LazyAdapter = {
120132 let retained_view = retained_view. clone ( ) ;
121133 Lazy :: new ( Box :: new ( move || {
122134 let view = Id :: as_ptr ( & retained_view) as * mut c_void ;
123135 unsafe { Adapter :: new ( view, source ( ) , action_handler) }
124136 } ) )
125137 } ;
138+ let view = Id :: as_ptr ( & retained_view) as * mut NSView ;
126139 // Cast to a pointer and back to force the lifetime to 'static
127140 // SAFETY: We know the class will live as long as the instance,
128141 // and we only use this reference while the instance is alive.
@@ -171,6 +184,29 @@ impl SubclassingAdapter {
171184 }
172185 }
173186
187+ /// Create an adapter that dynamically subclasses the content view
188+ /// of the specified window.
189+ ///
190+ /// The action handler will always be called on the main thread.
191+ ///
192+ /// # Safety
193+ ///
194+ /// `window` must be a valid, unreleased pointer to an `NSWindow`.
195+ ///
196+ /// # Panics
197+ ///
198+ /// This function panics if the specified window doesn't currently have
199+ /// a content view.
200+ pub unsafe fn for_window (
201+ window : * mut c_void ,
202+ source : impl ' static + FnOnce ( ) -> TreeUpdate ,
203+ action_handler : Box < dyn ActionHandler > ,
204+ ) -> Self {
205+ let window = unsafe { & * ( window as * const NSWindow ) } ;
206+ let retained_view = window. content_view ( ) . unwrap ( ) ;
207+ Self :: new_internal ( retained_view, source, action_handler)
208+ }
209+
174210 /// Initialize the tree if it hasn't been initialized already, then apply
175211 /// the provided update.
176212 ///
0 commit comments