diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f230d90..4e8d46fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,11 +40,6 @@ if (WIN32) option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF) endif() -if (APPLE) - option(GLFW_USE_CHDIR "Make glfwInit chdir to Contents/Resources" ON) - option(GLFW_USE_MENUBAR "Populate the menu bar on first window creation" ON) -endif() - if (UNIX AND NOT APPLE) option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF) option(GLFW_USE_MIR "Use Mir for window creation" OFF) @@ -335,14 +330,6 @@ endif() #-------------------------------------------------------------------- if (_GLFW_COCOA) - if (GLFW_USE_MENUBAR) - set(_GLFW_USE_MENUBAR 1) - endif() - - if (GLFW_USE_CHDIR) - set(_GLFW_USE_CHDIR 1) - endif() - list(APPEND glfw_LIBRARIES "-framework Cocoa" "-framework IOKit" diff --git a/README.md b/README.md index 90b77025..35a133f9 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ information on what to include when reporting a bug. - Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for receiving window maximization events (#778) - Added `glfwSetWindowAttrib` function for changing window attributes (#537) +- Added `glfwInitHint` function for setting library initialization hints - Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850) - Added definition of `GLAPIENTRY` to public header - Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering @@ -134,10 +135,14 @@ information on what to include when reporting a bug. - Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint - Added macOS specific `GLFW_COCOA_FRAME_AUTOSAVE` window hint (#195) - Added macOS specific `GLFW_COCOA_GRAPHICS_SWITCHING` window hint (#377,#935) +- Added macOS specific `GLFW_COCOA_CHDIR_RESOURCES` init hint +- Added macOS specific `GLFW_COCOA_MENUBAR` init hint - Added `GLFW_INCLUDE_ES32` for including the OpenGL ES 3.2 header - Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with [OSMesa](https://www.mesa3d.org/osmesa.html) (#281) - Removed `GLFW_USE_RETINA` compile-time option +- Removed `GLFW_USE_CHDIR` compile-time option +- Removed `GLFW_USE_MENUBAR` compile-time option - Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored - Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding OpenGL and OpenGL ES header macros diff --git a/docs/compile.dox b/docs/compile.dox index 6ac2432d..75f938ca 100644 --- a/docs/compile.dox +++ b/docs/compile.dox @@ -219,17 +219,6 @@ __GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked statically into the application. -@subsubsection compile_options_osx macOS specific CMake options - -@anchor GLFW_USE_CHDIR -__GLFW_USE_CHDIR__ determines whether @ref glfwInit changes the current -directory of bundled applications to the `Contents/Resources` directory. - -@anchor GLFW_USE_MENUBAR -__GLFW_USE_MENUBAR__ determines whether the first call to @ref glfwCreateWindow -sets up a minimal menu bar. - - @subsubsection compile_options_win32 Windows specific CMake options @anchor USE_MSVC_RUNTIME_LIBRARY_DLL @@ -281,14 +270,6 @@ For the EGL context creation API, the following options are available: - @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle definitions (fallback) -If you are using the Cocoa window creation API, the following options are -available: - - - @b _GLFW_USE_CHDIR to `chdir` to the `Resources` subdirectory of the - application bundle during @ref glfwInit (recommended) - - @b _GLFW_USE_MENUBAR to create and populate the menu bar when the first window - is created (recommended) - @note None of the @ref build_macros may be defined during the compilation of GLFW. If you define any of these in your build files, make sure they are not applied to the GLFW sources. diff --git a/docs/context.dox b/docs/context.dox index 22e6f513..9aa72a5c 100644 --- a/docs/context.dox +++ b/docs/context.dox @@ -84,10 +84,9 @@ 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 populated with -common commands like Hide, Quit and About. This is not desirable for example -when writing a command-line only application. The menu bar setup can be -disabled with a [compile-time option](@ref compile_options_osx). +@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 0852d145..70ed2d16 100644 --- a/docs/intro.dox +++ b/docs/intro.dox @@ -31,6 +31,7 @@ successfully initialized, and only from the main thread. - @ref glfwGetVersion - @ref glfwGetVersionString - @ref glfwSetErrorCallback + - @ref glfwInitHint - @ref glfwInit - @ref glfwTerminate @@ -61,6 +62,42 @@ allocated by programs that simply exit, but GLFW sometimes has to change global system settings and these might not be restored without termination. +@subsection init_hints Initialization hints + +There are a number of hints that can be set before initialization, that affect +how the library behaves. + +The values you set are not affected by initialization or termination, but they +are only read during initialization. Once GLFW has been initialized, setting +new hint values will not affect behavior until the next time it is terminated +and initialized. + +Some hints are platform specific. These are always valid to set on any +platform but they will only affect their specific platform. Other platforms +will simply ignore them. Setting these hints requires no platform specific +headers or calls. + + +@subsubsection init_hints_osx macOS specific hints + +@anchor GLFW_COCOA_CHDIR_RESOURCES +__GLFW_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to +the application to the `Contents/Resources` subdirectory of the application's +bundle, if present. + +@anchor GLFW_COCOA_MENUBAR +__GLFW_COCOA_MENUBAR__ specifies whether to create a basic menu bar when the +first window is created, which is when AppKit is initialized. + + +@subsubsection init_hints_values Supported and default values + +Init hint | Default value | Supported values +------------------------------- | ------------- | ---------------- +@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` + + @subsection intro_init_terminate Terminating GLFW Before your application exits, you should terminate the GLFW library if it has diff --git a/docs/news.dox b/docs/news.dox index 4df382c2..6c089756 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -25,6 +25,14 @@ GLFW now supports changing the [GLFW_DECORATED](@ref GLFW_DECORATED_attrib), windows with @ref glfwSetWindowAttrib. +@subsection news_33_inithint Support for initialization hints + +GLFW now supports setting library initialization hints with @ref glfwInitHint. +Currently the macOS specific @ref +GLFW_COCOA_CHDIR_RESOURCES and @ref GLFW_COCOA_MENUBAR init hints are supported, +replacing the corresponding compile-time options. + + @subsection news_33_centercursor Cursor centering window hint GLFW now supports controlling whether the cursor is centered over newly created diff --git a/examples/offscreen.c b/examples/offscreen.c index 26dba0f5..b19de0de 100644 --- a/examples/offscreen.c +++ b/examples/offscreen.c @@ -87,6 +87,8 @@ int main(void) glfwSetErrorCallback(error_callback); + glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE); + if (!glfwInit()) exit(EXIT_FAILURE); diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 99732a54..d6983bcf 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -926,6 +926,12 @@ extern "C" { #define GLFW_CONNECTED 0x00040001 #define GLFW_DISCONNECTED 0x00040002 +/*! @addtogroup init + * @{ */ +#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001 +#define GLFW_COCOA_MENUBAR 0x00051002 +/*! @} */ + #define GLFW_DONT_CARE -1 @@ -1445,8 +1451,8 @@ typedef struct GLFWimage * * @remark @macos This function will change the current directory of the * application to the `Contents/Resources` subdirectory of the application's - * bundle, if present. This can be disabled with a - * [compile-time option](@ref compile_options_osx). + * bundle, if present. This can be disabled with the @ref + * GLFW_COCOA_CHDIR_RESOURCES init hint. * * @thread_safety This function must only be called from the main thread. * @@ -1491,6 +1497,39 @@ GLFWAPI int glfwInit(void); */ GLFWAPI void glfwTerminate(void); +/*! @brief Sets the specified init hint to the desired value. + * + * This function sets hints for the next initialization of GLFW. + * + * The values you set are not affected by initialization or termination, but + * they are only read during initialization. Once GLFW has been initialized, + * setting new hint values will not affect behavior until the next time the + * library is terminated and initialized. + * + * Some hints are platform specific. These are always valid to set on any + * platform but they will only affect their specific platform. Other platforms + * will simply ignore them. Setting these hints requires no platform specific + * headers or calls. + * + * @param[in] hint The [init hint](@ref init_hints) to set. + * @param[in] value The new value of the init hint. + * + * @errors Possible errors include @ref GLFW_INVALID_ENUM and @ref + * GLFW_INVALID_VALUE. + * + * @remarks This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa init_hints + * @sa glfwInit + * + * @since Added in version 3.3. + * + * @ingroup init + */ +GLFWAPI void glfwInitHint(int hint, int value); + /*! @brief Retrieves the version of the GLFW library. * * This function retrieves the major, minor and revision numbers of the GLFW @@ -2049,8 +2088,7 @@ GLFWAPI void glfwWindowHint(int hint, int value); * @remark @macos The first time a window is created the menu bar is populated * 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 can be disabled with a - * [compile-time option](@ref compile_options_osx). + * menu bar can be disabled 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 diff --git a/src/cocoa_init.m b/src/cocoa_init.m index f029f50a..0913c476 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -28,8 +28,6 @@ #include // For MAXPATHLEN -#if defined(_GLFW_USE_CHDIR) - // Change to our application bundle's resources directory, if present // static void changeToResourcesDirectory(void) @@ -66,8 +64,6 @@ static void changeToResourcesDirectory(void) chdir(resourcesPath); } -#endif /* _GLFW_USE_CHDIR */ - // Create key code translation tables // static void createKeyTables(void) @@ -294,6 +290,9 @@ int _glfwPlatformInit(void) { _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; + if (_glfw.hints.init.ns.chdir) + changeToResourcesDirectory(); + _glfw.ns.listener = [[GLFWLayoutListener alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:_glfw.ns.listener @@ -301,10 +300,6 @@ int _glfwPlatformInit(void) name:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil]; -#if defined(_GLFW_USE_CHDIR) - changeToResourcesDirectory(); -#endif - createKeyTables(); _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); @@ -376,12 +371,6 @@ void _glfwPlatformTerminate(void) const char* _glfwPlatformGetVersionString(void) { return _GLFW_VERSION_NUMBER " Cocoa NSGL" -#if defined(_GLFW_USE_CHDIR) - " chdir" -#endif -#if defined(_GLFW_USE_MENUBAR) - " menubar" -#endif #if defined(_GLFW_BUILD_DLL) " dynamic" #endif diff --git a/src/cocoa_window.m b/src/cocoa_window.m index c2358a35..84c44148 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -811,8 +811,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } @end -#if defined(_GLFW_USE_MENUBAR) - // Try to figure out what the calling application is called // static NSString* findAppName(void) @@ -922,8 +920,6 @@ static void createMenuBar(void) [NSApp performSelector:setAppleMenuSelector withObject:appMenu]; } -#endif /* _GLFW_USE_MENUBAR */ - // Initialize the Cocoa Application Kit // static GLFWbool initializeAppKit(void) @@ -939,15 +935,16 @@ static GLFWbool initializeAppKit(void) toTarget:NSApp withObject:nil]; - // In case we are unbundled, make us a proper UI application - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + if (_glfw.hints.init.ns.menubar) + { + // In case we are unbundled, make us a proper UI application + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; -#if defined(_GLFW_USE_MENUBAR) - // Menu bar setup must go between sharedApplication above and - // finishLaunching below, in order to properly emulate the behavior - // of NSApplicationMain - createMenuBar(); -#endif + // Menu bar setup must go between sharedApplication above and + // finishLaunching below, in order to properly emulate the behavior + // of NSApplicationMain + createMenuBar(); + } // There can only be one application delegate, but we allocate it the // first time a window is created to keep all window code in this file diff --git a/src/glfw_config.h.in b/src/glfw_config.h.in index 822814e4..bc9f5d3e 100644 --- a/src/glfw_config.h.in +++ b/src/glfw_config.h.in @@ -55,8 +55,3 @@ // Define this to 1 to force use of high-performance GPU on hybrid systems #cmakedefine _GLFW_USE_HYBRID_HPG -// Define this to 1 if glfwInit should change the current directory -#cmakedefine _GLFW_USE_CHDIR -// Define this to 1 if glfwCreateWindow should populate the menu bar -#cmakedefine _GLFW_USE_MENUBAR - diff --git a/src/init.c b/src/init.c index c66b5f27..478b1211 100644 --- a/src/init.c +++ b/src/init.c @@ -40,11 +40,17 @@ // _GLFWlibrary _glfw = { GLFW_FALSE }; -// This is outside of _glfw so it can be initialized and usable before -// glfwInit is called, which lets that function report errors +// These are outside of _glfw so they can be used before initialization and +// after termination // -static GLFWerrorfun _glfwErrorCallback = NULL; - +static GLFWerrorfun _glfwErrorCallback; +static _GLFWinitconfig _glfwInitHints = +{ + { + GLFW_TRUE, // menubar + GLFW_TRUE // chdir + } +}; // Returns a generic string representation of the specified error // @@ -153,6 +159,7 @@ GLFWAPI int glfwInit(void) return GLFW_TRUE; memset(&_glfw, 0, sizeof(_glfw)); + _glfw.hints.init = _glfwInitHints; if (!_glfwPlatformInit()) { @@ -177,6 +184,21 @@ GLFWAPI void glfwTerminate(void) terminate(); } +GLFWAPI void glfwInitHint(int hint, int value) +{ + switch (hint) + { + case GLFW_COCOA_CHDIR_RESOURCES: + _glfwInitHints.ns.chdir = value; + return; + case GLFW_COCOA_MENUBAR: + _glfwInitHints.ns.menubar = value; + return; + } + + _glfwInputError(GLFW_INVALID_ENUM, "Invalid init hint %i", hint); +} + GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev) { if (major != NULL) diff --git a/src/internal.h b/src/internal.h index e026e721..f43638df 100644 --- a/src/internal.h +++ b/src/internal.h @@ -59,6 +59,7 @@ typedef int GLFWbool; +typedef struct _GLFWinitconfig _GLFWinitconfig; typedef struct _GLFWwndconfig _GLFWwndconfig; typedef struct _GLFWctxconfig _GLFWctxconfig; typedef struct _GLFWfbconfig _GLFWfbconfig; @@ -259,6 +260,18 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void); // Platform-independent structures //======================================================================== +/*! @brief Initialization configuration. + * + * Parameters relating to the initialization of the library. + */ +struct _GLFWinitconfig +{ + struct { + GLFWbool menubar; + GLFWbool chdir; + } ns; +}; + /*! @brief Window configuration. * * Parameters relating to the creation of the window but not directly related @@ -476,6 +489,7 @@ struct _GLFWlibrary GLFWbool initialized; struct { + _GLFWinitconfig init; _GLFWfbconfig framebuffer; _GLFWwndconfig window; _GLFWctxconfig context; diff --git a/src/window.c b/src/window.c index 023cb13f..d16f75c5 100644 --- a/src/window.c +++ b/src/window.c @@ -237,15 +237,15 @@ void glfwDefaultWindowHints(void) { _GLFW_REQUIRE_INIT(); - memset(&_glfw.hints, 0, sizeof(_glfw.hints)); - // The default is OpenGL with minimum version 1.0 + memset(&_glfw.hints.context, 0, sizeof(_glfw.hints.context)); _glfw.hints.context.client = GLFW_OPENGL_API; _glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API; _glfw.hints.context.major = 1; _glfw.hints.context.minor = 0; // The default is a focused, visible, resizable window with decorations + memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window)); _glfw.hints.window.resizable = GLFW_TRUE; _glfw.hints.window.visible = GLFW_TRUE; _glfw.hints.window.decorated = GLFW_TRUE; @@ -254,6 +254,7 @@ void glfwDefaultWindowHints(void) // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, // double buffered + memset(&_glfw.hints.framebuffer, 0, sizeof(_glfw.hints.framebuffer)); _glfw.hints.framebuffer.redBits = 8; _glfw.hints.framebuffer.greenBits = 8; _glfw.hints.framebuffer.blueBits = 8; diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 2e492a5c..47e22077 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -411,6 +411,8 @@ int main(int argc, char** argv) glfwSetErrorCallback(error_callback); + glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE); + if (!glfwInit()) exit(EXIT_FAILURE);