Add glfwInitHint

This allows setting hints that control how the library is initialized,
transforming more compile-time options into run-time ones.
This commit is contained in:
Camilla Löwy 2017-02-14 15:43:31 +01:00
parent 071a049f07
commit 6d9a58bfef
15 changed files with 154 additions and 77 deletions

View File

@ -40,11 +40,6 @@ if (WIN32)
option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF) option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF)
endif() 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) if (UNIX AND NOT APPLE)
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF) option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
option(GLFW_USE_MIR "Use Mir for window creation" OFF) option(GLFW_USE_MIR "Use Mir for window creation" OFF)
@ -335,14 +330,6 @@ endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
if (_GLFW_COCOA) 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 list(APPEND glfw_LIBRARIES
"-framework Cocoa" "-framework Cocoa"
"-framework IOKit" "-framework IOKit"

View File

@ -127,6 +127,7 @@ information on what to include when reporting a bug.
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for - Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
receiving window maximization events (#778) receiving window maximization events (#778)
- Added `glfwSetWindowAttrib` function for changing window attributes (#537) - 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 headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850)
- Added definition of `GLAPIENTRY` to public header - Added definition of `GLAPIENTRY` to public header
- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering - 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_RETINA_FRAMEBUFFER` window hint
- Added macOS specific `GLFW_COCOA_FRAME_AUTOSAVE` window hint (#195) - 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_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_INCLUDE_ES32` for including the OpenGL ES 3.2 header
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with - Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281) [OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
- Removed `GLFW_USE_RETINA` compile-time option - 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: Calling `glfwMaximizeWindow` on a full screen window was not ignored
- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding - Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
OpenGL and OpenGL ES header macros OpenGL and OpenGL ES header macros

View File

@ -219,17 +219,6 @@ __GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked
statically into the application. 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 @subsubsection compile_options_win32 Windows specific CMake options
@anchor USE_MSVC_RUNTIME_LIBRARY_DLL @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 - @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle
definitions (fallback) 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 @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 GLFW. If you define any of these in your build files, make sure they are not
applied to the GLFW sources. applied to the GLFW sources.

View File

@ -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 You should still [process events](@ref events) as long as you have at least one
window, even if none of them are visible. window, even if none of them are visible.
@macos The first time a window is created the menu bar is populated with @macos The first time a window is created the menu bar is created. This is not
common commands like Hide, Quit and About. This is not desirable for example desirable for example when writing a command-line only application. Menu bar
when writing a command-line only application. The menu bar setup can be creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
disabled with a [compile-time option](@ref compile_options_osx).
@subsection context_less Windows without contexts @subsection context_less Windows without contexts

View File

@ -31,6 +31,7 @@ successfully initialized, and only from the main thread.
- @ref glfwGetVersion - @ref glfwGetVersion
- @ref glfwGetVersionString - @ref glfwGetVersionString
- @ref glfwSetErrorCallback - @ref glfwSetErrorCallback
- @ref glfwInitHint
- @ref glfwInit - @ref glfwInit
- @ref glfwTerminate - @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. 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 @subsection intro_init_terminate Terminating GLFW
Before your application exits, you should terminate the GLFW library if it has Before your application exits, you should terminate the GLFW library if it has

View File

@ -25,6 +25,14 @@ GLFW now supports changing the [GLFW_DECORATED](@ref GLFW_DECORATED_attrib),
windows with @ref glfwSetWindowAttrib. 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 @subsection news_33_centercursor Cursor centering window hint
GLFW now supports controlling whether the cursor is centered over newly created GLFW now supports controlling whether the cursor is centered over newly created

View File

@ -87,6 +87,8 @@ int main(void)
glfwSetErrorCallback(error_callback); glfwSetErrorCallback(error_callback);
glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
if (!glfwInit()) if (!glfwInit())
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -926,6 +926,12 @@ extern "C" {
#define GLFW_CONNECTED 0x00040001 #define GLFW_CONNECTED 0x00040001
#define GLFW_DISCONNECTED 0x00040002 #define GLFW_DISCONNECTED 0x00040002
/*! @addtogroup init
* @{ */
#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
#define GLFW_COCOA_MENUBAR 0x00051002
/*! @} */
#define GLFW_DONT_CARE -1 #define GLFW_DONT_CARE -1
@ -1445,8 +1451,8 @@ typedef struct GLFWimage
* *
* @remark @macos This function will change the current directory of the * @remark @macos This function will change the current directory of the
* application to the `Contents/Resources` subdirectory of the application's * application to the `Contents/Resources` subdirectory of the application's
* bundle, if present. This can be disabled with a * bundle, if present. This can be disabled with the @ref
* [compile-time option](@ref compile_options_osx). * GLFW_COCOA_CHDIR_RESOURCES init hint.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
@ -1491,6 +1497,39 @@ GLFWAPI int glfwInit(void);
*/ */
GLFWAPI void glfwTerminate(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. /*! @brief Retrieves the version of the GLFW library.
* *
* This function retrieves the major, minor and revision numbers of the GLFW * 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 * @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 * with common commands like Hide, Quit and About. The About entry opens
* a minimal about dialog with information from the application's bundle. The * a minimal about dialog with information from the application's bundle. The
* menu bar can be disabled with a * menu bar can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
* [compile-time option](@ref compile_options_osx).
* *
* @remark @macos On OS X 10.10 and later the window frame will not be rendered * @remark @macos On OS X 10.10 and later the window frame will not be rendered
* at full resolution on Retina displays unless the * at full resolution on Retina displays unless the

View File

@ -28,8 +28,6 @@
#include <sys/param.h> // For MAXPATHLEN #include <sys/param.h> // For MAXPATHLEN
#if defined(_GLFW_USE_CHDIR)
// Change to our application bundle's resources directory, if present // Change to our application bundle's resources directory, if present
// //
static void changeToResourcesDirectory(void) static void changeToResourcesDirectory(void)
@ -66,8 +64,6 @@ static void changeToResourcesDirectory(void)
chdir(resourcesPath); chdir(resourcesPath);
} }
#endif /* _GLFW_USE_CHDIR */
// Create key code translation tables // Create key code translation tables
// //
static void createKeyTables(void) static void createKeyTables(void)
@ -294,6 +290,9 @@ int _glfwPlatformInit(void)
{ {
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
if (_glfw.hints.init.ns.chdir)
changeToResourcesDirectory();
_glfw.ns.listener = [[GLFWLayoutListener alloc] init]; _glfw.ns.listener = [[GLFWLayoutListener alloc] init];
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
addObserver:_glfw.ns.listener addObserver:_glfw.ns.listener
@ -301,10 +300,6 @@ int _glfwPlatformInit(void)
name:NSTextInputContextKeyboardSelectionDidChangeNotification name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil]; object:nil];
#if defined(_GLFW_USE_CHDIR)
changeToResourcesDirectory();
#endif
createKeyTables(); createKeyTables();
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
@ -376,12 +371,6 @@ void _glfwPlatformTerminate(void)
const char* _glfwPlatformGetVersionString(void) const char* _glfwPlatformGetVersionString(void)
{ {
return _GLFW_VERSION_NUMBER " Cocoa NSGL" 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) #if defined(_GLFW_BUILD_DLL)
" dynamic" " dynamic"
#endif #endif

View File

@ -811,8 +811,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
} }
@end @end
#if defined(_GLFW_USE_MENUBAR)
// Try to figure out what the calling application is called // Try to figure out what the calling application is called
// //
static NSString* findAppName(void) static NSString* findAppName(void)
@ -922,8 +920,6 @@ static void createMenuBar(void)
[NSApp performSelector:setAppleMenuSelector withObject:appMenu]; [NSApp performSelector:setAppleMenuSelector withObject:appMenu];
} }
#endif /* _GLFW_USE_MENUBAR */
// Initialize the Cocoa Application Kit // Initialize the Cocoa Application Kit
// //
static GLFWbool initializeAppKit(void) static GLFWbool initializeAppKit(void)
@ -939,15 +935,16 @@ static GLFWbool initializeAppKit(void)
toTarget:NSApp toTarget:NSApp
withObject:nil]; withObject:nil];
// In case we are unbundled, make us a proper UI application if (_glfw.hints.init.ns.menubar)
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; {
// 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
// Menu bar setup must go between sharedApplication above and // finishLaunching below, in order to properly emulate the behavior
// finishLaunching below, in order to properly emulate the behavior // of NSApplicationMain
// of NSApplicationMain createMenuBar();
createMenuBar(); }
#endif
// There can only be one application delegate, but we allocate it the // 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 // first time a window is created to keep all window code in this file

