From f65c76424077b593d536e79c606798541b1984b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=BE=E6=B5=A6=20=E7=9F=A5=E4=B9=9F=20Matsuura=20Tomoy?= =?UTF-8?q?a?= Date: Mon, 29 Dec 2025 20:59:26 +0900 Subject: [PATCH 1/2] fixed parented_window crash --- src/macos/window.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/macos/window.rs b/src/macos/window.rs index 57bca108..79421ea9 100644 --- a/src/macos/window.rs +++ b/src/macos/window.rs @@ -149,12 +149,22 @@ impl<'a> Window<'a> { panic!("Not a macOS window"); }; + let parent_window = if !handle.ns_window.is_null() { + handle.ns_window as *mut Object + } else { + let parent_view = handle.ns_view as id; + unsafe { + let window: id = msg_send![parent_view, window]; + window as *mut Object + } + }; + let ns_view = unsafe { create_view(&options) }; let window_inner = WindowInner { open: Cell::new(true), ns_app: Cell::new(None), - ns_window: Cell::new(None), + ns_window: Cell::new(Some(parent_window)), ns_view, #[cfg(feature = "opengl")] From d73e0b912c8c0f2989db6338fd5f07ec09ff4dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=BE=E6=B5=A6=20=E7=9F=A5=E4=B9=9F=20Matsuura=20Tomoy?= =?UTF-8?q?a?= Date: Mon, 29 Dec 2025 21:14:04 +0900 Subject: [PATCH 2/2] fixed metal layer crash --- src/macos/view.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/macos/view.rs b/src/macos/view.rs index 063ba24c..0360d5b6 100644 --- a/src/macos/view.rs +++ b/src/macos/view.rs @@ -121,6 +121,15 @@ pub(super) unsafe fn create_view(window_options: &WindowOpenOptions) -> id { view.initWithFrame_(NSRect::new(NSPoint::new(0., 0.), NSSize::new(size.width, size.height))); + // Make the view layer-backed and attach a CAMetalLayer so Metal surfaces can be created. + let _: () = msg_send![view, setWantsLayer: YES]; + let metal_layer: id = msg_send![class!(CAMetalLayer), layer]; + let scale: f64 = msg_send![view, backingScaleFactor]; + let bounds: NSRect = msg_send![view, bounds]; + let _: () = msg_send![metal_layer, setContentsScale: scale]; + let _: () = msg_send![metal_layer, setFrame: bounds]; + let _: () = msg_send![view, setLayer: metal_layer]; + register_notification(view, NSWindowDidBecomeKeyNotification, nil); register_notification(view, NSWindowDidResignKeyNotification, nil); @@ -172,6 +181,10 @@ unsafe fn create_view_class() -> &'static Class { sel!(viewWillMoveToWindow:), view_will_move_to_window as extern "C" fn(&Object, Sel, id), ); + class.add_method( + sel!(setFrameSize:), + set_frame_size as extern "C" fn(&Object, Sel, NSSize), + ); class.add_method( sel!(updateTrackingAreas:), 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) { state.window_info.set(new_window_info); state.trigger_event(Event::Window(WindowEvent::Resized(new_window_info))); } + + // Keep the metal layer in sync with scale and bounds changes. + let layer: id = msg_send![this, layer]; + if layer != nil { + let _: () = msg_send![layer, setContentsScale: scale_factor]; + let _: () = msg_send![layer, setFrame: bounds]; + } + } +} + +extern "C" fn set_frame_size(this: &Object, _sel: Sel, size: NSSize) { + unsafe { + // Call through to super to maintain default behavior + let superclass = msg_send![this, superclass]; + let () = msg_send![super(this, superclass), setFrameSize: size]; + + // Keep the attached CAMetalLayer in sync with the view's new bounds/scale + let layer: id = msg_send![this, layer]; + if layer != nil { + let bounds: NSRect = msg_send![this, bounds]; + let scale: f64 = msg_send![this, backingScaleFactor]; + let _: () = msg_send![layer, setFrame: bounds]; + let _: () = msg_send![layer, setContentsScale: scale]; + } } }