@@ -121,6 +121,15 @@ pub(super) unsafe fn create_view(window_options: &WindowOpenOptions) -> id {
121121
122122 view. initWithFrame_ ( NSRect :: new ( NSPoint :: new ( 0. , 0. ) , NSSize :: new ( size. width , size. height ) ) ) ;
123123
124+ // Make the view layer-backed and attach a CAMetalLayer so Metal surfaces can be created.
125+ let _: ( ) = msg_send ! [ view, setWantsLayer: YES ] ;
126+ let metal_layer: id = msg_send ! [ class!( CAMetalLayer ) , layer] ;
127+ let scale: f64 = msg_send ! [ view, backingScaleFactor] ;
128+ let bounds: NSRect = msg_send ! [ view, bounds] ;
129+ let _: ( ) = msg_send ! [ metal_layer, setContentsScale: scale] ;
130+ let _: ( ) = msg_send ! [ metal_layer, setFrame: bounds] ;
131+ let _: ( ) = msg_send ! [ view, setLayer: metal_layer] ;
132+
124133 register_notification ( view, NSWindowDidBecomeKeyNotification , nil) ;
125134 register_notification ( view, NSWindowDidResignKeyNotification , nil) ;
126135
@@ -172,6 +181,10 @@ unsafe fn create_view_class() -> &'static Class {
172181 sel ! ( viewWillMoveToWindow: ) ,
173182 view_will_move_to_window as extern "C" fn ( & Object , Sel , id ) ,
174183 ) ;
184+ class. add_method (
185+ sel ! ( setFrameSize: ) ,
186+ set_frame_size as extern "C" fn ( & Object , Sel , NSSize ) ,
187+ ) ;
175188 class. add_method (
176189 sel ! ( updateTrackingAreas: ) ,
177190 update_tracking_areas as extern "C" fn ( & Object , Sel , id ) ,
@@ -310,6 +323,30 @@ extern "C" fn view_did_change_backing_properties(this: &Object, _: Sel, _: id) {
310323 state. window_info . set ( new_window_info) ;
311324 state. trigger_event ( Event :: Window ( WindowEvent :: Resized ( new_window_info) ) ) ;
312325 }
326+
327+ // Keep the metal layer in sync with scale and bounds changes.
328+ let layer: id = msg_send ! [ this, layer] ;
329+ if layer != nil {
330+ let _: ( ) = msg_send ! [ layer, setContentsScale: scale_factor] ;
331+ let _: ( ) = msg_send ! [ layer, setFrame: bounds] ;
332+ }
333+ }
334+ }
335+
336+ extern "C" fn set_frame_size ( this : & Object , _sel : Sel , size : NSSize ) {
337+ unsafe {
338+ // Call through to super to maintain default behavior
339+ let superclass = msg_send ! [ this, superclass] ;
340+ let ( ) = msg_send ! [ super ( this, superclass) , setFrameSize: size] ;
341+
342+ // Keep the attached CAMetalLayer in sync with the view's new bounds/scale
343+ let layer: id = msg_send ! [ this, layer] ;
344+ if layer != nil {
345+ let bounds: NSRect = msg_send ! [ this, bounds] ;
346+ let scale: f64 = msg_send ! [ this, backingScaleFactor] ;
347+ let _: ( ) = msg_send ! [ layer, setFrame: bounds] ;
348+ let _: ( ) = msg_send ! [ layer, setContentsScale: scale] ;
349+ }
313350 }
314351}
315352
0 commit comments