From 6e6805000ac7ddf39c8c5f6be3e877770cba5083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 27 Nov 2019 23:21:13 +0100 Subject: [PATCH] Cocoa: Fix pre-window-creation event processing Polling the event queue before NSApp had been allowed to finish launching, in our case by starting our self-terminating run loop, triggered an assertion inside NSApplication. This fix, which makes all event processing functions capable of starting it, makes that assertion less likely. A more Cocoa-friendly fix would be to finish launching NSApp during glfwInit and let people annoyed by the menu bar disabled it with GLFW_COCOA_MENUBAR. That may not be suitable for 3.3-stable, though. Fixes #1543. --- README.md | 1 + src/cocoa_init.m | 4 ++-- src/cocoa_window.m | 15 ++++++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index daa1be9c..57206a06 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553) - [Cocoa] Bugfix: Window remained on screen after destruction until event poll (#1412) + - [Cocoa] Bugfix: Event processing before window creation would assert (#1543) - [X11] Bugfix: The CMake files did not check for the XInput headers (#1480) - [X11] Bugfix: Key names were not updated when the keyboard layout changed (#1462,#1528) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 70e45216..7e75299a 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -447,9 +447,9 @@ static GLFWbool initializeTIS(void) - (void)applicationDidFinishLaunching:(NSNotification *)notification { - [NSApp stop:nil]; - + _glfw.ns.finishedLaunching = GLFW_TRUE; _glfwPlatformPostEmptyEvent(); + [NSApp stop:nil]; } - (void)applicationDidHide:(NSNotification *)notification diff --git a/src/cocoa_window.m b/src/cocoa_window.m index bfec8b7b..3d55d6d7 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -891,10 +891,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, @autoreleasepool { if (!_glfw.ns.finishedLaunching) - { [NSApp run]; - _glfw.ns.finishedLaunching = GLFW_TRUE; - } if (!createNativeWindow(window, wndconfig, fbconfig)) return GLFW_FALSE; @@ -1385,6 +1382,9 @@ void _glfwPlatformPollEvents(void) { @autoreleasepool { + if (!_glfw.ns.finishedLaunching) + [NSApp run]; + for (;;) { NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny @@ -1404,6 +1404,9 @@ void _glfwPlatformWaitEvents(void) { @autoreleasepool { + if (!_glfw.ns.finishedLaunching) + [NSApp run]; + // I wanted to pass NO to dequeue:, and rely on PollEvents to // dequeue and send. For reasons not at all clear to me, passing // NO to dequeue: causes this method never to return. @@ -1422,6 +1425,9 @@ void _glfwPlatformWaitEventsTimeout(double timeout) { @autoreleasepool { + if (!_glfw.ns.finishedLaunching) + [NSApp run]; + NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout]; NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:date @@ -1439,6 +1445,9 @@ void _glfwPlatformPostEmptyEvent(void) { @autoreleasepool { + if (!_glfw.ns.finishedLaunching) + [NSApp run]; + NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined location:NSMakePoint(0, 0) modifierFlags:0