diff --git a/README.md b/README.md index 169f5666..546d38c6 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,7 @@ GLFW. `GLES2/gl2.h` instead of `GL/gl.h` * Added `GLFW_VISIBLE` window hint and parameter for controlling and polling window visibility + * Added `GLFW_REPEAT` key action for repeated keys * Added `windows` simple multi-window test program * Added `sharing` simple OpenGL object sharing test program * Added `modes` video mode enumeration and setting test program diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index af10e366..052a2d18 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -242,6 +242,10 @@ extern "C" { * @ingroup input */ #define GLFW_PRESS 1 +/*! @brief The key was held down until it repeated. + * @ingroup input + */ +#define GLFW_REPEAT 2 /*! @} */ /* Keyboard raw key codes. @@ -676,7 +680,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); * @param[in] window The window that received the event. * @param[in] key The @link keys keyboard key @endlink that was pressed or * released. - * @param[in] action One of @c GLFW_PRESS or @c GLFW_RELEASE. + * @param[in] action @ref GLFW_PRESS, @ref GLFW_RELEASE or @ref GLFW_REPEAT. * @ingroup input * * @sa glfwSetKeyCallback diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 9e5ed0bd..929dc27d 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -438,24 +438,21 @@ static int convertMacKeyCode(unsigned int macKeyCode) { NSUInteger i, length; NSString* characters; - int key = convertMacKeyCode([event keyCode]); + const int key = convertMacKeyCode([event keyCode]); + if (key == -1) + return; - if (key != -1) + _glfwInputKey(window, key, GLFW_PRESS); + + if ([event modifierFlags] & NSCommandKeyMask) + [super keyDown:event]; + else { - _glfwInputKey(window, key, GLFW_PRESS); + characters = [event characters]; + length = [characters length]; - if ([event modifierFlags] & NSCommandKeyMask) - { - [super keyDown:event]; - } - else - { - characters = [event characters]; - length = [characters length]; - - for (i = 0; i < length; i++) - _glfwInputChar(window, [characters characterAtIndex:i]); - } + for (i = 0; i < length; i++) + _glfwInputChar(window, [characters characterAtIndex:i]); } } diff --git a/src/input.c b/src/input.c index 8082f3b2..75dca2d8 100644 --- a/src/input.c +++ b/src/input.c @@ -120,23 +120,18 @@ void _glfwInputKey(_GLFWwindow* window, int key, int action) if (key < 0 || key > GLFW_KEY_LAST) return; - // Are we trying to release an already released key? - if (action == GLFW_RELEASE && window->key[key] != GLFW_PRESS) - return; + if (action == GLFW_PRESS && window->key[key] == GLFW_PRESS) + repeated = GL_TRUE; - // Register key action if (action == GLFW_RELEASE && window->stickyKeys) window->key[key] = _GLFW_STICK; else - { - if (action == GLFW_PRESS && window->key[key] == GLFW_PRESS) - repeated = GL_TRUE; - window->key[key] = (char) action; - } - // Call user callback function - if (window->callbacks.key && !repeated) + if (repeated) + action = GLFW_REPEAT; + + if (window->callbacks.key) window->callbacks.key((GLFWwindow*) window, key, action); } diff --git a/src/internal.h b/src/internal.h index 88bf9c52..fed23dd1 100644 --- a/src/internal.h +++ b/src/internal.h @@ -107,7 +107,7 @@ typedef struct _GLFWmonitor _GLFWmonitor; //======================================================================== // Internal key state used for sticky keys -#define _GLFW_STICK 2 +#define _GLFW_STICK 3 //======================================================================== diff --git a/src/x11_init.c b/src/x11_init.c index 73bd7ff1..441f63e2 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -488,11 +488,17 @@ static GLboolean initDisplay(void) return GL_FALSE; } - XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported); + if (!XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to set detectable key repeat"); + return GL_FALSE; + } + if (!supported) { _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Detectable key repeat is not available"); + "X11: Detectable key repeat is not supported"); return GL_FALSE; } diff --git a/tests/events.c b/tests/events.c index 19716891..530ea54b 100644 --- a/tests/events.c +++ b/tests/events.c @@ -183,6 +183,8 @@ static const char* get_action_name(int action) return "pressed"; case GLFW_RELEASE: return "released"; + case GLFW_REPEAT: + return "repeated"; } return "caused unknown action";