Skip to content

Commit d73e0b9

Browse files
fixed metal layer crash
1 parent f65c764 commit d73e0b9

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

src/macos/view.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)