1
0
Fork 0
mirror of https://github.com/gwm17/glfw.git synced 2024-11-22 18:28:52 -05:00

Add GLFW_CURSOR_CAPTURED

This adds a cursor mode that provides a visible cursor confined to the
content area of the window.

Related to #58.
This commit is contained in:
Camilla Löwy 2019-12-03 17:58:20 +01:00
parent 3e5331dc86
commit 99b55dd21b
8 changed files with 53 additions and 5 deletions

View File

@ -123,6 +123,8 @@ information on what to include when reporting a bug.
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427) - Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
- Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427) - Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427)
- Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427) - Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427)
- Added `GLFW_CURSOR_CAPTURED` cursor mode to confine the cursor to the window
content area (#58)
- Disabled tests and examples by default when built as a CMake subdirectory - Disabled tests and examples by default when built as a CMake subdirectory
- Bugfix: The CMake config-file package used an absolute path and was not - Bugfix: The CMake config-file package used an absolute path and was not
relocatable (#1470) relocatable (#1470)

View File

@ -300,6 +300,16 @@ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
This mode puts no limit on the motion of the cursor. This mode puts no limit on the motion of the cursor.
If you wish the cursor to be visible but confined to the content area of the
window, set the cursor mode to `GLFW_CURSOR_CAPTURED`.
@code
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED);
@endcode
The cursor will behave normally inside the content area but will not be able to
leave unless the window loses focus.
To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL` To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL`
cursor mode. cursor mode.
@ -307,6 +317,8 @@ cursor mode.
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
@endcode @endcode
If the cursor was disabled, this will move it back to its last visible position.
@anchor GLFW_RAW_MOUSE_MOTION @anchor GLFW_RAW_MOUSE_MOTION
@subsection raw_mouse_motion Raw mouse motion @subsection raw_mouse_motion Raw mouse motion

View File

@ -27,6 +27,14 @@ are still available.
For more information see @ref cursor_standard. For more information see @ref cursor_standard.
@subsubsection captured_cursor_34 Captured cursor mode
GLFW now supports confining the cursor to the window content area with the @ref
GLFW_CURSOR_CAPTURED cursor mode.
For more information see @ref cursor_mode.
@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu @subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu
GLFW now provides the GLFW now provides the
@ -71,6 +79,7 @@ add_subdirectory(path/to/glfw)
- @ref GLFW_NOT_ALLOWED_CURSOR - @ref GLFW_NOT_ALLOWED_CURSOR
- @ref GLFW_CURSOR_UNAVAILABLE - @ref GLFW_CURSOR_UNAVAILABLE
- @ref GLFW_WIN32_KEYBOARD_MENU - @ref GLFW_WIN32_KEYBOARD_MENU
- @ref GLFW_CURSOR_CAPTURED
@section news_archive Release notes for earlier versions @section news_archive Release notes for earlier versions

View File

@ -1038,6 +1038,7 @@ extern "C" {
#define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_NORMAL 0x00034001
#define GLFW_CURSOR_HIDDEN 0x00034002 #define GLFW_CURSOR_HIDDEN 0x00034002
#define GLFW_CURSOR_DISABLED 0x00034003 #define GLFW_CURSOR_DISABLED 0x00034003
#define GLFW_CURSOR_CAPTURED 0x00034004
#define GLFW_ANY_RELEASE_BEHAVIOR 0 #define GLFW_ANY_RELEASE_BEHAVIOR 0
#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 #define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
@ -4139,6 +4140,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
* and unlimited cursor movement. This is useful for implementing for * and unlimited cursor movement. This is useful for implementing for
* example 3D camera controls. * example 3D camera controls.
* - `GLFW_CURSOR_CAPTURED` makes the cursor visible and confines it to the
* content area of the window.
* *
* If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
* enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are

View File

@ -506,7 +506,8 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
{ {
if (value != GLFW_CURSOR_NORMAL && if (value != GLFW_CURSOR_NORMAL &&
value != GLFW_CURSOR_HIDDEN && value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED) value != GLFW_CURSOR_DISABLED &&
value != GLFW_CURSOR_CAPTURED)
{ {
_glfwInputError(GLFW_INVALID_ENUM, _glfwInputError(GLFW_INVALID_ENUM,
"Invalid cursor mode 0x%08X", "Invalid cursor mode 0x%08X",

View File

@ -242,7 +242,8 @@ static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
// //
static void updateCursorImage(_GLFWwindow* window) static void updateCursorImage(_GLFWwindow* window)
{ {
if (window->cursorMode == GLFW_CURSOR_NORMAL) if (window->cursorMode == GLFW_CURSOR_NORMAL ||
window->cursorMode == GLFW_CURSOR_CAPTURED)
{ {
if (window->cursor) if (window->cursor)
SetCursor(window->cursor->win32.handle); SetCursor(window->cursor->win32.handle);
@ -650,6 +651,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{ {
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
disableCursor(window); disableCursor(window);
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
captureCursor(window);
window->win32.frameAction = GLFW_FALSE; window->win32.frameAction = GLFW_FALSE;
} }
@ -668,6 +671,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
disableCursor(window); disableCursor(window);
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
captureCursor(window);
return 0; return 0;
} }
@ -676,6 +681,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{ {
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
enableCursor(window); enableCursor(window);
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
releaseCursor();
if (window->monitor && window->autoIconify) if (window->monitor && window->autoIconify)
_glfwPlatformIconifyWindow(window); _glfwPlatformIconifyWindow(window);
@ -959,6 +966,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// resizing the window or using the window menu // resizing the window or using the window menu
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
enableCursor(window); enableCursor(window);
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
releaseCursor();
break; break;
} }
@ -973,6 +982,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// resizing the window or using the menu // resizing the window or using the menu
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
disableCursor(window); disableCursor(window);
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
captureCursor(window);
break; break;
} }
@ -2050,7 +2061,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
disableRawMouseMotion(window); disableRawMouseMotion(window);
} }
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED || mode == GLFW_CURSOR_CAPTURED)
captureCursor(window); captureCursor(window);
else else
releaseCursor(); releaseCursor();

View File

@ -1786,6 +1786,8 @@ static void processEvent(XEvent *event)
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
disableCursor(window); disableCursor(window);
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
captureCursor(window);
if (window->x11.ic) if (window->x11.ic)
XSetICFocus(window->x11.ic); XSetICFocus(window->x11.ic);
@ -1806,6 +1808,8 @@ static void processEvent(XEvent *event)
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
enableCursor(window); enableCursor(window);
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
releaseCursor();
if (window->x11.ic) if (window->x11.ic)
XUnsetICFocus(window->x11.ic); XUnsetICFocus(window->x11.ic);
@ -2800,7 +2804,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
disableRawMouseMotion(window); disableRawMouseMotion(window);
} }
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED || mode == GLFW_CURSOR_CAPTURED)
captureCursor(window); captureCursor(window);
else else
releaseCursor(); releaseCursor();

View File

@ -171,7 +171,8 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
case GLFW_KEY_ESCAPE: case GLFW_KEY_ESCAPE:
{ {
if (glfwGetInputMode(window, GLFW_CURSOR) != GLFW_CURSOR_DISABLED) const int mode = glfwGetInputMode(window, GLFW_CURSOR);
if (mode != GLFW_CURSOR_DISABLED && mode != GLFW_CURSOR_CAPTURED)
{ {
glfwSetWindowShouldClose(window, GLFW_TRUE); glfwSetWindowShouldClose(window, GLFW_TRUE);
break; break;
@ -196,6 +197,11 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
printf("(( cursor is hidden ))\n"); printf("(( cursor is hidden ))\n");
break; break;
case GLFW_KEY_C:
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED);
printf("(( cursor is captured ))\n");
break;
case GLFW_KEY_R: case GLFW_KEY_R:
if (!glfwRawMouseMotionSupported()) if (!glfwRawMouseMotionSupported())
break; break;