From 88c5edb40925bc0c987e8cfc7d306174f8094453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 24 Dec 2018 23:31:58 +0100 Subject: [PATCH 01/43] Cocoa: Remove subclassing of NSApplication This removes the GLFW NSApplication subclass as a step towards better coexistence with other libraries that touch Cocoa. This moves application object creation to platform init to allow event processing before window creation. Related to #1317. --- src/cocoa_init.m | 49 +++++++++++++++----- src/cocoa_platform.h | 4 +- src/cocoa_window.m | 105 +++++++++++-------------------------------- 3 files changed, 67 insertions(+), 91 deletions(-) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 01a746bae..f3c479578 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -27,6 +27,10 @@ #include "internal.h" #include // For MAXPATHLEN +#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 + #define NSEventMaskKeyUp NSKeyUpMask + #define NSEventModifierFlagCommand NSCommandKeyMask +#endif // Change to our application bundle's resources directory, if present // @@ -271,17 +275,21 @@ static GLFWbool initializeTIS(void) return updateUnicodeDataNS(); } -@interface GLFWLayoutListener : NSObject +@interface GLFWHelper : NSObject @end -@implementation GLFWLayoutListener +@implementation GLFWHelper - (void)selectedKeyboardInputSourceChanged:(NSObject* )object { updateUnicodeDataNS(); } -@end +- (void)doNothing:(id)object +{ +} + +@end // GLFWHelper ////////////////////////////////////////////////////////////////////////// @@ -291,13 +299,31 @@ static GLFWbool initializeTIS(void) int _glfwPlatformInit(void) { _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; + _glfw.ns.helper = [[GLFWHelper alloc] init]; + + [NSThread detachNewThreadSelector:@selector(doNothing:) + toTarget:_glfw.ns.helper + withObject:nil]; + + [NSApplication sharedApplication]; + + NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event) + { + if ([event modifierFlags] & NSEventModifierFlagCommand) + [[NSApp keyWindow] sendEvent:event]; + + return event; + }; + + _glfw.ns.keyUpMonitor = + [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp + handler:block]; if (_glfw.hints.init.ns.chdir) changeToResourcesDirectory(); - _glfw.ns.listener = [[GLFWLayoutListener alloc] init]; [[NSNotificationCenter defaultCenter] - addObserver:_glfw.ns.listener + addObserver:_glfw.ns.helper selector:@selector(selectedKeyboardInputSourceChanged:) name:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil]; @@ -342,18 +368,21 @@ void _glfwPlatformTerminate(void) _glfw.ns.delegate = nil; } - if (_glfw.ns.listener) + if (_glfw.ns.helper) { [[NSNotificationCenter defaultCenter] - removeObserver:_glfw.ns.listener + removeObserver:_glfw.ns.helper name:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] - removeObserver:_glfw.ns.listener]; - [_glfw.ns.listener release]; - _glfw.ns.listener = nil; + removeObserver:_glfw.ns.helper]; + [_glfw.ns.helper release]; + _glfw.ns.helper = nil; } + if (_glfw.ns.keyUpMonitor) + [NSEvent removeMonitor:_glfw.ns.keyUpMonitor]; + free(_glfw.ns.clipboardString); _glfwTerminateNSGL(); diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 282f7cc8b..13adaa972 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -109,7 +109,9 @@ typedef struct _GLFWlibraryNS TISInputSourceRef inputSource; IOHIDManagerRef hidManager; id unicodeData; - id listener; + id helper; + id keyUpMonitor; + id nibObjects; char keyName[64]; short int keycodes[256]; diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 9c018eb8b..f450eda02 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -46,7 +46,6 @@ #define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask #define NSEventMaskAny NSAnyEventMask #define NSEventTypeApplicationDefined NSApplicationDefined - #define NSEventTypeKeyUp NSKeyUp #define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat #endif @@ -856,52 +855,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; @end -//------------------------------------------------------------------------ -// GLFW application class -//------------------------------------------------------------------------ - -@interface GLFWApplication : NSApplication -{ - NSArray* nibObjects; -} - -@end - -@implementation GLFWApplication - -// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost -// This works around an AppKit bug, where key up events while holding -// down the command key don't get sent to the key window. -- (void)sendEvent:(NSEvent *)event -{ - if ([event type] == NSEventTypeKeyUp && - ([event modifierFlags] & NSEventModifierFlagCommand)) - { - [[self keyWindow] sendEvent:event]; - } - else - [super sendEvent:event]; -} - - -// No-op thread entry point -// -- (void)doNothing:(id)object -{ -} - -- (void)loadMainMenu -{ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 - [[NSBundle mainBundle] loadNibNamed:@"MainMenu" - owner:NSApp - topLevelObjects:&nibObjects]; -#else - [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp]; -#endif -} -@end - // Set up the menu bar (manually) // This is nasty, nasty stuff -- calls to undocumented semi-private APIs that // could go away at any moment, lots of stuff that really should be @@ -1011,32 +964,9 @@ static void createMenuBar(void) // static GLFWbool initializeAppKit(void) { - if (NSApp) + if (_glfw.ns.delegate) return GLFW_TRUE; - // Implicitly create shared NSApplication instance - [GLFWApplication sharedApplication]; - - // Make Cocoa enter multi-threaded mode - [NSThread detachNewThreadSelector:@selector(doNothing:) - toTarget:NSApp - withObject:nil]; - - if (_glfw.hints.init.ns.menubar) - { - // In case we are unbundled, make us a proper UI application - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - - // Menu bar setup must go between sharedApplication above and - // finishLaunching below, in order to properly emulate the behavior - // of NSApplicationMain - - if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"]) - [NSApp loadMainMenu]; - else - 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 _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; @@ -1048,6 +978,30 @@ static GLFWbool initializeAppKit(void) } [NSApp setDelegate:_glfw.ns.delegate]; + + if (_glfw.hints.init.ns.menubar) + { + // In case we are unbundled, make us a proper UI application + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + + // Menu bar setup must go between sharedApplication above and + // finishLaunching below, in order to properly emulate the behavior + // of NSApplicationMain + + if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"]) + { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 + [[NSBundle mainBundle] loadNibNamed:@"MainMenu" + owner:NSApp + topLevelObjects:&_glfw.ns.nibObjects]; +#else + [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp]; +#endif + } + else + createMenuBar(); + } + [NSApp run]; // Press and Hold prevents some keys from emitting repeated characters @@ -1554,9 +1508,6 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) void _glfwPlatformPollEvents(void) { - if (!initializeAppKit()) - return; - for (;;) { NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny @@ -1707,9 +1658,6 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, NSImage* native; NSBitmapImageRep* rep; - if (!initializeAppKit()) - return GLFW_FALSE; - rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:image->width @@ -1745,9 +1693,6 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) { - if (!initializeAppKit()) - return GLFW_FALSE; - if (shape == GLFW_ARROW_CURSOR) cursor->ns.object = [NSCursor arrowCursor]; else if (shape == GLFW_IBEAM_CURSOR) From c3ed70a4b77a2a4a08ef9a7cac7ac64a1835118d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 24 Dec 2018 23:40:30 +0100 Subject: [PATCH 02/43] Cocoa: Add NSApplicationDelegate protocol --- src/cocoa_window.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index f450eda02..043a5f0da 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -363,7 +363,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; // Delegate for application related notifications //------------------------------------------------------------------------ -@interface GLFWApplicationDelegate : NSObject +@interface GLFWApplicationDelegate : NSObject @end @implementation GLFWApplicationDelegate From 17a15a20f28ed95e0e69d403687416c023c77e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 24 Dec 2018 23:41:29 +0100 Subject: [PATCH 03/43] Cocoa: Move to modern Objective-C literals --- src/cocoa_window.m | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 043a5f0da..0a0da8c01 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -657,7 +657,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods); - [self interpretKeyEvents:[NSArray arrayWithObject:event]]; + [self interpretKeyEvents:@[event]]; } - (void)flagsChanged:(NSEvent *)event @@ -1005,10 +1005,7 @@ static GLFWbool initializeAppKit(void) [NSApp run]; // Press and Hold prevents some keys from emitting repeated characters - NSDictionary* defaults = - [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], - @"ApplePressAndHoldEnabled", - nil]; + NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO}; [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; return GLFW_TRUE; @@ -1731,10 +1728,8 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwPlatformSetClipboardString(const char* string) { - NSArray* types = [NSArray arrayWithObjects:NSPasteboardTypeString, nil]; - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - [pasteboard declareTypes:types owner:nil]; + [pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil]; [pasteboard setString:[NSString stringWithUTF8String:string] forType:NSPasteboardTypeString]; } From cc621765e5e9a5ef258a05ccf070e8c1603a7b6f Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sat, 24 Nov 2018 09:38:07 -0500 Subject: [PATCH 04/43] Cocoa: Accept focusing mouse click as input This makes the behavior on macOS consistent with other platforms. Fixes #1209. Closes #1386. --- src/cocoa_window.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 0a0da8c01..217588f78 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -492,6 +492,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; updateCursorImage(window); } +- (BOOL)acceptsFirstMouse:(NSEvent *)event +{ + return YES; +} + - (void)mouseDown:(NSEvent *)event { _glfwInputMouseClick(window, From cf0857f79aed5688d764d33dda11d3cee031a182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Dec 2018 20:52:58 +0100 Subject: [PATCH 05/43] Add credit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d2b25d061..ba34f9afe 100644 --- a/README.md +++ b/README.md @@ -314,6 +314,7 @@ skills. - John Bartholomew - Coşku Baş - Niklas Behrens + - Andrew Belt - Niklas Bergström - Denis Bernard - Doug Binks From c4903d92675a4c971d35190b749edb0ab14574f1 Mon Sep 17 00:00:00 2001 From: Keith Bauer Date: Sun, 4 Nov 2018 13:12:28 +1300 Subject: [PATCH 06/43] Cocoa: Fix half of all key events for Caps Lock This adds reporting of those Caps Lock key events that cause the lock state to change. The full fix involving IOHID is being worked on in #1368. Related to #1368. Closes #1373. --- README.md | 1 + src/cocoa_window.m | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index ba34f9afe..26aa74191 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,7 @@ information on what to include when reporting a bug. - [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871) - [EGL] Added support for `EGL_KHR_context_flush_control` - [EGL] Bugfix: The test for `EGL_RGB_BUFFER` was invalid +- [Cocoa] Bugfix: caps lock was not generating key events ## Contact diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 217588f78..db9935ce8 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -235,6 +235,8 @@ static NSUInteger translateKeyToModifierFlag(int key) case GLFW_KEY_LEFT_SUPER: case GLFW_KEY_RIGHT_SUPER: return NSEventModifierFlagCommand; + case GLFW_KEY_CAPS_LOCK: + return NSEventModifierFlagCapsLock; } return 0; From 91c1ff1b7d8004d2d0e9f41e3d52e81eead7ab7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Dec 2018 20:59:51 +0100 Subject: [PATCH 07/43] Cleanup --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26aa74191..2f86760f9 100644 --- a/README.md +++ b/README.md @@ -275,6 +275,7 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: Event polling did not initialize AppKit if necessary (#1218) - [Cocoa] Bugfix: OpenGL rendering was not initially visible on 10.14 (#1334,#1346) +- [Cocoa] Bugfix: Caps Lock did not generate any key events (#1368,#1373) - [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts - [WGL] Added support for `WGL_ARB_create_context_no_error` - [GLX] Added support for `GLX_ARB_create_context_no_error` @@ -283,7 +284,6 @@ information on what to include when reporting a bug. - [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871) - [EGL] Added support for `EGL_KHR_context_flush_control` - [EGL] Bugfix: The test for `EGL_RGB_BUFFER` was invalid -- [Cocoa] Bugfix: caps lock was not generating key events ## Contact From 86e7bf4169e0b500909146b0a6ff2dff5ae458e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Dec 2018 22:11:23 +0100 Subject: [PATCH 08/43] Documentation work --- include/GLFW/glfw3.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 2c0a3c272..a9897581b 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -4302,9 +4302,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); * The character callback behaves as system text input normally does and will * not be called if modifier keys are held down that would prevent normal text * input on that platform, for example a Super (Command) key on macOS or Alt key - * on Windows. There is a - * [character with modifiers callback](@ref glfwSetCharModsCallback) that - * receives these events. + * on Windows. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set From f4a304ff0320eacb6e830a1cff9435c6612c7130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Dec 2018 22:13:00 +0100 Subject: [PATCH 09/43] Remove deprecated event from events test --- tests/events.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/events.c b/tests/events.c index 9a0144d79..5c89beb5a 100644 --- a/tests/events.c +++ b/tests/events.c @@ -429,15 +429,6 @@ static void char_callback(GLFWwindow* window, unsigned int codepoint) get_character_string(codepoint)); } -static void char_mods_callback(GLFWwindow* window, unsigned int codepoint, int mods) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Character 0x%08x (%s) with modifiers (with%s) input\n", - counter++, slot->number, glfwGetTime(), codepoint, - get_character_string(codepoint), - get_mods_name(mods)); -} - static void drop_callback(GLFWwindow* window, int count, const char** paths) { int i; @@ -616,7 +607,6 @@ int main(int argc, char** argv) glfwSetScrollCallback(slots[i].window, scroll_callback); glfwSetKeyCallback(slots[i].window, key_callback); glfwSetCharCallback(slots[i].window, char_callback); - glfwSetCharModsCallback(slots[i].window, char_mods_callback); glfwSetDropCallback(slots[i].window, drop_callback); glfwMakeContextCurrent(slots[i].window); From a59315ed6adf3bec16e44a07801b2613786756f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 13 Dec 2018 20:29:50 +0100 Subject: [PATCH 10/43] Win32: Fix joystick element info memory leak The array was freed on failure but not on success. Fixes #1396. --- src/win32_joystick.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/win32_joystick.c b/src/win32_joystick.c index d9d341ff5..581239654 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -260,6 +260,8 @@ static void closeJoystick(_GLFWjoystick* js) IDirectInputDevice8_Release(js->win32.device); } + free(js->win32.objects); + _glfwFreeJoystick(js); _glfwInputJoystick(js, GLFW_DISCONNECTED); } From 3b255af4c3901338f460e075bda811290b31732d Mon Sep 17 00:00:00 2001 From: Sylvain Boilard Date: Thu, 13 Sep 2018 16:23:44 +0200 Subject: [PATCH 11/43] Documentation work The error section of the reference documentation for glfwWaitEventsTimeout was missing. Closes #1326. --- include/GLFW/glfw3.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index a9897581b..fb1841c83 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3777,6 +3777,9 @@ GLFWAPI void glfwWaitEvents(void); * * @param[in] timeout The maximum amount of time, in seconds, to wait. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_INVALID_VALUE. + * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. From 8e313d911becb802260d097d4eeefab734f7dcf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 13 Dec 2018 20:33:17 +0100 Subject: [PATCH 12/43] Cleanup GLFW_PLATFORM_ERROR should be listed last. --- include/GLFW/glfw3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index fb1841c83..db191c769 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3778,7 +3778,7 @@ GLFWAPI void glfwWaitEvents(void); * @param[in] timeout The maximum amount of time, in seconds, to wait. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_ERROR and @ref GLFW_INVALID_VALUE. + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * From 8c611fd5d06e19460b3632efb0ce09e1caeafe51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 18 Dec 2018 19:15:29 +0100 Subject: [PATCH 13/43] Win32: Fix build on older versions of Visual C++ Older versions did not provide fmin or fmax. This adds internal versions of fminf and fmaxf that should not be confused with standards compliant implementations. --- src/init.c | 24 ++++++++++++++++++++++++ src/input.c | 2 +- src/internal.h | 2 ++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/init.c b/src/init.c index 9e670d423..4f424c4a9 100644 --- a/src/init.c +++ b/src/init.c @@ -119,6 +119,30 @@ char* _glfw_strdup(const char* source) return result; } +float _glfw_fminf(float a, float b) +{ + if (a != a) + return b; + else if (b != b) + return a; + else if (a < b) + return a; + else + return b; +} + +float _glfw_fmaxf(float a, float b) +{ + if (a != a) + return b; + else if (b != b) + return a; + else if (a > b) + return a; + else + return b; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW event API ////// diff --git a/src/input.c b/src/input.c index b0bb3de47..460e9f31f 100644 --- a/src/input.c +++ b/src/input.c @@ -1242,7 +1242,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state) if (e->type == _GLFW_JOYSTICK_AXIS) { const float value = js->axes[e->index] * e->axisScale + e->axisOffset; - state->axes[i] = fminf(fmaxf(value, -1.f), 1.f); + state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f); } else if (e->type == _GLFW_JOYSTICK_HATBIT) { diff --git a/src/internal.h b/src/internal.h index 7be2b267c..30c7551a2 100644 --- a/src/internal.h +++ b/src/internal.h @@ -766,4 +766,6 @@ void _glfwTerminateVulkan(void); const char* _glfwGetVulkanResultString(VkResult result); char* _glfw_strdup(const char* source); +float _glfw_fminf(float a, float b); +float _glfw_fmaxf(float a, float b); From 751c6f9a2792bfc0c09cd381293db21c5a15a9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 17 Dec 2018 17:04:29 +0100 Subject: [PATCH 14/43] Fix assertions for glfwSetGamma value The NaN assert was implicit in the other ones. The lower bound assert incorrectly allowed a value of zero. Related to #1387. --- src/monitor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/monitor.c b/src/monitor.c index f7de5500f..0be3d2053 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -431,8 +431,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) unsigned short values[256]; GLFWgammaramp ramp; assert(handle != NULL); - assert(gamma == gamma); - assert(gamma >= 0.f); + assert(gamma > 0.f); assert(gamma <= FLT_MAX); _GLFW_REQUIRE_INIT(); From 064dfaa5493e2f532ce523b63d43eb6e73fadeca Mon Sep 17 00:00:00 2001 From: Alexander Monakov Date: Sat, 24 Nov 2018 18:25:20 +0300 Subject: [PATCH 15/43] Wayland: Remove gamma-related TODOs Commit 9c513346ada1f52d559c4eb4c1ec9d80c05696af ("Gamma will never be supported on Wayland") made it clear that it cannot be implemented, so this removes the TODO markers and rewords the error messages. Related to #1387. --- src/wl_monitor.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 7d8e23eb9..f033fb6ec 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -182,17 +182,15 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { - // TODO _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Gamma ramp getting not supported yet"); + "Wayland: Gamma ramp access it not available"); } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { - // TODO _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Gamma ramp setting not supported yet"); + "Wayland: Gamma ramp access is not available"); } From a533c9b3ca494dea845bb6c8e5b480ff745a1777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 26 Dec 2018 14:59:31 +0100 Subject: [PATCH 16/43] Add credit Related to #1387. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2f86760f9..9941f749a 100644 --- a/README.md +++ b/README.md @@ -398,6 +398,7 @@ skills. - Bruce Mitchener - Jack Moffitt - Jeff Molofee + - Alexander Monakov - Pierre Morel - Jon Morton - Pierre Moulon From 3201eedc34a8e707367e09c397bdbd7ca6c3be8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 26 Dec 2018 14:59:51 +0100 Subject: [PATCH 17/43] Cleanup We have a usable fminf now. --- src/monitor.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/monitor.c b/src/monitor.c index 0be3d2053..c161ea110 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -450,10 +450,8 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) value = i / 255.f; // Apply gamma curve value = powf(value, 1.f / gamma) * 65535.f + 0.5f; - // Clamp to value range - if (value > 65535.f) - value = 65535.f; + value = _glfw_fminf(value, 65535.f); values[i] = (unsigned short) value; } From 52c7a4fc7f243095fb116d6ac721a7590000e972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 19 Dec 2018 14:53:01 +0100 Subject: [PATCH 18/43] Fix glfwGetGammaRamp error handling This makes glfwGetGammaRamp return NULL on platform error as specified. Related to #1387. --- src/cocoa_monitor.m | 3 ++- src/internal.h | 2 +- src/monitor.c | 8 ++++++-- src/null_monitor.c | 3 ++- src/win32_monitor.c | 4 +++- src/wl_monitor.c | 3 ++- src/x11_monitor.c | 15 ++++++++++++++- 7 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 986d799e7..39fff6f7f 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -467,7 +467,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) CVDisplayLinkRelease(link); } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); @@ -489,6 +489,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) } free(values); + return GLFW_TRUE; } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) diff --git a/src/internal.h b/src/internal.h index 30c7551a2..c7c5bf8fd 100644 --- a/src/internal.h +++ b/src/internal.h @@ -611,7 +611,7 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, float* xscale, float* yscale); GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); void _glfwPlatformSetClipboardString(const char* string); diff --git a/src/monitor.c b/src/monitor.c index c161ea110..dea45d6e0 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -472,7 +472,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _glfwFreeGammaArrays(&monitor->currentRamp); - _glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp); + if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp)) + return NULL; return &monitor->currentRamp; } @@ -498,7 +499,10 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) _GLFW_REQUIRE_INIT(); if (!monitor->originalRamp.size) - _glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp); + { + if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp)) + return; + } _glfwPlatformSetGammaRamp(monitor, ramp); } diff --git a/src/null_monitor.c b/src/null_monitor.c index 84b41c7e3..45c4a10f8 100644 --- a/src/null_monitor.c +++ b/src/null_monitor.c @@ -58,8 +58,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) { } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { + return GLFW_FALSE; } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) diff --git a/src/win32_monitor.c b/src/win32_monitor.c index b7a24e615..07b3614bb 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -455,7 +455,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) &mode->blueBits); } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { HDC dc; WORD values[768]; @@ -469,6 +469,8 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short)); memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short)); memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short)); + + return GLFW_TRUE; } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) diff --git a/src/wl_monitor.c b/src/wl_monitor.c index f033fb6ec..588f8b0de 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -180,10 +180,11 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) *mode = monitor->modes[monitor->wl.currentMode]; } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Gamma ramp access it not available"); + return GLFW_FALSE; } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, diff --git a/src/x11_monitor.c b/src/x11_monitor.c index f557fe472..df53041df 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -422,7 +422,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) } } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) { @@ -438,6 +438,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short)); XRRFreeGamma(gamma); + return GLFW_TRUE; } else if (_glfw.x11.vidmode.available) { @@ -449,6 +450,13 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) XF86VidModeGetGammaRamp(_glfw.x11.display, _glfw.x11.screen, ramp->size, ramp->red, ramp->green, ramp->blue); + return GLFW_TRUE; + } + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Gamma ramp access not supported by server"); + return GLFW_FALSE; } } @@ -481,6 +489,11 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) (unsigned short*) ramp->green, (unsigned short*) ramp->blue); } + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Gamma ramp access not supported by server"); + } } From 3531c320afd6816cabae31ff30b9fb0890952c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 17 Dec 2018 17:40:18 +0100 Subject: [PATCH 19/43] Fix glfwSetGamma generating ramps of invalid sizes This makes glfwSetGamma generate a gamma ramp of the same size as the monitor's current ramp, which will avoid failure on non-256 entry monitors on X11 and avoid ramp interpolation on macOS. Closes #1387. Fixes #1388. --- README.md | 2 ++ include/GLFW/glfw3.h | 10 +++++----- src/monitor.c | 18 +++++++++++++----- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9941f749a..d2fbceaaa 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,8 @@ information on what to include when reporting a bug. - Bugfix: Invalid library paths were used in test and example CMake files (#930) - Bugfix: The scancode for synthetic key release events was always zero - Bugfix: The generated Doxyfile did not handle paths with spaces (#1081) +- Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor + ramp size (#1387,#1388) - [Win32] Added system error strings to relevant GLFW error descriptions (#733) - [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125) - [Win32] Removed XInput circular deadzone from joystick axis data (#1045) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index db191c769..099cd8e67 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -2156,9 +2156,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); /*! @brief Generates a gamma ramp and sets it for the specified monitor. * - * This function generates a 256-element gamma ramp from the specified exponent - * and then calls @ref glfwSetGammaRamp with it. The value must be a finite - * number greater than zero. + * This function generates an appropriately sized gamma ramp from the specified + * exponent and then calls @ref glfwSetGammaRamp with it. The value must be + * a finite number greater than zero. * * The software controlled gamma ramp is applied _in addition_ to the hardware * gamma correction, which today is usually an approximation of sRGB gamma. @@ -2237,8 +2237,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark Gamma ramp sizes other than 256 are not supported by all platforms - * or graphics hardware. + * @remark The size of the specified gamma ramp should match the size of the + * current ramp for that monitor. * * @remark @win32 The gamma ramp size must be 256. * diff --git a/src/monitor.c b/src/monitor.c index dea45d6e0..0ab865e3b 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -427,9 +427,10 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) { - int i; - unsigned short values[256]; + unsigned int i; + unsigned short* values; GLFWgammaramp ramp; + const GLFWgammaramp* original; assert(handle != NULL); assert(gamma > 0.f); assert(gamma <= FLT_MAX); @@ -442,12 +443,18 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) return; } - for (i = 0; i < 256; i++) + original = glfwGetGammaRamp(handle); + if (!original) + return; + + values = calloc(original->size, sizeof(unsigned short)); + + for (i = 0; i < original->size; i++) { float value; // Calculate intensity - value = i / 255.f; + value = i / (float) (original->size - 1); // Apply gamma curve value = powf(value, 1.f / gamma) * 65535.f + 0.5f; // Clamp to value range @@ -459,9 +466,10 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) ramp.red = values; ramp.green = values; ramp.blue = values; - ramp.size = 256; + ramp.size = original->size; glfwSetGammaRamp(handle, &ramp); + free(values); } GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) From e29882523ee9e0561154ff13b4e67fe8d1ec1e68 Mon Sep 17 00:00:00 2001 From: Vallentin Date: Fri, 14 Dec 2018 19:26:42 +0100 Subject: [PATCH 20/43] Fix typos Closes #1402. --- examples/boing.c | 4 ++-- src/osmesa_context.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/boing.c b/examples/boing.c index 45c867fd1..5b8e667e8 100644 --- a/examples/boing.c +++ b/examples/boing.c @@ -302,7 +302,7 @@ void cursor_position_callback( GLFWwindow* window, double x, double y ) * The Boing ball is sphere in which each facet is a rectangle. * Facet colors alternate between red and white. * The ball is built by stacking latitudinal circles. Each circle is composed - * of a widely-separated set of points, so that each facet is noticably large. + * of a widely-separated set of points, so that each facet is noticeably large. *****************************************************************************/ void DrawBoingBall( void ) { @@ -446,7 +446,7 @@ void DrawBoingBallBand( GLfloat long_lo, static int colorToggle = 0; /* - * Iterate thru the points of a latitude circle. + * Iterate through the points of a latitude circle. * A latitude circle is a 2D set of X,Z points. */ for ( lat_deg = 0; diff --git a/src/osmesa_context.c b/src/osmesa_context.c index a7de33f26..03651ebf4 100644 --- a/src/osmesa_context.c +++ b/src/osmesa_context.c @@ -240,7 +240,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, if (ctxconfig->forward) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "OSMesa: Foward-compatible contexts not supported"); + "OSMesa: Forward-compatible contexts not supported"); return GLFW_FALSE; } From 9ac9d7b85a224bb932f4a74912ddf5625a4eb110 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Sun, 18 Nov 2018 23:32:11 -0500 Subject: [PATCH 21/43] Win32: Disable non-client painting if undecorated Fixes an issue where a small title bar and window caption buttons were being painted after restoring a minimized undecorated window. Closes #1383. --- src/win32_window.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/win32_window.c b/src/win32_window.c index 796ae150e..daef15363 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1161,6 +1161,19 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, DragFinish(drop); return 0; } + + case WM_NCACTIVATE: + case WM_NCPAINT: + { + // HACK: Prevent title bar artifacts from appearing after restoring + // a minimized borderless window + if (!window->decorated) + { + return TRUE; + } + + break; + } } return DefWindowProcW(hWnd, uMsg, wParam, lParam); From 1635fe28265019f1a16ee01e4efaf655599a7f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 26 Dec 2018 15:18:36 +0100 Subject: [PATCH 22/43] Cleanup Put the non-client painting related message cases with the client ones so that they can be happy together. Related to #1383. --- README.md | 2 ++ src/win32_window.c | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d2fbceaaa..51911f989 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,8 @@ information on what to include when reporting a bug. hint set to false (#1179,#1180) - [Win32] Bugfix: The keypad equals key was reported as `GLFW_KEY_UNKNOWN` (#1315,#1316) +- [Win32] Bugfix: A title bar would be drawn over undecorated windows in some + circumstances (#1383) - [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125) - [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading - [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X diff --git a/src/win32_window.c b/src/win32_window.c index daef15363..a0abca060 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1060,6 +1060,17 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return TRUE; } + case WM_NCACTIVATE: + case WM_NCPAINT: + { + // Prevent title bar from being drawn after restoring a minimized + // undecorated window + if (!window->decorated) + return TRUE; + + break; + } + case WM_DWMCOMPOSITIONCHANGED: { if (window->win32.transparent) @@ -1161,19 +1172,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, DragFinish(drop); return 0; } - - case WM_NCACTIVATE: - case WM_NCPAINT: - { - // HACK: Prevent title bar artifacts from appearing after restoring - // a minimized borderless window - if (!window->decorated) - { - return TRUE; - } - - break; - } } return DefWindowProcW(hWnd, uMsg, wParam, lParam); From c90c7b97109db909577e3bf540b5f884422b7e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 26 Dec 2018 15:19:02 +0100 Subject: [PATCH 23/43] Add credit Related to #1383. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 51911f989..6366a4f37 100644 --- a/README.md +++ b/README.md @@ -386,6 +386,7 @@ skills. - Glenn Lewis - Shane Liesegang - Eyal Lotem + - Aaron Loucks - Tristam MacDonald - Hans Mackowiak - Дмитри Малышев From cde0aaaab1e3610b6c8f27cd9a5f57f011a31b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 1 Jan 2019 18:24:11 +0100 Subject: [PATCH 24/43] X11: Fix glfwSetWindowMonitor not updating hints This makes glfwSetWindowMonitor update the WM_NORMAL_HINTS when resizing non-user-resizable windowed mode windows. --- README.md | 2 ++ src/x11_window.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index 6366a4f37..2c0436ce0 100644 --- a/README.md +++ b/README.md @@ -245,6 +245,8 @@ information on what to include when reporting a bug. - [X11] Bugfix: NVidia EGL would segfault if unloaded before closing the display - [X11] Bugfix: Checking window maximized attrib could crash some WMs (#1356) - [X11] Bugfix: Update cursor position on enter event (#1366) +- [X11] Bugfix: `glfwSetWindowMonitor` did not update hints when resizing + non-user-resizable windows - [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel headers (#1196) - [Linux] Moved to evdev for joystick input (#906,#1005) diff --git a/src/x11_window.c b/src/x11_window.c index 5e9161072..e9efcb1f3 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2403,6 +2403,9 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, } else { + if (!window->resizable) + updateNormalHints(window, width, height); + XMoveResizeWindow(_glfw.x11.display, window->x11.handle, xpos, ypos, width, height); } From 72c3908e1474d0cd72bed9fecb6ff3da022f7200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 1 Jan 2019 18:32:45 +0100 Subject: [PATCH 25/43] X11: Fix glfwSetWindowMonitor not flushing buffer --- README.md | 1 + src/x11_window.c | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 2c0436ce0..442165595 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,7 @@ information on what to include when reporting a bug. - [X11] Bugfix: Update cursor position on enter event (#1366) - [X11] Bugfix: `glfwSetWindowMonitor` did not update hints when resizing non-user-resizable windows +- [X11] Bugfix: `glfwSetWindowMonitor` did not flush output buffer in some cases - [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel headers (#1196) - [Linux] Moved to evdev for joystick input (#906,#1005) diff --git a/src/x11_window.c b/src/x11_window.c index e9efcb1f3..19ed73723 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2410,6 +2410,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, xpos, ypos, width, height); } + XFlush(_glfw.x11.display); return; } From 9a9568212c2dfd17fe46845eaa68ec0731de6173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 3 Jan 2019 19:32:45 +0100 Subject: [PATCH 26/43] Cocoa: Move slightly towards modern Objective-C --- README.md | 2 +- src/cocoa_monitor.m | 10 +++------- src/cocoa_window.m | 18 ++++++++---------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 442165595..80059c95d 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ more information. ## System requirements -GLFW supports Windows XP and later and macOS 10.7 and later. Linux and other +GLFW supports Windows XP and later and macOS 10.8 and later. Linux and other Unix-like systems running the X Window System are supported even without a desktop environment or modern extensions, although some features require a running window or clipboard manager. The OSMesa backend requires Mesa 6.3. diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 39fff6f7f..955d52d15 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -374,14 +374,10 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, { if (!monitor->ns.screen) { - NSUInteger i; - NSArray* screens = [NSScreen screens]; - - for (i = 0; i < [screens count]; i++) + for (NSScreen* screen in [NSScreen screens]) { - NSScreen* screen = [screens objectAtIndex:i]; NSNumber* displayID = - [[screen deviceDescription] objectForKey:@"NSScreenNumber"]; + [screen deviceDescription][@"NSScreenNumber"]; // HACK: Compare unit numbers instead of display IDs to work around // display replacement on machines with automatic graphics @@ -394,7 +390,7 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, } } - if (i == [screens count]) + if (!monitor->ns.screen) { _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor"); diff --git a/src/cocoa_window.m b/src/cocoa_window.m index db9935ce8..92b110ddd 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -737,7 +737,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; char** paths = calloc(count, sizeof(char*)); for (NSUInteger i = 0; i < count; i++) - paths[i] = _glfw_strdup([[urls objectAtIndex:i] fileSystemRepresentation]); + paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]); _glfwInputDrop(window, (int) count, (const char**) paths); @@ -883,7 +883,7 @@ static void createMenuBar(void) for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) { - id name = [bundleInfo objectForKey:nameKeys[i]]; + id name = bundleInfo[nameKeys[i]]; if (name && [name isKindOfClass:[NSString class]] && ![name isEqualToString:@""]) @@ -897,7 +897,7 @@ static void createMenuBar(void) { char** progname = _NSGetProgname(); if (progname && *progname) - appName = [NSString stringWithUTF8String:*progname]; + appName = @(*progname); else appName = @"GLFW Application"; } @@ -1084,7 +1084,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, } if (strlen(wndconfig->ns.frameName)) - [window->ns.object setFrameAutosaveName:[NSString stringWithUTF8String:wndconfig->ns.frameName]]; + [window->ns.object setFrameAutosaveName:@(wndconfig->ns.frameName)]; window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window]; @@ -1099,7 +1099,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, [window->ns.object setContentView:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view]; - [window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]]; + [window->ns.object setTitle:@(wndconfig->title)]; [window->ns.object setDelegate:window->ns.delegate]; [window->ns.object setAcceptsMouseMovedEvents:YES]; [window->ns.object setRestorable:NO]; @@ -1190,11 +1190,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) { - NSString* string = [NSString stringWithUTF8String:title]; - [window->ns.object setTitle:string]; + [window->ns.object setTitle:@(title)]; // HACK: Set the miniwindow title explicitly as setTitle: doesn't update it // if the window lacks NSWindowStyleMaskTitled - [window->ns.object setMiniwindowTitle:string]; + [window->ns.object setMiniwindowTitle:@(title)]; } void _glfwPlatformSetWindowIcon(_GLFWwindow* window, @@ -1737,8 +1736,7 @@ void _glfwPlatformSetClipboardString(const char* string) { NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; [pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil]; - [pasteboard setString:[NSString stringWithUTF8String:string] - forType:NSPasteboardTypeString]; + [pasteboard setString:@(string) forType:NSPasteboardTypeString]; } const char* _glfwPlatformGetClipboardString(void) From ea7eb2ddab823e21c846c68d112d90f91fcba318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 11 Jan 2019 01:05:00 +0100 Subject: [PATCH 27/43] Cocoa: Move app delegate and menu creation to init The application delegate needs to be set at init to receive monitor events before window creation. Menu creation is moved to applicationWillFinishLaunching: to play nicer with other toolkits in the same process. Related to #1317. --- src/cocoa_init.m | 195 +++++++++++++++++++++++++++++++++++++ src/cocoa_platform.h | 1 + src/cocoa_window.m | 222 ++----------------------------------------- 3 files changed, 204 insertions(+), 214 deletions(-) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index f3c479578..2f08144ab 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -27,9 +27,14 @@ #include "internal.h" #include // For MAXPATHLEN +// Needed for _NSGetProgname +#include + #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 #define NSEventMaskKeyUp NSKeyUpMask #define NSEventModifierFlagCommand NSCommandKeyMask + #define NSEventModifierFlagControl NSControlKeyMask + #define NSEventModifierFlagOption NSAlternateKeyMask #endif // Change to our application bundle's resources directory, if present @@ -68,6 +73,111 @@ static void changeToResourcesDirectory(void) chdir(resourcesPath); } +// Set up the menu bar (manually) +// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that +// could go away at any moment, lots of stuff that really should be +// localize(d|able), etc. Add a nib to save us this horror. +// +static void createMenuBar(void) +{ + size_t i; + NSString* appName = nil; + NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary]; + NSString* nameKeys[] = + { + @"CFBundleDisplayName", + @"CFBundleName", + @"CFBundleExecutable", + }; + + // Try to figure out what the calling application is called + + for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) + { + id name = bundleInfo[nameKeys[i]]; + if (name && + [name isKindOfClass:[NSString class]] && + ![name isEqualToString:@""]) + { + appName = name; + break; + } + } + + if (!appName) + { + char** progname = _NSGetProgname(); + if (progname && *progname) + appName = @(*progname); + else + appName = @"GLFW Application"; + } + + NSMenu* bar = [[NSMenu alloc] init]; + [NSApp setMainMenu:bar]; + + NSMenuItem* appMenuItem = + [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; + NSMenu* appMenu = [[NSMenu alloc] init]; + [appMenuItem setSubmenu:appMenu]; + + [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName] + action:@selector(orderFrontStandardAboutPanel:) + keyEquivalent:@""]; + [appMenu addItem:[NSMenuItem separatorItem]]; + NSMenu* servicesMenu = [[NSMenu alloc] init]; + [NSApp setServicesMenu:servicesMenu]; + [[appMenu addItemWithTitle:@"Services" + action:NULL + keyEquivalent:@""] setSubmenu:servicesMenu]; + [servicesMenu release]; + [appMenu addItem:[NSMenuItem separatorItem]]; + [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName] + action:@selector(hide:) + keyEquivalent:@"h"]; + [[appMenu addItemWithTitle:@"Hide Others" + action:@selector(hideOtherApplications:) + keyEquivalent:@"h"] + setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand]; + [appMenu addItemWithTitle:@"Show All" + action:@selector(unhideAllApplications:) + keyEquivalent:@""]; + [appMenu addItem:[NSMenuItem separatorItem]]; + [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName] + action:@selector(terminate:) + keyEquivalent:@"q"]; + + NSMenuItem* windowMenuItem = + [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; + [bar release]; + NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + [NSApp setWindowsMenu:windowMenu]; + [windowMenuItem setSubmenu:windowMenu]; + + [windowMenu addItemWithTitle:@"Minimize" + action:@selector(performMiniaturize:) + keyEquivalent:@"m"]; + [windowMenu addItemWithTitle:@"Zoom" + action:@selector(performZoom:) + keyEquivalent:@""]; + [windowMenu addItem:[NSMenuItem separatorItem]]; + [windowMenu addItemWithTitle:@"Bring All to Front" + action:@selector(arrangeInFront:) + keyEquivalent:@""]; + + // TODO: Make this appear at the bottom of the menu (for consistency) + [windowMenu addItem:[NSMenuItem separatorItem]]; + [[windowMenu addItemWithTitle:@"Enter Full Screen" + action:@selector(toggleFullScreen:) + keyEquivalent:@"f"] + setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand]; + + // Prior to Snow Leopard, we need to use this oddly-named semi-private API + // to get the application menu working properly. + SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:"); + [NSApp performSelector:setAppleMenuSelector withObject:appMenu]; +} + // Create key code translation tables // static void createKeyTables(void) @@ -291,6 +401,77 @@ static GLFWbool initializeTIS(void) @end // GLFWHelper +@interface GLFWApplicationDelegate : NSObject +@end + +@implementation GLFWApplicationDelegate + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + _GLFWwindow* window; + + for (window = _glfw.windowListHead; window; window = window->next) + _glfwInputWindowCloseRequest(window); + + return NSTerminateCancel; +} + +- (void)applicationDidChangeScreenParameters:(NSNotification *) notification +{ + _GLFWwindow* window; + + for (window = _glfw.windowListHead; window; window = window->next) + { + if (window->context.client != GLFW_NO_API) + [window->context.nsgl.object update]; + } + + _glfwPollMonitorsNS(); +} + +- (void)applicationWillFinishLaunching:(NSNotification *)notification +{ + if (_glfw.hints.init.ns.menubar) + { + // In case we are unbundled, make us a proper UI application + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + + // Menu bar setup must go between sharedApplication above and + // finishLaunching below, in order to properly emulate the behavior + // of NSApplicationMain + + if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"]) + { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 + [[NSBundle mainBundle] loadNibNamed:@"MainMenu" + owner:NSApp + topLevelObjects:&_glfw.ns.nibObjects]; +#else + [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp]; +#endif + } + else + createMenuBar(); + } +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notification +{ + [NSApp stop:nil]; + + _glfwPlatformPostEmptyEvent(); +} + +- (void)applicationDidHide:(NSNotification *)notification +{ + int i; + + for (i = 0; i < _glfw.monitorCount; i++) + _glfwRestoreVideoModeNS(_glfw.monitors[i]); +} + +@end // GLFWApplicationDelegate + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// @@ -307,6 +488,16 @@ int _glfwPlatformInit(void) [NSApplication sharedApplication]; + _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; + if (_glfw.ns.delegate == nil) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Failed to create application delegate"); + return GLFW_FALSE; + } + + [NSApp setDelegate:_glfw.ns.delegate]; + NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event) { if ([event modifierFlags] & NSEventModifierFlagCommand) @@ -322,6 +513,10 @@ int _glfwPlatformInit(void) if (_glfw.hints.init.ns.chdir) changeToResourcesDirectory(); + // Press and Hold prevents some keys from emitting repeated characters + NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO}; + [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; + [[NSNotificationCenter defaultCenter] addObserver:_glfw.ns.helper selector:@selector(selectedKeyboardInputSourceChanged:) diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 13adaa972..cf7ead59e 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -105,6 +105,7 @@ typedef struct _GLFWlibraryNS CGEventSourceRef eventSource; id delegate; id autoreleasePool; + GLFWbool finishedLaunching; GLFWbool cursorHidden; TISInputSourceRef inputSource; IOHIDManagerRef hidManager; diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 92b110ddd..7011a797a 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -29,9 +29,6 @@ #include #include -// Needed for _NSGetProgname -#include - #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 #define NSWindowStyleMaskBorderless NSBorderlessWindowMask #define NSWindowStyleMaskClosable NSClosableWindowMask @@ -361,56 +358,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; @end -//------------------------------------------------------------------------ -// Delegate for application related notifications -//------------------------------------------------------------------------ - -@interface GLFWApplicationDelegate : NSObject -@end - -@implementation GLFWApplicationDelegate - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender -{ - _GLFWwindow* window; - - for (window = _glfw.windowListHead; window; window = window->next) - _glfwInputWindowCloseRequest(window); - - return NSTerminateCancel; -} - -- (void)applicationDidChangeScreenParameters:(NSNotification *) notification -{ - _GLFWwindow* window; - - for (window = _glfw.windowListHead; window; window = window->next) - { - if (window->context.client != GLFW_NO_API) - [window->context.nsgl.object update]; - } - - _glfwPollMonitorsNS(); -} - -- (void)applicationDidFinishLaunching:(NSNotification *)notification -{ - [NSApp stop:nil]; - - _glfwPlatformPostEmptyEvent(); -} - -- (void)applicationDidHide:(NSNotification *)notification -{ - int i; - - for (i = 0; i < _glfw.monitorCount; i++) - _glfwRestoreVideoModeNS(_glfw.monitors[i]); -} - -@end - - //------------------------------------------------------------------------ // Content view class for the GLFW window //------------------------------------------------------------------------ @@ -862,162 +809,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; @end -// Set up the menu bar (manually) -// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that -// could go away at any moment, lots of stuff that really should be -// localize(d|able), etc. Add a nib to save us this horror. -// -static void createMenuBar(void) -{ - size_t i; - NSString* appName = nil; - NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary]; - NSString* nameKeys[] = - { - @"CFBundleDisplayName", - @"CFBundleName", - @"CFBundleExecutable", - }; - - // Try to figure out what the calling application is called - - for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) - { - id name = bundleInfo[nameKeys[i]]; - if (name && - [name isKindOfClass:[NSString class]] && - ![name isEqualToString:@""]) - { - appName = name; - break; - } - } - - if (!appName) - { - char** progname = _NSGetProgname(); - if (progname && *progname) - appName = @(*progname); - else - appName = @"GLFW Application"; - } - - NSMenu* bar = [[NSMenu alloc] init]; - [NSApp setMainMenu:bar]; - - NSMenuItem* appMenuItem = - [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; - NSMenu* appMenu = [[NSMenu alloc] init]; - [appMenuItem setSubmenu:appMenu]; - - [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName] - action:@selector(orderFrontStandardAboutPanel:) - keyEquivalent:@""]; - [appMenu addItem:[NSMenuItem separatorItem]]; - NSMenu* servicesMenu = [[NSMenu alloc] init]; - [NSApp setServicesMenu:servicesMenu]; - [[appMenu addItemWithTitle:@"Services" - action:NULL - keyEquivalent:@""] setSubmenu:servicesMenu]; - [servicesMenu release]; - [appMenu addItem:[NSMenuItem separatorItem]]; - [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName] - action:@selector(hide:) - keyEquivalent:@"h"]; - [[appMenu addItemWithTitle:@"Hide Others" - action:@selector(hideOtherApplications:) - keyEquivalent:@"h"] - setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand]; - [appMenu addItemWithTitle:@"Show All" - action:@selector(unhideAllApplications:) - keyEquivalent:@""]; - [appMenu addItem:[NSMenuItem separatorItem]]; - [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName] - action:@selector(terminate:) - keyEquivalent:@"q"]; - - NSMenuItem* windowMenuItem = - [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; - [bar release]; - NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - [NSApp setWindowsMenu:windowMenu]; - [windowMenuItem setSubmenu:windowMenu]; - - [windowMenu addItemWithTitle:@"Minimize" - action:@selector(performMiniaturize:) - keyEquivalent:@"m"]; - [windowMenu addItemWithTitle:@"Zoom" - action:@selector(performZoom:) - keyEquivalent:@""]; - [windowMenu addItem:[NSMenuItem separatorItem]]; - [windowMenu addItemWithTitle:@"Bring All to Front" - action:@selector(arrangeInFront:) - keyEquivalent:@""]; - - // TODO: Make this appear at the bottom of the menu (for consistency) - [windowMenu addItem:[NSMenuItem separatorItem]]; - [[windowMenu addItemWithTitle:@"Enter Full Screen" - action:@selector(toggleFullScreen:) - keyEquivalent:@"f"] - setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand]; - - // Prior to Snow Leopard, we need to use this oddly-named semi-private API - // to get the application menu working properly. - SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:"); - [NSApp performSelector:setAppleMenuSelector withObject:appMenu]; -} - -// Initialize the Cocoa Application Kit -// -static GLFWbool initializeAppKit(void) -{ - if (_glfw.ns.delegate) - return GLFW_TRUE; - - // 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 - _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; - if (_glfw.ns.delegate == nil) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Cocoa: Failed to create application delegate"); - return GLFW_FALSE; - } - - [NSApp setDelegate:_glfw.ns.delegate]; - - if (_glfw.hints.init.ns.menubar) - { - // In case we are unbundled, make us a proper UI application - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - - // Menu bar setup must go between sharedApplication above and - // finishLaunching below, in order to properly emulate the behavior - // of NSApplicationMain - - if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"]) - { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 - [[NSBundle mainBundle] loadNibNamed:@"MainMenu" - owner:NSApp - topLevelObjects:&_glfw.ns.nibObjects]; -#else - [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp]; -#endif - } - else - createMenuBar(); - } - - [NSApp run]; - - // Press and Hold prevents some keys from emitting repeated characters - NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO}; - [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; - - return GLFW_TRUE; -} - // Create the Cocoa window // static GLFWbool createNativeWindow(_GLFWwindow* window, @@ -1120,8 +911,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig) { - if (!initializeAppKit()) - return GLFW_FALSE; + if (!_glfw.ns.finishedLaunching) + { + [NSApp run]; + _glfw.ns.finishedLaunching = GLFW_TRUE; + } if (!createNativeWindow(window, wndconfig, fbconfig)) return GLFW_FALSE; @@ -1344,9 +1138,9 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) void _glfwPlatformFocusWindow(_GLFWwindow* window) { // Make us the active application - // HACK: This has been moved here from initializeAppKit to prevent - // applications using only hidden windows from being activated, but - // should probably not be done every time any window is shown + // HACK: This is here to prevent applications using only hidden windows from + // being activated, but should probably not be done every time any + // window is shown [NSApp activateIgnoringOtherApps:YES]; [window->ns.object makeKeyAndOrderFront:nil]; From 55b1a16f9061520724fc507a9ef243f641d1ee02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 15 Jan 2019 19:28:17 +0100 Subject: [PATCH 28/43] Remove window requirement for all event functions This lets an application wait for non-window events without needing to create a window. Fixes #1317. --- README.md | 2 ++ docs/input.dox | 3 +-- include/GLFW/glfw3.h | 12 ------------ src/window.c | 8 -------- 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 80059c95d..d50e5ddb4 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,8 @@ information on what to include when reporting a bug. - Removed `GLFW_USE_RETINA` compile-time option - Removed `GLFW_USE_CHDIR` compile-time option - Removed `GLFW_USE_MENUBAR` compile-time option +- Removed requirement of at least one window for `glfwWaitEvents` and + `glfwPostEmptyEvent` (#1317) - 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/input.dox b/docs/input.dox index 84978bd09..73c7ef70d 100644 --- a/docs/input.dox +++ b/docs/input.dox @@ -57,8 +57,7 @@ glfwWaitEvents(); It puts the thread to sleep until at least one event has been received and then processes all received events. This saves a great deal of CPU cycles and is -useful for, for example, editing tools. There must be at least one GLFW window -for this function to sleep. +useful for, for example, editing tools. If you want to wait for events but have UI elements or other tasks that need periodic updates, @ref glfwWaitEventsTimeout lets you specify a timeout. diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 099cd8e67..8606edc16 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3718,10 +3718,6 @@ GLFWAPI void glfwPollEvents(void); * GLFW will pass those events on to the application callbacks before * returning. * - * If no windows exist, this function returns immediately. For synchronization - * of threads in applications that do not create windows, use your threading - * library of choice. - * * Event processing is not required for joystick input to work. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref @@ -3769,10 +3765,6 @@ GLFWAPI void glfwWaitEvents(void); * GLFW will pass those events on to the application callbacks before * returning. * - * If no windows exist, this function returns immediately. For synchronization - * of threads in applications that do not create windows, use your threading - * library of choice. - * * Event processing is not required for joystick input to work. * * @param[in] timeout The maximum amount of time, in seconds, to wait. @@ -3799,10 +3791,6 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout); * This function posts an empty event from the current thread to the event * queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return. * - * If no windows exist, this function returns immediately. For synchronization - * of threads in applications that do not create windows, use your threading - * library of choice. - * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * diff --git a/src/window.c b/src/window.c index 4e365cb47..2c98d4cb8 100644 --- a/src/window.c +++ b/src/window.c @@ -1078,10 +1078,6 @@ GLFWAPI void glfwPollEvents(void) GLFWAPI void glfwWaitEvents(void) { _GLFW_REQUIRE_INIT(); - - if (!_glfw.windowListHead) - return; - _glfwPlatformWaitEvents(); } @@ -1104,10 +1100,6 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout) GLFWAPI void glfwPostEmptyEvent(void) { _GLFW_REQUIRE_INIT(); - - if (!_glfw.windowListHead) - return; - _glfwPlatformPostEmptyEvent(); } From 2053f3ed22afa1e3cabed04d94bcaa0e69d543c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 17 Jan 2019 00:11:17 +0100 Subject: [PATCH 29/43] Cleanup --- src/context.c | 2 +- src/wgl_context.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/context.c b/src/context.c index fd344cf15..385085225 100644 --- a/src/context.c +++ b/src/context.c @@ -358,7 +358,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window, window->context.source = ctxconfig->source; window->context.client = GLFW_OPENGL_API; - previous = _glfwPlatformGetTls(&_glfw.contextSlot);; + previous = _glfwPlatformGetTls(&_glfw.contextSlot); glfwMakeContextCurrent((GLFWwindow*) window); window->context.GetIntegerv = (PFNGLGETINTEGERVPROC) diff --git a/src/wgl_context.c b/src/wgl_context.c index 06ba8b55a..b12ca91a7 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -377,7 +377,7 @@ GLFWbool _glfwInitWGL(void) // NOTE: This code will accept the Microsoft GDI ICD; accelerated context // creation failure occurs during manual pixel format enumeration - dc = GetDC(_glfw.win32.helperWindowHandle);; + dc = GetDC(_glfw.win32.helperWindowHandle); ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); From 9b0c16596caea0f8008b90cd5cbbf7e6b1610c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 17 Jan 2019 00:11:42 +0100 Subject: [PATCH 30/43] Add full screen option to tearing test --- tests/CMakeLists.txt | 2 +- tests/tearing.c | 49 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7078b005d..8a15da1db 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -33,7 +33,7 @@ add_executable(icon WIN32 MACOSX_BUNDLE icon.c ${GLAD}) add_executable(inputlag WIN32 MACOSX_BUNDLE inputlag.c ${GETOPT} ${GLAD}) add_executable(joysticks WIN32 MACOSX_BUNDLE joysticks.c ${GLAD}) add_executable(opacity WIN32 MACOSX_BUNDLE opacity.c ${GLAD}) -add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GLAD}) +add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GETOPT} ${GLAD}) add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD}) add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD}) add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD}) diff --git a/tests/tearing.c b/tests/tearing.c index fe7ed0761..4acf3b292 100644 --- a/tests/tearing.c +++ b/tests/tearing.c @@ -35,6 +35,7 @@ #include #include +#include "getopt.h" #include "linmath.h" static const struct @@ -68,6 +69,14 @@ static int swap_tear; static int swap_interval; static double frame_rate; +static void usage(void) +{ + printf("Usage: tearing [-f] [-h]\n"); + printf("Options:\n"); + printf(" -f use full screen\n"); + printf(" -h show this help\n"); +} + static void update_window_title(GLFWwindow* window) { char title[256]; @@ -154,6 +163,8 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, int main(int argc, char** argv) { unsigned long frame_count = 0; + GLFWmonitor* monitor = NULL; + int ch, width, height; double last_time, current_time; GLFWwindow* window; GLuint vertex_buffer, vertex_shader, fragment_shader, program; @@ -164,10 +175,46 @@ int main(int argc, char** argv) if (!glfwInit()) exit(EXIT_FAILURE); + while ((ch = getopt(argc, argv, "hf")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + + case 'f': + monitor = glfwGetPrimaryMonitor(); + break; + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - window = glfwCreateWindow(640, 480, "Tearing detector", NULL, NULL); + window = glfwCreateWindow(width, height, "Tearing detector", monitor, NULL); if (!window) { glfwTerminate(); From babafc13dbdf6b031659ef54259185f72263e1d3 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Fri, 12 Oct 2018 11:58:32 +0100 Subject: [PATCH 31/43] WGL: Add array-based call to wglGetPixelFormatAttribivARB This improves performance of pixel format enumeration and helps the very poor performance reported on a small number of machines. Closes #1381. --- src/wgl_context.c | 149 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 126 insertions(+), 23 deletions(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index b12ca91a7..5f8d63a63 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -31,6 +31,103 @@ #include #include +// array of pixel format attributes we need +static const int glfwPixelFormatAttribs[] = { + WGL_SUPPORT_OPENGL_ARB, + WGL_DRAW_TO_WINDOW_ARB, + WGL_PIXEL_TYPE_ARB, + WGL_ACCELERATION_ARB, + WGL_RED_BITS_ARB, + WGL_RED_SHIFT_ARB, + WGL_GREEN_BITS_ARB, + WGL_GREEN_SHIFT_ARB, + WGL_BLUE_BITS_ARB, + WGL_BLUE_SHIFT_ARB, + WGL_ALPHA_BITS_ARB, + WGL_ALPHA_SHIFT_ARB, + WGL_DEPTH_BITS_ARB, + WGL_STENCIL_BITS_ARB, + WGL_ACCUM_BITS_ARB, + WGL_ACCUM_RED_BITS_ARB, + WGL_ACCUM_GREEN_BITS_ARB, + WGL_ACCUM_BLUE_BITS_ARB, + WGL_ACCUM_ALPHA_BITS_ARB, + WGL_AUX_BUFFERS_ARB, + WGL_STEREO_ARB, + WGL_DOUBLE_BUFFER_ARB, + // ARB EXT attribs only below this line, see initPixelFormatAttribArry + WGL_SAMPLES_ARB, + WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, + WGL_COLORSPACE_EXT +}; + +// initialize array attribs with formatattribs available +// attribs array must be at least of size sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0]) +// returns number of valid elemets in array +static int initPixelFormatAttribArry( int* attribs, int api ) +{ + const int numARBEXTAtrribs = 3; // Update this value when adding ARB EXT attribs + int numAttribs = sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0]) - numARBEXTAtrribs; + memcpy(attribs, glfwPixelFormatAttribs, sizeof(glfwPixelFormatAttribs)); + + if (_glfw.wgl.ARB_multisample) + { + attribs[numAttribs++] = WGL_SAMPLES_ARB; + } + + if (api == GLFW_OPENGL_API) + { + if (_glfw.wgl.ARB_framebuffer_sRGB || + _glfw.wgl.EXT_framebuffer_sRGB) + { + attribs[numAttribs++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; + } + } + else + { + if (_glfw.wgl.EXT_colorspace) + { + attribs[numAttribs++] = WGL_COLORSPACE_EXT; + } + } + return numAttribs; +} + +// Returns all formats in glfwPixelFormats attribute of the specified pixel format +// values should be of size GLFW_PFA_COUNT and on return will hold integer values +// which can be indexed using glfwEnumPixelFormatAttribs +// returns 1 on success, 0 on failure +static int getPixelFormatAttribs(_GLFWwindow* window, int pixelFormat, int numAttribs, int* attribs, int* values ) +{ + assert(_glfw.wgl.ARB_pixel_format); + + if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc, + pixelFormat, + 0, numAttribs, + attribs, values)) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "WGL: Failed to retrieve pixel format attributes"); + return 0; + } + + return 1; +} + +static int getPixelFormatAttribFromArray( int* attribs, int* values, int attrib ) +{ + int i; + for (i = 0; i < sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0]); ++i ) + { + if ( attribs[i] == attrib ) + return values[i]; + } + + // error + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "WGL: Unknown attribute requested from attribute array"); + return 0; +} // Returns the specified attribute of the specified pixel format // @@ -60,7 +157,11 @@ static int choosePixelFormat(_GLFWwindow* window, { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, pixelFormat, nativeCount, usableCount; + int i, pixelFormat, nativeCount, usableCount, numAttribs, hintPos; + int pfAttribs[sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0])]; + int pfValues[sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0])]; + + numAttribs = initPixelFormatAttribArry(pfAttribs, ctxconfig->client); if (_glfw.wgl.ARB_pixel_format) { @@ -87,54 +188,56 @@ static int choosePixelFormat(_GLFWwindow* window, if (_glfw.wgl.ARB_pixel_format) { // Get pixel format attributes through "modern" extension + getPixelFormatAttribs(window, n, numAttribs, pfAttribs, pfValues ); + hintPos = 0; - if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) || - !getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB)) + if (!getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_SUPPORT_OPENGL_ARB) || + !getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DRAW_TO_WINDOW_ARB)) { continue; } - if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) != - WGL_TYPE_RGBA_ARB) + if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_PIXEL_TYPE_ARB) != + WGL_TYPE_RGBA_ARB ) { continue; } - if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) == - WGL_NO_ACCELERATION_ARB) + if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCELERATION_ARB) == + WGL_NO_ACCELERATION_ARB ) { continue; } - u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB); - u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB); - u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB); - u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB); + u->redBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_RED_BITS_ARB); + u->greenBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_GREEN_BITS_ARB); + u->blueBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_BLUE_BITS_ARB); + u->alphaBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ALPHA_BITS_ARB); - u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB); - u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB); + u->depthBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DEPTH_BITS_ARB); + u->stencilBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_STENCIL_BITS_ARB); - u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB); - u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB); - u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB); - u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB); + u->accumRedBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_RED_BITS_ARB); + u->accumGreenBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_GREEN_BITS_ARB); + u->accumBlueBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_BLUE_BITS_ARB); + u->accumAlphaBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_ALPHA_BITS_ARB); - u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB); + u->auxBuffers = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_AUX_BUFFERS_ARB); - if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB)) + if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_STEREO_ARB)) u->stereo = GLFW_TRUE; - if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB)) + if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DOUBLE_BUFFER_ARB)) u->doublebuffer = GLFW_TRUE; if (_glfw.wgl.ARB_multisample) - u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB); + u->samples = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_SAMPLES_ARB); if (ctxconfig->client == GLFW_OPENGL_API) { if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) { - if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) + if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) u->sRGB = GLFW_TRUE; } } @@ -142,7 +245,7 @@ static int choosePixelFormat(_GLFWwindow* window, { if (_glfw.wgl.EXT_colorspace) { - if (getPixelFormatAttrib(window, n, WGL_COLORSPACE_EXT) == + if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT) { u->sRGB = GLFW_TRUE; From 3d748cf530ca13742c9817577dff6952b2f19798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 30 Dec 2018 18:16:28 +0100 Subject: [PATCH 32/43] Cleanup Related to #1381. --- src/wgl_context.c | 251 +++++++++++++++++++--------------------------- 1 file changed, 103 insertions(+), 148 deletions(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index 5f8d63a63..51916e576 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -31,123 +31,33 @@ #include #include -// array of pixel format attributes we need -static const int glfwPixelFormatAttribs[] = { - WGL_SUPPORT_OPENGL_ARB, - WGL_DRAW_TO_WINDOW_ARB, - WGL_PIXEL_TYPE_ARB, - WGL_ACCELERATION_ARB, - WGL_RED_BITS_ARB, - WGL_RED_SHIFT_ARB, - WGL_GREEN_BITS_ARB, - WGL_GREEN_SHIFT_ARB, - WGL_BLUE_BITS_ARB, - WGL_BLUE_SHIFT_ARB, - WGL_ALPHA_BITS_ARB, - WGL_ALPHA_SHIFT_ARB, - WGL_DEPTH_BITS_ARB, - WGL_STENCIL_BITS_ARB, - WGL_ACCUM_BITS_ARB, - WGL_ACCUM_RED_BITS_ARB, - WGL_ACCUM_GREEN_BITS_ARB, - WGL_ACCUM_BLUE_BITS_ARB, - WGL_ACCUM_ALPHA_BITS_ARB, - WGL_AUX_BUFFERS_ARB, - WGL_STEREO_ARB, - WGL_DOUBLE_BUFFER_ARB, - // ARB EXT attribs only below this line, see initPixelFormatAttribArry - WGL_SAMPLES_ARB, - WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, - WGL_COLORSPACE_EXT -}; - -// initialize array attribs with formatattribs available -// attribs array must be at least of size sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0]) -// returns number of valid elemets in array -static int initPixelFormatAttribArry( int* attribs, int api ) -{ - const int numARBEXTAtrribs = 3; // Update this value when adding ARB EXT attribs - int numAttribs = sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0]) - numARBEXTAtrribs; - memcpy(attribs, glfwPixelFormatAttribs, sizeof(glfwPixelFormatAttribs)); - - if (_glfw.wgl.ARB_multisample) - { - attribs[numAttribs++] = WGL_SAMPLES_ARB; - } - - if (api == GLFW_OPENGL_API) - { - if (_glfw.wgl.ARB_framebuffer_sRGB || - _glfw.wgl.EXT_framebuffer_sRGB) - { - attribs[numAttribs++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; - } - } - else - { - if (_glfw.wgl.EXT_colorspace) - { - attribs[numAttribs++] = WGL_COLORSPACE_EXT; - } - } - return numAttribs; -} - -// Returns all formats in glfwPixelFormats attribute of the specified pixel format -// values should be of size GLFW_PFA_COUNT and on return will hold integer values -// which can be indexed using glfwEnumPixelFormatAttribs -// returns 1 on success, 0 on failure -static int getPixelFormatAttribs(_GLFWwindow* window, int pixelFormat, int numAttribs, int* attribs, int* values ) -{ - assert(_glfw.wgl.ARB_pixel_format); - - if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc, - pixelFormat, - 0, numAttribs, - attribs, values)) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "WGL: Failed to retrieve pixel format attributes"); - return 0; - } - - return 1; -} - -static int getPixelFormatAttribFromArray( int* attribs, int* values, int attrib ) +// Return the value corresponding to the specified attribute +// +static int findPixelFormatAttribValue(const int* attribs, + int attribCount, + const int* values, + int attrib) { int i; - for (i = 0; i < sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0]); ++i ) + + for (i = 0; i < attribCount; i++) { - if ( attribs[i] == attrib ) + if (attribs[i] == attrib) return values[i]; } - // error _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "WGL: Unknown attribute requested from attribute array"); + "WGL: Unknown pixel format attribute requested"); return 0; } -// Returns the specified attribute of the specified pixel format -// -static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) -{ - int value = 0; - - assert(_glfw.wgl.ARB_pixel_format); - - if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc, - pixelFormat, - 0, 1, &attrib, &value)) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "WGL: Failed to retrieve pixel format attribute"); - return 0; - } - - return value; +#define addAttrib(a) \ +{ \ + assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \ + attribs[attribCount++] = a; \ } +#define findAttribValue(a) \ + findPixelFormatAttribValue(attribs, attribCount, values, a) // Return a list of available and usable framebuffer configs // @@ -157,17 +67,60 @@ static int choosePixelFormat(_GLFWwindow* window, { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, pixelFormat, nativeCount, usableCount, numAttribs, hintPos; - int pfAttribs[sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0])]; - int pfValues[sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0])]; - - numAttribs = initPixelFormatAttribArry(pfAttribs, ctxconfig->client); + int i, pixelFormat, nativeCount, usableCount, attribCount; + int attribs[40]; + int values[sizeof(attribs) / sizeof(attribs[0])]; if (_glfw.wgl.ARB_pixel_format) { - nativeCount = getPixelFormatAttrib(window, - 1, - WGL_NUMBER_PIXEL_FORMATS_ARB); + const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB; + + if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc, + 1, 0, 1, &attrib, &nativeCount)) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "WGL: Failed to retrieve pixel format attribute"); + return 0; + } + + attribCount = 0; + + addAttrib(WGL_SUPPORT_OPENGL_ARB); + addAttrib(WGL_DRAW_TO_WINDOW_ARB); + addAttrib(WGL_PIXEL_TYPE_ARB); + addAttrib(WGL_ACCELERATION_ARB); + addAttrib(WGL_RED_BITS_ARB); + addAttrib(WGL_RED_SHIFT_ARB); + addAttrib(WGL_GREEN_BITS_ARB); + addAttrib(WGL_GREEN_SHIFT_ARB); + addAttrib(WGL_BLUE_BITS_ARB); + addAttrib(WGL_BLUE_SHIFT_ARB); + addAttrib(WGL_ALPHA_BITS_ARB); + addAttrib(WGL_ALPHA_SHIFT_ARB); + addAttrib(WGL_DEPTH_BITS_ARB); + addAttrib(WGL_STENCIL_BITS_ARB); + addAttrib(WGL_ACCUM_BITS_ARB); + addAttrib(WGL_ACCUM_RED_BITS_ARB); + addAttrib(WGL_ACCUM_GREEN_BITS_ARB); + addAttrib(WGL_ACCUM_BLUE_BITS_ARB); + addAttrib(WGL_ACCUM_ALPHA_BITS_ARB); + addAttrib(WGL_AUX_BUFFERS_ARB); + addAttrib(WGL_STEREO_ARB); + addAttrib(WGL_DOUBLE_BUFFER_ARB); + + if (_glfw.wgl.ARB_multisample) + addAttrib(WGL_SAMPLES_ARB); + + if (ctxconfig->client == GLFW_OPENGL_API) + { + if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) + addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); + } + else + { + if (_glfw.wgl.EXT_colorspace) + addAttrib(WGL_COLORSPACE_EXT); + } } else { @@ -182,62 +135,64 @@ static int choosePixelFormat(_GLFWwindow* window, for (i = 0; i < nativeCount; i++) { - const int n = i + 1; _GLFWfbconfig* u = usableConfigs + usableCount; + pixelFormat = i + 1; if (_glfw.wgl.ARB_pixel_format) { // Get pixel format attributes through "modern" extension - getPixelFormatAttribs(window, n, numAttribs, pfAttribs, pfValues ); - hintPos = 0; - if (!getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_SUPPORT_OPENGL_ARB) || - !getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DRAW_TO_WINDOW_ARB)) + if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc, + pixelFormat, 0, + attribCount, + attribs, values)) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "WGL: Failed to retrieve pixel format attributes"); + return 0; + } + + if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) || + !findAttribValue(WGL_DRAW_TO_WINDOW_ARB)) { continue; } - if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_PIXEL_TYPE_ARB) != - WGL_TYPE_RGBA_ARB ) - { + if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) continue; - } - if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCELERATION_ARB) == - WGL_NO_ACCELERATION_ARB ) - { + if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) continue; - } - u->redBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_RED_BITS_ARB); - u->greenBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_GREEN_BITS_ARB); - u->blueBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_BLUE_BITS_ARB); - u->alphaBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ALPHA_BITS_ARB); + u->redBits = findAttribValue(WGL_RED_BITS_ARB); + u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB); + u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB); + u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB); - u->depthBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DEPTH_BITS_ARB); - u->stencilBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_STENCIL_BITS_ARB); + u->depthBits = findAttribValue(WGL_DEPTH_BITS_ARB); + u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB); - u->accumRedBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_RED_BITS_ARB); - u->accumGreenBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_GREEN_BITS_ARB); - u->accumBlueBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_BLUE_BITS_ARB); - u->accumAlphaBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_ALPHA_BITS_ARB); + u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB); + u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB); + u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB); + u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB); - u->auxBuffers = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_AUX_BUFFERS_ARB); + u->auxBuffers = findAttribValue(WGL_AUX_BUFFERS_ARB); - if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_STEREO_ARB)) + if (findAttribValue(WGL_STEREO_ARB)) u->stereo = GLFW_TRUE; - if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DOUBLE_BUFFER_ARB)) + if (findAttribValue(WGL_DOUBLE_BUFFER_ARB)) u->doublebuffer = GLFW_TRUE; if (_glfw.wgl.ARB_multisample) - u->samples = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_SAMPLES_ARB); + u->samples = findAttribValue(WGL_SAMPLES_ARB); if (ctxconfig->client == GLFW_OPENGL_API) { if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) { - if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) + if (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) u->sRGB = GLFW_TRUE; } } @@ -245,11 +200,8 @@ static int choosePixelFormat(_GLFWwindow* window, { if (_glfw.wgl.EXT_colorspace) { - if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_COLORSPACE_EXT) == - WGL_COLORSPACE_SRGB_EXT) - { + if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT) u->sRGB = GLFW_TRUE; - } } } } @@ -260,7 +212,7 @@ static int choosePixelFormat(_GLFWwindow* window, PIXELFORMATDESCRIPTOR pfd; if (!DescribePixelFormat(window->context.wgl.dc, - n, + pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { @@ -303,7 +255,7 @@ static int choosePixelFormat(_GLFWwindow* window, u->doublebuffer = GLFW_TRUE; } - u->handle = n; + u->handle = pixelFormat; usableCount++; } @@ -332,6 +284,9 @@ static int choosePixelFormat(_GLFWwindow* window, return pixelFormat; } +#undef addAttrib +#undef findAttribValue + static void makeContextCurrentWGL(_GLFWwindow* window) { if (window) From 29d8ca4ce4aef8e0afca62b8ace9ee18a24a9ffd Mon Sep 17 00:00:00 2001 From: maobaoqi Date: Tue, 15 Jan 2019 14:34:42 +0000 Subject: [PATCH 33/43] Fix bug in CrossProduct function in boing example Closes #1418. --- examples/boing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/boing.c b/examples/boing.c index 5b8e667e8..d13c58414 100644 --- a/examples/boing.c +++ b/examples/boing.c @@ -165,7 +165,7 @@ void CrossProduct( vertex_t a, vertex_t b, vertex_t c, vertex_t *n ) v2 = c.y - a.y; v3 = c.z - a.z; - n->x = u2 * v3 - v2 * v3; + n->x = u2 * v3 - v2 * u3; n->y = u3 * v1 - v3 * u1; n->z = u1 * v2 - v1 * u2; } From 757cd3aea210d74e1de8d9ad0fce2865fe877c03 Mon Sep 17 00:00:00 2001 From: Ivan Achlaqullah Date: Sat, 19 Jan 2019 00:46:46 +0700 Subject: [PATCH 34/43] Add Visual Studio .vs directory to .gitignore Closes #1419. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f6103c222..859499268 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ _ReSharper* *.dir *.vcxproj* *.sln +.vs/ Win32 x64 Debug From a46104ee69360ee73d59cfd397a7f1b23d751b77 Mon Sep 17 00:00:00 2001 From: iamCaveLamp Date: Mon, 24 Dec 2018 22:24:51 +0200 Subject: [PATCH 35/43] Removed duplicates of centerCursor function --- src/cocoa_window.m | 17 ++++------------- src/input.c | 9 +++++++++ src/internal.h | 1 + src/win32_window.c | 11 +---------- src/window.c | 7 +------ src/x11_window.c | 11 +---------- 6 files changed, 17 insertions(+), 39 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 7011a797a..6382968c8 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -67,15 +67,6 @@ static NSUInteger getStyleMask(_GLFWwindow* window) return styleMask; } -// Center the cursor in the view of the window -// -static void centerCursor(_GLFWwindow *window) -{ - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); -} - // Returns whether the cursor is in the client area of the specified window // static GLFWbool cursorInClientArea(_GLFWwindow* window) @@ -133,7 +124,7 @@ static void updateCursorMode(_GLFWwindow* window) _glfwPlatformGetCursorPos(window, &_glfw.ns.restoreCursorPosX, &_glfw.ns.restoreCursorPosY); - centerCursor(window); + _glfwCenterCursor(window); CGAssociateMouseAndMouseCursorPosition(false); } else if (_glfw.ns.disabledCursorWindow == window) @@ -280,7 +271,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; [window->context.nsgl.object update]; if (_glfw.ns.disabledCursorWindow == window) - centerCursor(window); + _glfwCenterCursor(window); const int maximized = [window->ns.object isZoomed]; if (window->ns.maximized != maximized) @@ -315,7 +306,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; [window->context.nsgl.object update]; if (_glfw.ns.disabledCursorWindow == window) - centerCursor(window); + _glfwCenterCursor(window); int x, y; _glfwPlatformGetWindowPos(window, &x, &y); @@ -341,7 +332,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)windowDidBecomeKey:(NSNotification *)notification { if (_glfw.ns.disabledCursorWindow == window) - centerCursor(window); + _glfwCenterCursor(window); _glfwInputWindowFocus(window, GLFW_TRUE); updateCursorMode(window); diff --git a/src/input.c b/src/input.c index 460e9f31f..c3da79dd8 100644 --- a/src/input.c +++ b/src/input.c @@ -453,6 +453,15 @@ void _glfwFreeJoystick(_GLFWjoystick* js) memset(js, 0, sizeof(_GLFWjoystick)); } +// Center the cursor in the middle of the window +// +void _glfwCenterCursor(_GLFWwindow* window) +{ + int width, height; + + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); +} ////////////////////////////////////////////////////////////////////////// ////// GLFW public API ////// diff --git a/src/internal.h b/src/internal.h index c7c5bf8fd..aa8376851 100644 --- a/src/internal.h +++ b/src/internal.h @@ -760,6 +760,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, int buttonCount, int hatCount); void _glfwFreeJoystick(_GLFWjoystick* js); +void _glfwCenterCursor(_GLFWwindow* window); GLFWbool _glfwInitVulkan(int mode); void _glfwTerminateVulkan(void); diff --git a/src/win32_window.c b/src/win32_window.c index a0abca060..0953292e6 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -236,15 +236,6 @@ static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) } } -// Centers the cursor over the window client area -// -static void centerCursor(_GLFWwindow* window) -{ - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); -} - // Updates the cursor image according to its cursor mode // static void updateCursorImage(_GLFWwindow* window) @@ -287,7 +278,7 @@ static void disableCursor(_GLFWwindow* window) &_glfw.win32.restoreCursorPosX, &_glfw.win32.restoreCursorPosY); updateCursorImage(window); - centerCursor(window); + _glfwCenterCursor(window); updateClipRect(window); if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) diff --git a/src/window.c b/src/window.c index 2c98d4cb8..6367f2ba3 100644 --- a/src/window.c +++ b/src/window.c @@ -143,7 +143,6 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor) window->monitor = monitor; } - ////////////////////////////////////////////////////////////////////////// ////// GLFW public API ////// ////////////////////////////////////////////////////////////////////////// @@ -230,11 +229,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, if (window->monitor) { if (wndconfig.centerCursor) - { - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); - } + _glfwCenterCursor(window); } else { diff --git a/src/x11_window.c b/src/x11_window.c index 19ed73723..252d9140a 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -501,15 +501,6 @@ static char* convertLatin1toUTF8(const char* source) return target; } -// Centers the cursor over the window client area -// -static void centerCursor(_GLFWwindow* window) -{ - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); -} - // Updates the cursor image according to its cursor mode // static void updateCursorImage(_GLFWwindow* window) @@ -553,7 +544,7 @@ static void disableCursor(_GLFWwindow* window) &_glfw.x11.restoreCursorPosX, &_glfw.x11.restoreCursorPosY); updateCursorImage(window); - centerCursor(window); + _glfwCenterCursor(window); XGrabPointer(_glfw.x11.display, window->x11.handle, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, From d5ab3e919a4f163f4010f7112a9cf1bdcd80f805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 22 Jan 2019 20:54:16 +0100 Subject: [PATCH 36/43] Cleanup Replace client area with content area. --- docs/input.dox | 12 ++-- docs/intro.dox | 16 ++--- docs/news.dox | 6 +- docs/spaces.svg | 157 ++++++++++++++++++++++--------------------- docs/window.dox | 32 ++++----- include/GLFW/glfw3.h | 100 +++++++++++++-------------- src/cocoa_window.m | 16 ++--- src/input.c | 6 +- src/internal.h | 2 +- src/win32_window.c | 24 +++---- src/window.c | 4 +- src/x11_window.c | 2 +- 12 files changed, 191 insertions(+), 186 deletions(-) diff --git a/docs/input.dox b/docs/input.dox index 73c7ef70d..159fb454e 100644 --- a/docs/input.dox +++ b/docs/input.dox @@ -248,7 +248,7 @@ glfwSetCursorPosCallback(window, cursor_position_callback); @endcode The callback functions receives the cursor position, measured in screen -coordinates but relative to the top-left corner of the window client area. On +coordinates but relative to the top-left corner of the window content area. On platforms that provide it, the full sub-pixel cursor position is passed on. @code @@ -377,7 +377,7 @@ glfwSetCursor(window, cursor); @endcode Once set, the cursor image will be used as long as the system cursor is over the -client area of the window and the [cursor mode](@ref cursor_mode) is set +content area of the window and the [cursor mode](@ref cursor_mode) is set to `GLFW_CURSOR_NORMAL`. A single cursor may be set for any number of windows. @@ -394,7 +394,7 @@ default cursor. This does not affect the cursor mode. @subsection cursor_enter Cursor enter/leave events -If you wish to be notified when the cursor enters or leaves the client area of +If you wish to be notified when the cursor enters or leaves the content area of a window, set a cursor enter/leave callback. @code @@ -408,16 +408,16 @@ void cursor_enter_callback(GLFWwindow* window, int entered) { if (entered) { - // The cursor entered the client area of the window + // The cursor entered the content area of the window } else { - // The cursor left the client area of the window + // The cursor left the content area of the window } } @endcode -You can query whether the cursor is currently inside the client area of the +You can query whether the cursor is currently inside the content area of the window with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute. @code diff --git a/docs/intro.dox b/docs/intro.dox index 58ab8fd5d..36bc73e6f 100644 --- a/docs/intro.dox +++ b/docs/intro.dox @@ -208,24 +208,24 @@ future that same call may generate a different error or become valid. @section coordinate_systems Coordinate systems GLFW has two primary coordinate systems: the _virtual screen_ and the window -_client area_ or _content area_. Both use the same unit: _virtual screen +_content area_ or _content area_. Both use the same unit: _virtual screen coordinates_, or just _screen coordinates_, which don't necessarily correspond to pixels. -Both the virtual screen and the client area coordinate systems have the X-axis +Both the virtual screen and the content area coordinate systems have the X-axis pointing to the right and the Y-axis pointing down. Window and monitor positions are specified as the position of the upper-left corners of their content areas relative to the virtual screen, while cursor -positions are specified relative to a window's client area. +positions are specified relative to a window's content area. -Because the origin of the window's client area coordinate system is also the -point from which the window position is specified, you can translate client area -coordinates to the virtual screen by adding the window position. The window -frame, when present, extends out from the client area but does not affect the -window position. +Because the origin of the window's content area coordinate system is also the +point from which the window position is specified, you can translate content +area coordinates to the virtual screen by adding the window position. The +window frame, when present, extends out from the content area but does not +affect the window position. Almost all positions and sizes in GLFW are measured in screen coordinates relative to one of the two origins above. This includes cursor positions, diff --git a/docs/news.dox b/docs/news.dox index 0cdec0055..43f384eab 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -128,7 +128,7 @@ window hint. It is enabled by default. @subsection news_33_hover Mouse cursor hover window attribute -GLFW now supports polling whether the cursor is hovering over the window client +GLFW now supports polling whether the cursor is hovering over the window content area with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute. This attribute corresponds to the [cursor enter/leave](@ref cursor_enter) event. @@ -308,7 +308,7 @@ glfwWaitEvents to return. @subsection news_31_framesize Window frame size query GLFW now supports querying the size, on each side, of the frame around the -client area of a window, with @ref glfwGetWindowFrameSize. +content area of a window, with @ref glfwGetWindowFrameSize. @see [Window size](@ref window_size) @@ -506,7 +506,7 @@ glfwSetWindowFocusCallback. @subsection news_30_enterleave Cursor enter/leave callback Each window now has a callback for when the mouse cursor enters or leaves its -client area, which is set with @ref glfwSetCursorEnterCallback. +content area, which is set with @ref glfwSetCursorEnterCallback. @subsection news_30_wndtitle Initial window title diff --git a/docs/spaces.svg b/docs/spaces.svg index 562fa8be1..5b3264609 100644 --- a/docs/spaces.svg +++ b/docs/spaces.svg @@ -13,7 +13,7 @@ height="327.98221" id="svg2" version="1.1" - inkscape:version="0.48.4 r9939" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)" sodipodi:docname="spaces.svg"> @@ -38,11 +38,11 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="2.5611424" - inkscape:cx="344.24359" - inkscape:cy="163.9911" + inkscape:zoom="1.8110012" + inkscape:cx="320.68941" + inkscape:cy="159.80509" inkscape:document-units="px" - inkscape:current-layer="svg2" + inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1920" inkscape:window-height="1021" @@ -475,18 +475,18 @@ inkscape:export-ydpi="109.89113" /> + y="340.20465" + style="font-size:12px;line-height:1.25;font-family:sans-serif">  @@ -647,74 +647,6 @@ style="font-size:10px" id="path3239" /> - - - - - - - - - - - - - - - - - - @@ -868,5 +800,78 @@ style="font-size:5px" id="path3161" /> + + + + + + + + + + + + + + + + + + + diff --git a/docs/window.dox b/docs/window.dox index f30127847..5f94f3587 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -599,7 +599,7 @@ void window_close_callback(GLFWwindow* window) The size of a window can be changed with @ref glfwSetWindowSize. For windowed mode windows, this sets the size, in -[screen coordinates](@ref coordinate_systems) of the _client area_ or _content +[screen coordinates](@ref coordinate_systems) of the _content area_ or _content area_ of the window. The window system may impose limits on window size. @code @@ -619,7 +619,7 @@ glfwSetWindowSizeCallback(window, window_size_callback); @endcode The callback function receives the new size, in screen coordinates, of the -client area of the window when the window is resized. +content area of the window when the window is resized. @code void window_size_callback(GLFWwindow* window, int width, int height) @@ -640,9 +640,9 @@ calls. The window size is in screen coordinates, not pixels. Use the [framebuffer size](@ref window_fbsize), which is in pixels, for pixel-based calls. -The above functions work with the size of the client area, but decorated windows -typically have title bars and window frames around this rectangle. You can -retrieve the extents of these with @ref glfwGetWindowFrameSize. +The above functions work with the size of the content area, but decorated +windows typically have title bars and window frames around this rectangle. You +can retrieve the extents of these with @ref glfwGetWindowFrameSize. @code int left, top, right, bottom; @@ -650,7 +650,7 @@ glfwGetWindowFrameSize(window, &left, &top, &right, &bottom); @endcode The returned values are the distances, in screen coordinates, from the edges of -the client area to the corresponding edges of the full window. As they are +the content area to the corresponding edges of the full window. As they are distances and not coordinates, they are always zero or positive. @@ -737,10 +737,10 @@ GLFW_SCALE_TO_MONITOR window hint. @subsection window_sizelimits Window size limits -The minimum and maximum size of the client area of a windowed mode window can be -enforced with @ref glfwSetWindowSizeLimits. The user may resize the window to -any size and aspect ratio within the specified limits, unless the aspect ratio -is also set. +The minimum and maximum size of the content area of a windowed mode window can +be enforced with @ref glfwSetWindowSizeLimits. The user may resize the window +to any size and aspect ratio within the specified limits, unless the aspect +ratio is also set. @code glfwSetWindowSizeLimits(window, 200, 200, 400, 400); @@ -755,7 +755,7 @@ glfwSetWindowSizeLimits(window, 640, 480, GLFW_DONT_CARE, GLFW_DONT_CARE); To disable size limits for a window, set them all to `GLFW_DONT_CARE`. -The aspect ratio of the client area of a windowed mode window can be enforced +The aspect ratio of the content area of a windowed mode window can be enforced with @ref glfwSetWindowAspectRatio. The user may resize the window freely unless size limits are also set, but the size will be constrained to maintain the aspect ratio. @@ -785,7 +785,7 @@ are undefined if they conflict. The position of a windowed-mode window can be changed with @ref glfwSetWindowPos. This moves the window so that the upper-left corner of its -client area has the specified [screen coordinates](@ref coordinate_systems). +content area has the specified [screen coordinates](@ref coordinate_systems). The window system may put limitations on window placement. @code @@ -800,7 +800,7 @@ glfwSetWindowPosCallback(window, window_pos_callback); @endcode The callback function receives the new position, in screen coordinates, of the -upper-left corner of the client area when the window is moved. +upper-left corner of the content area when the window is moved. @code void window_pos_callback(GLFWwindow* window, int xpos, int ypos) @@ -809,7 +809,7 @@ void window_pos_callback(GLFWwindow* window, int xpos, int ypos) @endcode There is also @ref glfwGetWindowPos for directly retrieving the current position -of the client area of the window. +of the content area of the window. @code int xpos, ypos; @@ -1249,8 +1249,8 @@ __GLFW_MAXIMIZED__ indicates whether the specified window is maximized. See @anchor GLFW_HOVERED_attrib __GLFW_HOVERED__ indicates whether the cursor is currently directly over the -client area of the window, with no other windows between. See @ref cursor_enter -for details. +content area of the window, with no other windows between. See @ref +cursor_enter for details. @anchor GLFW_VISIBLE_attrib __GLFW_VISIBLE__ indicates whether the specified window is visible. See @ref diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 8606edc16..35a781c93 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1170,9 +1170,9 @@ typedef void (* GLFWerrorfun)(int,const char*); * * @param[in] window The window that was moved. * @param[in] xpos The new x-coordinate, in screen coordinates, of the - * upper-left corner of the client area of the window. + * upper-left corner of the content area of the window. * @param[in] ypos The new y-coordinate, in screen coordinates, of the - * upper-left corner of the client area of the window. + * upper-left corner of the content area of the window. * * @sa @ref window_pos * @sa @ref glfwSetWindowPosCallback @@ -1349,9 +1349,9 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); * * @param[in] window The window that received the event. * @param[in] xpos The new cursor x-coordinate, relative to the left edge of - * the client area. + * the content area. * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the - * client area. + * content area. * * @sa @ref cursor_pos * @sa @ref glfwSetCursorPosCallback @@ -1367,7 +1367,7 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); * This is the function signature for cursor enter/leave callback functions. * * @param[in] window The window that received the event. - * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client + * @param[in] entered `GLFW_TRUE` if the cursor entered the window's content * area, or `GLFW_FALSE` if it left it. * * @sa @ref cursor_enter @@ -2644,19 +2644,19 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); */ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); -/*! @brief Retrieves the position of the client area of the specified window. +/*! @brief Retrieves the position of the content area of the specified window. * * This function retrieves the position, in screen coordinates, of the - * upper-left corner of the client area of the specified window. + * upper-left corner of the content area of the specified window. * * Any or all of the position arguments may be `NULL`. If an error occurs, all * non-`NULL` position arguments will be set to zero. * * @param[in] window The window to query. * @param[out] xpos Where to store the x-coordinate of the upper-left corner of - * the client area, or `NULL`. + * the content area, or `NULL`. * @param[out] ypos Where to store the y-coordinate of the upper-left corner of - * the client area, or `NULL`. + * the content area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -2676,10 +2676,10 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i */ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); -/*! @brief Sets the position of the client area of the specified window. +/*! @brief Sets the position of the content area of the specified window. * * This function sets the position, in screen coordinates, of the upper-left - * corner of the client area of the specified windowed mode window. If the + * corner of the content area of the specified windowed mode window. If the * window is a full screen window, this function does nothing. * * __Do not use this function__ to move an already visible window unless you @@ -2689,8 +2689,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); * cannot and should not override these limits. * * @param[in] window The window to query. - * @param[in] xpos The x-coordinate of the upper-left corner of the client area. - * @param[in] ypos The y-coordinate of the upper-left corner of the client area. + * @param[in] xpos The x-coordinate of the upper-left corner of the content area. + * @param[in] ypos The y-coordinate of the upper-left corner of the content area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -2711,9 +2711,9 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); */ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); -/*! @brief Retrieves the size of the client area of the specified window. +/*! @brief Retrieves the size of the content area of the specified window. * - * This function retrieves the size, in screen coordinates, of the client area + * This function retrieves the size, in screen coordinates, of the content area * of the specified window. If you wish to retrieve the size of the * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. * @@ -2722,9 +2722,9 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); * * @param[in] window The window whose size to retrieve. * @param[out] width Where to store the width, in screen coordinates, of the - * client area, or `NULL`. + * content area, or `NULL`. * @param[out] height Where to store the height, in screen coordinates, of the - * client area, or `NULL`. + * content area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -2743,7 +2743,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); /*! @brief Sets the size limits of the specified window. * - * This function sets the size limits of the client area of the specified + * This function sets the size limits of the content area of the specified * window. If the window is full screen, the size limits only take effect * once it is made windowed. If the window is not resizable, this function * does nothing. @@ -2755,14 +2755,14 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); * dimensions and all must be greater than or equal to zero. * * @param[in] window The window to set limits for. - * @param[in] minwidth The minimum width, in screen coordinates, of the client + * @param[in] minwidth The minimum width, in screen coordinates, of the content * area, or `GLFW_DONT_CARE`. * @param[in] minheight The minimum height, in screen coordinates, of the - * client area, or `GLFW_DONT_CARE`. - * @param[in] maxwidth The maximum width, in screen coordinates, of the client + * content area, or `GLFW_DONT_CARE`. + * @param[in] maxwidth The maximum width, in screen coordinates, of the content * area, or `GLFW_DONT_CARE`. * @param[in] maxheight The maximum height, in screen coordinates, of the - * client area, or `GLFW_DONT_CARE`. + * content area, or `GLFW_DONT_CARE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. @@ -2786,7 +2786,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe /*! @brief Sets the aspect ratio of the specified window. * - * This function sets the required aspect ratio of the client area of the + * This function sets the required aspect ratio of the content area of the * specified window. If the window is full screen, the aspect ratio only takes * effect once it is made windowed. If the window is not resizable, this * function does nothing. @@ -2827,9 +2827,9 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe */ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); -/*! @brief Sets the size of the client area of the specified window. +/*! @brief Sets the size of the content area of the specified window. * - * This function sets the size, in screen coordinates, of the client area of + * This function sets the size, in screen coordinates, of the content area of * the specified window. * * For full screen windows, this function updates the resolution of its desired @@ -2845,9 +2845,9 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); * * @param[in] window The window to resize. * @param[in] width The desired width, in screen coordinates, of the window - * client area. + * content area. * @param[in] height The desired height, in screen coordinates, of the window - * client area. + * content area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -3251,7 +3251,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * The window position is ignored when setting a monitor. * * When the monitor is `NULL`, the position, width and height are used to - * place the window client area. The refresh rate is ignored when no monitor + * place the window content area. The refresh rate is ignored when no monitor * is specified. * * If you only wish to update the resolution of a full screen window or the @@ -3264,12 +3264,12 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * @param[in] window The window whose monitor, size or video mode to set. * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. * @param[in] xpos The desired x-coordinate of the upper-left corner of the - * client area. + * content area. * @param[in] ypos The desired y-coordinate of the upper-left corner of the - * client area. - * @param[in] width The desired with, in screen coordinates, of the client area - * or video mode. - * @param[in] height The desired height, in screen coordinates, of the client + * content area. + * @param[in] width The desired with, in screen coordinates, of the content + * area or video mode. + * @param[in] height The desired height, in screen coordinates, of the content * area or video mode. * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode, * or `GLFW_DONT_CARE`. @@ -3419,8 +3419,8 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); * * This function sets the position callback of the specified window, which is * called when the window is moved. The callback is provided with the - * position, in screen coordinates, of the upper-left corner of the client area - * of the window. + * position, in screen coordinates, of the upper-left corner of the content + * area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set @@ -3447,7 +3447,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow * * This function sets the size callback of the specified window, which is * called when the window is resized. The callback is provided with the size, - * in screen coordinates, of the client area of the window. + * in screen coordinates, of the content area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set @@ -3504,7 +3504,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi /*! @brief Sets the refresh callback for the specified window. * * This function sets the refresh callback of the specified window, which is - * called when the client area of the window needs to be redrawn, for example + * called when the content area of the window needs to be redrawn, for example * if the window has been exposed after having been covered by another window. * * On compositing window systems such as Aero, Compiz, Aqua or Wayland, where @@ -3838,8 +3838,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * modes: * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. - * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client - * area of the window but does not restrict the cursor from leaving. + * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the + * content area of the window but does not restrict the cursor from leaving. * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual * and unlimited cursor movement. This is useful for implementing for * example 3D camera controls. @@ -4042,11 +4042,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); */ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); -/*! @brief Retrieves the position of the cursor relative to the client area of +/*! @brief Retrieves the position of the cursor relative to the content area of * the window. * * This function returns the position of the cursor, in screen coordinates, - * relative to the upper-left corner of the client area of the specified + * relative to the upper-left corner of the content area of the specified * window. * * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor @@ -4062,9 +4062,9 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); * * @param[in] window The desired window. * @param[out] xpos Where to store the cursor x-coordinate, relative to the - * left edge of the client area, or `NULL`. + * left edge of the content area, or `NULL`. * @param[out] ypos Where to store the cursor y-coordinate, relative to the to - * top edge of the client area, or `NULL`. + * top edge of the content area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -4080,11 +4080,11 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); */ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); -/*! @brief Sets the position of the cursor, relative to the client area of the +/*! @brief Sets the position of the cursor, relative to the content area of the * window. * * This function sets the position, in screen coordinates, of the cursor - * relative to the upper-left corner of the client area of the specified + * relative to the upper-left corner of the content area of the specified * window. The window must have input focus. If the window does not have * input focus when this function is called, it fails silently. * @@ -4099,9 +4099,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); * * @param[in] window The desired window. * @param[in] xpos The desired x-coordinate, relative to the left edge of the - * client area. + * content area. * @param[in] ypos The desired y-coordinate, relative to the top edge of the - * client area. + * content area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -4211,7 +4211,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); /*! @brief Sets the cursor for the window. * * This function sets the cursor image to be used when the cursor is over the - * client area of the specified window. The set cursor will only be visible + * content area of the specified window. The set cursor will only be visible * when the [cursor mode](@ref cursor_mode) of the window is * `GLFW_CURSOR_NORMAL`. * @@ -4384,7 +4384,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo * This function sets the cursor position callback of the specified window, * which is called when the cursor is moved. The callback is provided with the * position, in screen coordinates, relative to the upper-left corner of the - * client area of the window. + * content area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set @@ -4407,7 +4407,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor /*! @brief Sets the cursor enter/exit callback. * * This function sets the cursor boundary crossing callback of the specified - * window, which is called when the cursor enters or leaves the client area of + * window, which is called when the cursor enters or leaves the content area of * the window. * * @param[in] window The window whose callback to set. diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 6382968c8..28c7ef591 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -67,9 +67,9 @@ static NSUInteger getStyleMask(_GLFWwindow* window) return styleMask; } -// Returns whether the cursor is in the client area of the specified window +// Returns whether the cursor is in the content area of the specified window // -static GLFWbool cursorInClientArea(_GLFWwindow* window) +static GLFWbool cursorInContentArea(_GLFWwindow* window) { const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; return [window->ns.view mouse:pos inRect:[window->ns.view frame]]; @@ -124,7 +124,7 @@ static void updateCursorMode(_GLFWwindow* window) _glfwPlatformGetCursorPos(window, &_glfw.ns.restoreCursorPosX, &_glfw.ns.restoreCursorPosY); - _glfwCenterCursor(window); + _glfwCenterCursorInContentArea(window); CGAssociateMouseAndMouseCursorPosition(false); } else if (_glfw.ns.disabledCursorWindow == window) @@ -136,7 +136,7 @@ static void updateCursorMode(_GLFWwindow* window) _glfw.ns.restoreCursorPosY); } - if (cursorInClientArea(window)) + if (cursorInContentArea(window)) updateCursorImage(window); } @@ -271,7 +271,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; [window->context.nsgl.object update]; if (_glfw.ns.disabledCursorWindow == window) - _glfwCenterCursor(window); + _glfwCenterCursorInContentArea(window); const int maximized = [window->ns.object isZoomed]; if (window->ns.maximized != maximized) @@ -306,7 +306,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; [window->context.nsgl.object update]; if (_glfw.ns.disabledCursorWindow == window) - _glfwCenterCursor(window); + _glfwCenterCursorInContentArea(window); int x, y; _glfwPlatformGetWindowPos(window, &x, &y); @@ -332,7 +332,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)windowDidBecomeKey:(NSNotification *)notification { if (_glfw.ns.disabledCursorWindow == window) - _glfwCenterCursor(window); + _glfwCenterCursorInContentArea(window); _glfwInputWindowFocus(window, GLFW_TRUE); updateCursorMode(window); @@ -1513,7 +1513,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) { - if (cursorInClientArea(window)) + if (cursorInContentArea(window)) updateCursorImage(window); } diff --git a/src/input.c b/src/input.c index c3da79dd8..33ed06045 100644 --- a/src/input.c +++ b/src/input.c @@ -333,7 +333,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) } // Notifies shared code of a cursor motion event -// The position is specified in client-area relative screen coordinates +// The position is specified in content area relative screen coordinates // void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos) { @@ -453,9 +453,9 @@ void _glfwFreeJoystick(_GLFWjoystick* js) memset(js, 0, sizeof(_GLFWjoystick)); } -// Center the cursor in the middle of the window +// Center the cursor in the content area of the specified window // -void _glfwCenterCursor(_GLFWwindow* window) +void _glfwCenterCursorInContentArea(_GLFWwindow* window) { int width, height; diff --git a/src/internal.h b/src/internal.h index aa8376851..e8df80a07 100644 --- a/src/internal.h +++ b/src/internal.h @@ -760,7 +760,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, int buttonCount, int hatCount); void _glfwFreeJoystick(_GLFWjoystick* js); -void _glfwCenterCursor(_GLFWwindow* window); +void _glfwCenterCursorInContentArea(_GLFWwindow* window); GLFWbool _glfwInitVulkan(int mode); void _glfwTerminateVulkan(void); diff --git a/src/win32_window.c b/src/win32_window.c index 0953292e6..afcdc9ee2 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -186,14 +186,14 @@ static HICON createIcon(const GLFWimage* image, return handle; } -// Translate client window size to full window size according to styles and DPI +// Translate content area size to full window size according to styles and DPI // static void getFullWindowSize(DWORD style, DWORD exStyle, - int clientWidth, int clientHeight, + int contentWidth, int contentHeight, int* fullWidth, int* fullHeight, UINT dpi) { - RECT rect = { 0, 0, clientWidth, clientHeight }; + RECT rect = { 0, 0, contentWidth, contentHeight }; if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi); @@ -204,7 +204,7 @@ static void getFullWindowSize(DWORD style, DWORD exStyle, *fullHeight = rect.bottom - rect.top; } -// Enforce the client rect aspect ratio based on which edge is being dragged +// Enforce the content area aspect ratio based on which edge is being dragged // static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) { @@ -278,7 +278,7 @@ static void disableCursor(_GLFWwindow* window) &_glfw.win32.restoreCursorPosX, &_glfw.win32.restoreCursorPosY); updateCursorImage(window); - _glfwCenterCursor(window); + _glfwCenterCursorInContentArea(window); updateClipRect(window); if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) @@ -308,9 +308,9 @@ static void enableCursor(_GLFWwindow* window) } } -// Returns whether the cursor is in the client area of the specified window +// Returns whether the cursor is in the content area of the specified window // -static GLFWbool cursorInClientArea(_GLFWwindow* window) +static GLFWbool cursorInContentArea(_GLFWwindow* window) { RECT area; POINT pos; @@ -1074,7 +1074,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (window->win32.scaleToMonitor) break; - // Adjust the window size to keep the client area size constant + // Adjust the window size to keep the content area size constant if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32()) { RECT source = {0}, target = {0}; @@ -1244,7 +1244,7 @@ static int createNativeWindow(_GLFWwindow* window, window->win32.scaleToMonitor = wndconfig->scaleToMonitor; // Adjust window size to account for DPI scaling of the window frame and - // optionally DPI scaling of the client area + // optionally DPI scaling of the content area // This cannot be done until we know what monitor it was placed on if (!window->monitor) { @@ -1779,7 +1779,7 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window) int _glfwPlatformWindowHovered(_GLFWwindow* window) { - return cursorInClientArea(window); + return cursorInContentArea(window); } int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) @@ -1972,7 +1972,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) } else if (_glfw.win32.disabledCursorWindow == window) enableCursor(window); - else if (cursorInClientArea(window)) + else if (cursorInContentArea(window)) updateCursorImage(window); } @@ -2035,7 +2035,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) { - if (cursorInClientArea(window)) + if (cursorInContentArea(window)) updateCursorImage(window); } diff --git a/src/window.c b/src/window.c index 6367f2ba3..24e60054d 100644 --- a/src/window.c +++ b/src/window.c @@ -67,7 +67,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused) } // Notifies shared code that a window has moved -// The position is specified in client-area relative screen coordinates +// The position is specified in content area relative screen coordinates // void _glfwInputWindowPos(_GLFWwindow* window, int x, int y) { @@ -229,7 +229,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, if (window->monitor) { if (wndconfig.centerCursor) - _glfwCenterCursor(window); + _glfwCenterCursorInContentArea(window); } else { diff --git a/src/x11_window.c b/src/x11_window.c index 252d9140a..4a23a1e37 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -544,7 +544,7 @@ static void disableCursor(_GLFWwindow* window) &_glfw.x11.restoreCursorPosX, &_glfw.x11.restoreCursorPosY); updateCursorImage(window); - _glfwCenterCursor(window); + _glfwCenterCursorInContentArea(window); XGrabPointer(_glfw.x11.display, window->x11.handle, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, From b41cd341436258861e13d4f64bdfc1b9349df28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 23 Jan 2019 23:43:15 +0100 Subject: [PATCH 37/43] Cleanup --- src/wgl_context.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index 51916e576..0ffe2cfce 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -67,7 +67,7 @@ static int choosePixelFormat(_GLFWwindow* window, { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, pixelFormat, nativeCount, usableCount, attribCount; + int i, pixelFormat, nativeCount, usableCount = 0, attribCount = 0; int attribs[40]; int values[sizeof(attribs) / sizeof(attribs[0])]; @@ -83,8 +83,6 @@ static int choosePixelFormat(_GLFWwindow* window, return 0; } - attribCount = 0; - addAttrib(WGL_SUPPORT_OPENGL_ARB); addAttrib(WGL_DRAW_TO_WINDOW_ARB); addAttrib(WGL_PIXEL_TYPE_ARB); @@ -131,7 +129,6 @@ static int choosePixelFormat(_GLFWwindow* window, } usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); - usableCount = 0; for (i = 0; i < nativeCount; i++) { From 7f4dde15e453093c7a12efa0b5d79514a58b5243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 25 Jan 2019 12:14:23 +0100 Subject: [PATCH 38/43] Allow zero windows for events test glfwWaitEvents is sane now, yay. --- tests/events.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/events.c b/tests/events.c index 5c89beb5a..5a0fde04a 100644 --- a/tests/events.c +++ b/tests/events.c @@ -524,7 +524,7 @@ int main(int argc, char** argv) break; case 'n': - count = (int) strtol(optarg, NULL, 10); + count = (int) strtoul(optarg, NULL, 10); break; default: @@ -551,12 +551,6 @@ int main(int argc, char** argv) height = 480; } - if (!count) - { - fprintf(stderr, "Invalid user\n"); - exit(EXIT_FAILURE); - } - slots = calloc(count, sizeof(Slot)); for (i = 0; i < count; i++) From 78e6a0063d27ed44c2c4805606309744f6fb29fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 31 Jan 2019 00:02:16 +0100 Subject: [PATCH 39/43] X11: Fix EWMH state update for hidden windows The EWMH window state code assumed the window was mapped. Fixes #1358. --- README.md | 2 ++ src/x11_window.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d50e5ddb4..763550f94 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,8 @@ information on what to include when reporting a bug. - [X11] Bugfix: `glfwSetWindowMonitor` did not update hints when resizing non-user-resizable windows - [X11] Bugfix: `glfwSetWindowMonitor` did not flush output buffer in some cases +- [X11] Bugfix: `glfwSetWindowMonitor` did not update the EWMH state of hidden + windows (#1358) - [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel headers (#1196) - [Linux] Moved to evdev for joystick input (#906,#1005) diff --git a/src/x11_window.c b/src/x11_window.c index 4a23a1e37..a83340332 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2410,16 +2410,21 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _glfwInputWindowMonitor(window, monitor); updateNormalHints(window, width, height); - updateWindowMode(window); if (window->monitor) { - XMapRaised(_glfw.x11.display, window->x11.handle); - if (waitForVisibilityNotify(window)) - acquireMonitor(window); + if (!_glfwPlatformWindowVisible(window)) + { + XMapRaised(_glfw.x11.display, window->x11.handle); + waitForVisibilityNotify(window); + } + + updateWindowMode(window); + acquireMonitor(window); } else { + updateWindowMode(window); XMoveResizeWindow(_glfw.x11.display, window->x11.handle, xpos, ypos, width, height); } From 530b37f4db964466f327cb567499da234e3bce1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 18 Jan 2019 00:41:47 +0100 Subject: [PATCH 40/43] Cocoa: Disable automatic tabbing for GLFW windows Related to #1250. --- README.md | 1 + src/cocoa_window.m | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 763550f94..2d818ac38 100644 --- a/README.md +++ b/README.md @@ -262,6 +262,7 @@ information on what to include when reporting a bug. - [Cocoa] Added support for Vulkan window surface creation via [MoltenVK](https://moltengl.com/moltenvk/) (#870) - [Cocoa] Added support for loading a `MainMenu.nib` when available +- [Cocoa] Disabled automatic window tabbing for created windows (#1250) - [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852) - [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883) - [Cocoa] Bugfix: Removed use of deprecated `CGDisplayIOServicePort` function diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 28c7ef591..156b97b16 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -885,6 +885,9 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, [window->ns.object setDelegate:window->ns.delegate]; [window->ns.object setAcceptsMouseMovedEvents:YES]; [window->ns.object setRestorable:NO]; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 + [window->ns.object setTabbingMode:NSWindowTabbingModeDisallowed]; +#endif _glfwPlatformGetWindowSize(window, &window->ns.width, &window->ns.height); _glfwPlatformGetFramebufferSize(window, &window->ns.fbWidth, &window->ns.fbHeight); From 51ca41dd9fdf98bc9d38810f84ad4cb218ecd88a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 31 Jan 2019 00:44:10 +0100 Subject: [PATCH 41/43] Cocoa: Add missing IOHID page and usages Related to #1385. --- README.md | 1 + src/cocoa_joystick.m | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2d818ac38..b361ae3fe 100644 --- a/README.md +++ b/README.md @@ -288,6 +288,7 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: OpenGL rendering was not initially visible on 10.14 (#1334,#1346) - [Cocoa] Bugfix: Caps Lock did not generate any key events (#1368,#1373) +- [Cocoa] Bugfix: Some buttons for some joysticks were ignored (#1385) - [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts - [WGL] Added support for `WGL_ARB_create_context_no_error` - [GLX] Added support for `GLX_ARB_create_context_no_error` diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 0831809f8..2d1522e6b 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -220,9 +220,18 @@ static void matchCallback(void* context, case kHIDUsage_GD_Hatswitch: target = hats; break; + case kHIDUsage_GD_DPadUp: + case kHIDUsage_GD_DPadRight: + case kHIDUsage_GD_DPadDown: + case kHIDUsage_GD_DPadLeft: + case kHIDUsage_GD_SystemMainMenu: + case kHIDUsage_GD_Select: + case kHIDUsage_GD_Start: + target = buttons; + break; } } - else if (page == kHIDPage_Button) + else if (page == kHIDPage_Button || page == kHIDPage_Consumer) target = buttons; if (target) From 463ef7eb71268f57790fdb67f26d328b45d3346e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 31 Jan 2019 01:54:06 +0100 Subject: [PATCH 42/43] Cocoa: Fix handling of analog joystick buttons The reported state was not clamped to [0,1], i.e. GLFW_RELEASE and GLFW_PRESS. Fixes #1385. --- README.md | 1 + src/cocoa_joystick.m | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b361ae3fe..5ea88f985 100644 --- a/README.md +++ b/README.md @@ -289,6 +289,7 @@ information on what to include when reporting a bug. (#1334,#1346) - [Cocoa] Bugfix: Caps Lock did not generate any key events (#1368,#1373) - [Cocoa] Bugfix: Some buttons for some joysticks were ignored (#1385) +- [Cocoa] Bugfix: Analog joystick buttons were not translated correctly (#1385) - [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts - [WGL] Added support for `WGL_ARB_create_context_no_error` - [GLX] Added support for `GLX_ARB_create_context_no_error` diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 2d1522e6b..2ce977d0a 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -426,7 +426,8 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) _GLFWjoyelementNS* button = (_GLFWjoyelementNS*) CFArrayGetValueAtIndex(js->ns.buttons, i); const char value = getElementValue(js, button) - button->minimum; - _glfwInputJoystickButton(js, (int) i, value); + const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE; + _glfwInputJoystickButton(js, (int) i, state); } for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) From 90e22947c60b0c1fa47cf1496790ce1942e4a5d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 31 Jan 2019 01:58:04 +0100 Subject: [PATCH 43/43] Cleanup --- src/cocoa_joystick.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 2ce977d0a..1c2818f01 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -406,12 +406,12 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) if (raw > axis->maximum) axis->maximum = raw; - const long delta = axis->maximum - axis->minimum; - if (delta == 0) + const long size = axis->maximum - axis->minimum; + if (size == 0) _glfwInputJoystickAxis(js, (int) i, 0.f); else { - const float value = (2.f * (raw - axis->minimum) / delta) - 1.f; + const float value = (2.f * (raw - axis->minimum) / size) - 1.f; _glfwInputJoystickAxis(js, (int) i, value); } }