From 72366ac9a98ddb3e5b80b91b214e9ec0f0626c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 5 Mar 2020 20:32:19 +0100 Subject: [PATCH] Cocoa: Finish launching NSApp in glfwInit This moves the remaining bits of NSApplication initialization into _glfwPlatformInit. As a side-effect of this, any command-line program initializing GLFW will get a menu bar, which is not ideal. If this has happened to you and a bisect led you here, please see the GLFW_COCOA_MENUBAR init hint introduced in GLFW 3.3. If this patch is a terrible idea, please get in touch in the 3.4 release timeframe. This is a replacement for 6e6805000ac7ddf39c8c5f6be3e877770cba5083, which attempts to preserve the existing menu bar creation behavior for the 3.3-stable branch. Fixes #1649. --- README.md | 3 +++ docs/context.dox | 4 ---- docs/intro.dox | 11 ++++++++--- docs/news.dox | 7 +++++++ include/GLFW/glfw3.h | 15 ++++++++------- src/cocoa_init.m | 8 ++++---- src/cocoa_platform.h | 1 - src/cocoa_window.m | 15 --------------- tests/monitors.c | 2 ++ 9 files changed, 32 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index f8406acc..f63f3efd 100644 --- a/README.md +++ b/README.md @@ -148,12 +148,15 @@ information on what to include when reporting a bug. (#1623) - [Cocoa] Added support for `VK_EXT_metal_surface` (#1619) - [Cocoa] Added locating the Vulkan loader at runtime in an application bundle + - [Cocoa] Moved main menu creation to GLFW initialization time (#1649) - [Cocoa] Removed dependency on the CoreVideo framework - [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) - [Cocoa] Bugfix: Undecorated windows could not be iconified on recent macOS + - [Cocoa] Bugfix: Touching event queue from secondary thread before main thread + would abort (#1649) - [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/docs/context.dox b/docs/context.dox index 69b8fa7f..dd952122 100644 --- a/docs/context.dox +++ b/docs/context.dox @@ -84,10 +84,6 @@ objects are recommended for rendering with such contexts. You should still [process events](@ref events) as long as you have at least one window, even if none of them are visible. -@macos The first time a window is created the menu bar is created. This is not -desirable for example when writing a command-line only application. Menu bar -creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint. - @subsection context_less Windows without contexts diff --git a/docs/intro.dox b/docs/intro.dox index a72b620e..36e33525 100644 --- a/docs/intro.dox +++ b/docs/intro.dox @@ -62,6 +62,11 @@ before the application exits. Modern systems are very good at freeing resources allocated by programs that exit, but GLFW sometimes has to change global system settings and these might not be restored without termination. +@macos When the library is initialized the main menu and dock icon are created. +These are not desirable for a command-line only program. The creation of the +main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init +hint. + @subsection init_hints Initialization hints @@ -97,9 +102,9 @@ the application to the `Contents/Resources` subdirectory of the application's bundle, if present. Set this with @ref glfwInitHint. @anchor GLFW_COCOA_MENUBAR_hint -__GLFW_COCOA_MENUBAR__ specifies whether to create a basic menu bar, either from -a nib or manually, when the first window is created, which is when AppKit is -initialized. Set this with @ref glfwInitHint. +__GLFW_COCOA_MENUBAR__ specifies whether to create the menu bar and dock icon +when GLFW is initialized. This applies whether the menu bar is created from +a nib or manually by GLFW. Set this with @ref glfwInitHint. @subsubsection init_hints_values Supported and default values diff --git a/docs/news.dox b/docs/news.dox index 81af3d1d..4dd72795 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -52,6 +52,13 @@ add_subdirectory(path/to/glfw) @endcode +@subsubsection initmenu_34 macOS main menu now created at initialization + +GLFW now creates the main menu and completes the initialization of NSApplication +during initialization. Programs that do not want a main menu can disable it +with the [GLFW_COCOA_MENUBAR](@ref GLFW_COCOA_MENUBAR_hint) init hint. + + @subsubsection corevideo_34 CoreVideo dependency has been removed GLFW no longer depends on the CoreVideo framework on macOS and it no longer diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index cbff44a0..e5b9b6c6 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1831,6 +1831,14 @@ typedef struct GLFWgamepadstate * bundle, if present. This can be disabled with the @ref * GLFW_COCOA_CHDIR_RESOURCES init hint. * + * @remark @macos This function will create the main menu and dock icon for the + * application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to + * contain a menu bar. Otherwise a minimal menu bar is created manually with + * common commands like Hide, Quit and About. The About entry opens a minimal + * about dialog with information from the application's bundle. The menu bar + * and dock icon can be disabled entirely with the @ref GLFW_COCOA_MENUBAR init + * hint. + * * @remark @x11 This function will set the `LC_CTYPE` category of the * application locale according to the current environment if that category is * still "C". This is because the "C" locale breaks Unicode text input. @@ -2674,13 +2682,6 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) * in the Mac Developer Library. * - * @remark @macos The first time a window is created the menu bar is created. - * If GLFW finds a `MainMenu.nib` it is loaded and assumed to contain a menu - * bar. Otherwise a minimal menu bar is created manually with common commands - * like Hide, Quit and About. The About entry opens a minimal about dialog - * with information from the application's bundle. Menu bar creation can be - * disabled entirely with the @ref GLFW_COCOA_MENUBAR init hint. - * * @remark @macos On OS X 10.10 and later the window frame will not be rendered * at full resolution on Retina displays unless the * [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index cbc9462f..434e5beb 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -447,7 +447,6 @@ static GLFWbool initializeTIS(void) - (void)applicationDidFinishLaunching:(NSNotification *)notification { - _glfw.ns.finishedLaunching = GLFW_TRUE; _glfwPlatformPostEmptyEvent(); [NSApp stop:nil]; } @@ -503,9 +502,6 @@ int _glfwPlatformInit(void) toTarget:_glfw.ns.helper withObject:nil]; - if (NSApp) - _glfw.ns.finishedLaunching = GLFW_TRUE; - [NSApplication sharedApplication]; _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; @@ -558,6 +554,10 @@ int _glfwPlatformInit(void) _glfwInitJoysticksNS(); _glfwPollMonitorsNS(); + + if (![[NSRunningApplication currentApplication] isFinishedLaunching]) + [NSApp run]; + return GLFW_TRUE; } // autoreleasepool diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 9a979af2..90714341 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -141,7 +141,6 @@ typedef struct _GLFWlibraryNS { CGEventSourceRef eventSource; id delegate; - GLFWbool finishedLaunching; GLFWbool cursorHidden; TISInputSourceRef inputSource; IOHIDManagerRef hidManager; diff --git a/src/cocoa_window.m b/src/cocoa_window.m index e12b5cda..c50bf21a 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -884,9 +884,6 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - if (!createNativeWindow(window, wndconfig, fbconfig)) return GLFW_FALSE; @@ -1377,9 +1374,6 @@ void _glfwPlatformPollEvents(void) { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - for (;;) { NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny @@ -1399,9 +1393,6 @@ 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. @@ -1420,9 +1411,6 @@ void _glfwPlatformWaitEventsTimeout(double timeout) { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout]; NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:date @@ -1440,9 +1428,6 @@ void _glfwPlatformPostEmptyEvent(void) { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined location:NSMakePoint(0, 0) modifierFlags:0 diff --git a/tests/monitors.c b/tests/monitors.c index 2b75d7b1..c66950bf 100644 --- a/tests/monitors.c +++ b/tests/monitors.c @@ -241,6 +241,8 @@ int main(int argc, char** argv) glfwSetErrorCallback(error_callback); + glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE); + if (!glfwInit()) exit(EXIT_FAILURE);