View File

@ -55,8 +55,3 @@
// Define this to 1 to force use of high-performance GPU on hybrid systems // Define this to 1 to force use of high-performance GPU on hybrid systems
#cmakedefine _GLFW_USE_HYBRID_HPG #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

View File

@ -40,11 +40,17 @@
// //
_GLFWlibrary _glfw = { GLFW_FALSE }; _GLFWlibrary _glfw = { GLFW_FALSE };
// This is outside of _glfw so it can be initialized and usable before // These are outside of _glfw so they can be used before initialization and
// glfwInit is called, which lets that function report errors // 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 // Returns a generic string representation of the specified error
// //
@ -153,6 +159,7 @@ GLFWAPI int glfwInit(void)
return GLFW_TRUE; return GLFW_TRUE;
memset(&_glfw, 0, sizeof(_glfw)); memset(&_glfw, 0, sizeof(_glfw));
_glfw.hints.init = _glfwInitHints;
if (!_glfwPlatformInit()) if (!_glfwPlatformInit())
{ {
@ -177,6 +184,21 @@ GLFWAPI void glfwTerminate(void)
terminate(); 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) GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
{ {
if (major != NULL) if (major != NULL)

View File

@ -59,6 +59,7 @@
typedef int GLFWbool; typedef int GLFWbool;
typedef struct _GLFWinitconfig _GLFWinitconfig;
typedef struct _GLFWwndconfig _GLFWwndconfig; typedef struct _GLFWwndconfig _GLFWwndconfig;
typedef struct _GLFWctxconfig _GLFWctxconfig; typedef struct _GLFWctxconfig _GLFWctxconfig;
typedef struct _GLFWfbconfig _GLFWfbconfig; typedef struct _GLFWfbconfig _GLFWfbconfig;
@ -259,6 +260,18 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
// Platform-independent structures // 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. /*! @brief Window configuration.
* *
* Parameters relating to the creation of the window but not directly related * Parameters relating to the creation of the window but not directly related
@ -476,6 +489,7 @@ struct _GLFWlibrary
GLFWbool initialized; GLFWbool initialized;
struct { struct {
_GLFWinitconfig init;
_GLFWfbconfig framebuffer; _GLFWfbconfig framebuffer;
_GLFWwndconfig window; _GLFWwndconfig window;
_GLFWctxconfig context; _GLFWctxconfig context;

View File

@ -237,15 +237,15 @@ void glfwDefaultWindowHints(void)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
memset(&_glfw.hints, 0, sizeof(_glfw.hints));
// The default is OpenGL with minimum version 1.0 // 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.client = GLFW_OPENGL_API;
_glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API; _glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
_glfw.hints.context.major = 1; _glfw.hints.context.major = 1;
_glfw.hints.context.minor = 0; _glfw.hints.context.minor = 0;
// The default is a focused, visible, resizable window with decorations // 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.resizable = GLFW_TRUE;
_glfw.hints.window.visible = GLFW_TRUE; _glfw.hints.window.visible = GLFW_TRUE;
_glfw.hints.window.decorated = 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, // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
// double buffered // double buffered
memset(&_glfw.hints.framebuffer, 0, sizeof(_glfw.hints.framebuffer));
_glfw.hints.framebuffer.redBits = 8; _glfw.hints.framebuffer.redBits = 8;
_glfw.hints.framebuffer.greenBits = 8; _glfw.hints.framebuffer.greenBits = 8;
_glfw.hints.framebuffer.blueBits = 8; _glfw.hints.framebuffer.blueBits = 8;

View File

@ -411,6 +411,8 @@ int main(int argc, char** argv)
glfwSetErrorCallback(error_callback); glfwSetErrorCallback(error_callback);
glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
if (!glfwInit()) if (!glfwInit())
exit(EXIT_FAILURE); exit(EXIT_FAILURE);