Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/vsg/platform/macos/MacOS_Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace vsgMacOS

const char* instanceExtensionSurfaceName() const override { return "VK_MVK_macos_surface"; }

bool valid() const override { return _window; }
bool valid() const override { return _window || _view; }

bool pollEvents(vsg::UIEvents& events) override;

Expand Down
75 changes: 64 additions & 11 deletions src/vsg/platform/macos/MacOS_Window.mm
Original file line number Diff line number Diff line change
Expand Up @@ -708,10 +708,58 @@ void createApplicationMenus(void)
}

MacOS_Window::MacOS_Window(vsg::ref_ptr<vsg::WindowTraits> traits) :
Inherit(traits)
Inherit(traits),
_window(nil),
_view(nil),
_metalLayer(nil)
{
_keyboard = new KeyboardMap;

// When nativeWindow is set, embed into the provided NSView rather than
// creating a standalone NSWindow. This mirrors Win32_Window's handling
// of an external HWND.
if (traits->nativeWindow.has_value())
{
auto nativeHandle = std::any_cast<unsigned long long>(traits->nativeWindow);
if (nativeHandle)
{
NSView* externalView = reinterpret_cast<NSView*>(nativeHandle);
_view = (vsg_MacOS_NSView*)externalView;
[_view setWantsLayer:YES];

_metalLayer = (CAMetalLayer*)[_view layer];
if (!_metalLayer || ![_metalLayer isKindOfClass:[CAMetalLayer class]])
{
_metalLayer = [[CAMetalLayer alloc] init];
if (!_metalLayer)
{
throw Exception{"Error: vsg::MacOS_Window::MacOS_Window(...) failed to create CAMetalLayer for embedded view.", VK_ERROR_INVALID_EXTERNAL_HANDLE};
}
[_view setLayer:_metalLayer];
}

auto devicePixelScale = _traits->hdpi ? [[_view window] backingScaleFactor] : 1.0f;
[_metalLayer setContentsScale:devicePixelScale];

uint32_t finalwidth = traits->width * devicePixelScale;
uint32_t finalheight = traits->height * devicePixelScale;

if (traits->device) share(traits->device);

_extent2D.width = finalwidth;
_extent2D.height = finalheight;

_first_macos_timestamp = [[NSProcessInfo processInfo] systemUptime];
_first_macos_time_point = vsg::clock::now();

vsg::clock::time_point event_time = vsg::clock::now();
bufferedEvents.emplace_back(vsg::ConfigureWindowEvent::create(this, event_time, _traits->x, _traits->y, finalwidth, finalheight));

return;
}
}

// Standalone window path
NSRect contentRect = NSMakeRect(0, 0, traits->width, traits->height);

NSWindowStyleMask styleMask = 0;
Expand Down Expand Up @@ -822,16 +870,20 @@ void createApplicationMenus(void)

bool MacOS_Window::pollEvents(vsg::UIEvents& events)
{
for (;;)
// Skip NSApp event polling when embedded — the host owns the event loop.
if (_window)
{
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES];
if (event == nil)
break;

[NSApp sendEvent:event];
for (;;)
{
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES];
if (event == nil)
break;

[NSApp sendEvent:event];
}
}

return Window::pollEvents(events);
Expand All @@ -841,7 +893,8 @@ void createApplicationMenus(void)
{
const NSRect contentRect = [_view frame];

auto devicePixelScale = _traits->hdpi ? [_window backingScaleFactor] : 1.0f;
NSWindow* hostWindow = _window ? _window : [_view window];
auto devicePixelScale = _traits->hdpi ? [hostWindow backingScaleFactor] : 1.0f;
//[_metalLayer setContentsScale:devicePixelScale];

_extent2D.width = contentRect.size.width * devicePixelScale;
Expand Down
Loading