@@ -20,7 +20,11 @@ use objc2::{
20
20
use once_cell:: { sync:: Lazy as SyncLazy , unsync:: Lazy } ;
21
21
use std:: { collections:: HashMap , ffi:: c_void, sync:: Mutex } ;
22
22
23
- use crate :: { appkit:: NSView , event:: QueuedEvents , Adapter } ;
23
+ use crate :: {
24
+ appkit:: { NSView , NSWindow } ,
25
+ event:: QueuedEvents ,
26
+ Adapter ,
27
+ } ;
24
28
25
29
static SUBCLASSES : SyncLazy < Mutex < HashMap < & ' static Class , & ' static Class > > > =
26
30
SyncLazy :: new ( || Mutex :: new ( HashMap :: new ( ) ) ) ;
@@ -116,13 +120,22 @@ impl SubclassingAdapter {
116
120
) -> Self {
117
121
let view = view as * mut NSView ;
118
122
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 {
119
131
let adapter: LazyAdapter = {
120
132
let retained_view = retained_view. clone ( ) ;
121
133
Lazy :: new ( Box :: new ( move || {
122
134
let view = Id :: as_ptr ( & retained_view) as * mut c_void ;
123
135
unsafe { Adapter :: new ( view, source ( ) , action_handler) }
124
136
} ) )
125
137
} ;
138
+ let view = Id :: as_ptr ( & retained_view) as * mut NSView ;
126
139
// Cast to a pointer and back to force the lifetime to 'static
127
140
// SAFETY: We know the class will live as long as the instance,
128
141
// and we only use this reference while the instance is alive.
@@ -171,6 +184,29 @@ impl SubclassingAdapter {
171
184
}
172
185
}
173
186
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
+
174
210
/// Initialize the tree if it hasn't been initialized already, then apply
175
211
/// the provided update.
176
212
///
0 commit comments