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.
This commit is contained in:
Camilla Löwy 2019-11-27 23:21:13 +01:00 committed by Camilla Löwy
parent b3544ca43e
commit 6e6805000a
3 changed files with 15 additions and 5 deletions

View File

@ -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: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll - [Cocoa] Bugfix: Window remained on screen after destruction until event poll
(#1412) (#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: The CMake files did not check for the XInput headers (#1480)
- [X11] Bugfix: Key names were not updated when the keyboard layout changed - [X11] Bugfix: Key names were not updated when the keyboard layout changed
(#1462,#1528) (#1462,#1528)

View File

@ -447,9 +447,9 @@ static GLFWbool initializeTIS(void)
- (void)applicationDidFinishLaunching:(NSNotification *)notification - (void)applicationDidFinishLaunching:(NSNotification *)notification
{ {
[NSApp stop:nil]; _glfw.ns.finishedLaunching = GLFW_TRUE;
_glfwPlatformPostEmptyEvent(); _glfwPlatformPostEmptyEvent();
[NSApp stop:nil];
} }
- (void)applicationDidHide:(NSNotification *)notification - (void)applicationDidHide:(NSNotification *)notification

View File

@ -891,10 +891,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
@autoreleasepool { @autoreleasepool {
if (!_glfw.ns.finishedLaunching) if (!_glfw.ns.finishedLaunching)
{
[NSApp run]; [NSApp run];
_glfw.ns.finishedLaunching = GLFW_TRUE;
}
if (!createNativeWindow(window, wndconfig, fbconfig)) if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
@ -1385,6 +1382,9 @@ void _glfwPlatformPollEvents(void)
{ {
@autoreleasepool { @autoreleasepool {
if (!_glfw.ns.finishedLaunching)
[NSApp run];
for (;;) for (;;)
{ {
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
@ -1404,6 +1404,9 @@ void _glfwPlatformWaitEvents(void)
{ {
@autoreleasepool { @autoreleasepool {
if (!_glfw.ns.finishedLaunching)
[NSApp run];
// I wanted to pass NO to dequeue:, and rely on PollEvents to // I wanted to pass NO to dequeue:, and rely on PollEvents to
// dequeue and send. For reasons not at all clear to me, passing // dequeue and send. For reasons not at all clear to me, passing
// NO to dequeue: causes this method never to return. // NO to dequeue: causes this method never to return.
@ -1422,6 +1425,9 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
{ {
@autoreleasepool { @autoreleasepool {
if (!_glfw.ns.finishedLaunching)
[NSApp run];
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout]; NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:date untilDate:date
@ -1439,6 +1445,9 @@ void _glfwPlatformPostEmptyEvent(void)
{ {
@autoreleasepool { @autoreleasepool {
if (!_glfw.ns.finishedLaunching)
[NSApp run];
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0) location:NSMakePoint(0, 0)
modifierFlags:0 modifierFlags:0