@@ -708,10 +708,58 @@ void createApplicationMenus(void)
708708}
709709
710710MacOS_Window::MacOS_Window (vsg::ref_ptr<vsg::WindowTraits> traits) :
711- Inherit(traits)
711+ Inherit(traits),
712+ _window(nil ),
713+ _view(nil ),
714+ _metalLayer(nil )
712715{
713716 _keyboard = new KeyboardMap;
714717
718+ // When nativeWindow is set, embed into the provided NSView rather than
719+ // creating a standalone NSWindow. This mirrors Win32_Window's handling
720+ // of an external HWND.
721+ if (traits->nativeWindow .has_value ())
722+ {
723+ auto nativeHandle = std::any_cast<unsigned long long >(traits->nativeWindow );
724+ if (nativeHandle)
725+ {
726+ NSView * externalView = reinterpret_cast <NSView *>(nativeHandle);
727+ _view = (vsg_MacOS_NSView*)externalView;
728+ [_view setWantsLayer: YES ];
729+
730+ _metalLayer = (CAMetalLayer *)[_view layer ];
731+ if (!_metalLayer || ![_metalLayer isKindOfClass: [CAMetalLayer class ]])
732+ {
733+ _metalLayer = [[CAMetalLayer alloc ] init ];
734+ if (!_metalLayer)
735+ {
736+ throw Exception{" Error: vsg::MacOS_Window::MacOS_Window(...) failed to create CAMetalLayer for embedded view." , VK_ERROR_INVALID_EXTERNAL_HANDLE};
737+ }
738+ [_view setLayer: _metalLayer];
739+ }
740+
741+ auto devicePixelScale = _traits->hdpi ? [[_view window ] backingScaleFactor ] : 1 .0f ;
742+ [_metalLayer setContentsScale: devicePixelScale];
743+
744+ uint32_t finalwidth = traits->width * devicePixelScale;
745+ uint32_t finalheight = traits->height * devicePixelScale;
746+
747+ if (traits->device ) share (traits->device );
748+
749+ _extent2D.width = finalwidth;
750+ _extent2D.height = finalheight;
751+
752+ _first_macos_timestamp = [[NSProcessInfo processInfo ] systemUptime ];
753+ _first_macos_time_point = vsg::clock::now ();
754+
755+ vsg::clock::time_point event_time = vsg::clock::now ();
756+ bufferedEvents.emplace_back (vsg::ConfigureWindowEvent::create (this , event_time, _traits->x , _traits->y , finalwidth, finalheight));
757+
758+ return ;
759+ }
760+ }
761+
762+ // Standalone window path
715763 NSRect contentRect = NSMakeRect (0 , 0 , traits->width , traits->height );
716764
717765 NSWindowStyleMask styleMask = 0 ;
@@ -822,16 +870,20 @@ void createApplicationMenus(void)
822870
823871bool MacOS_Window::pollEvents (vsg::UIEvents& events)
824872{
825- for (;;)
873+ // Skip NSApp event polling when embedded — the host owns the event loop.
874+ if (_window)
826875 {
827- NSEvent * event = [NSApp nextEventMatchingMask: NSEventMaskAny
828- untilDate: [NSDate distantPast ]
829- inMode: NSDefaultRunLoopMode
830- dequeue: YES ];
831- if (event == nil )
832- break ;
833-
834- [NSApp sendEvent: event];
876+ for (;;)
877+ {
878+ NSEvent * event = [NSApp nextEventMatchingMask: NSEventMaskAny
879+ untilDate: [NSDate distantPast ]
880+ inMode: NSDefaultRunLoopMode
881+ dequeue: YES ];
882+ if (event == nil )
883+ break ;
884+
885+ [NSApp sendEvent: event];
886+ }
835887 }
836888
837889 return Window::pollEvents (events);
@@ -841,7 +893,8 @@ void createApplicationMenus(void)
841893{
842894 const NSRect contentRect = [_view frame ];
843895
844- auto devicePixelScale = _traits->hdpi ? [_window backingScaleFactor ] : 1 .0f ;
896+ NSWindow * hostWindow = _window ? _window : [_view window ];
897+ auto devicePixelScale = _traits->hdpi ? [hostWindow backingScaleFactor ] : 1 .0f ;
845898 // [_metalLayer setContentsScale:devicePixelScale];
846899
847900 _extent2D.width = contentRect.size .width * devicePixelScale;
0 commit comments