mirror of
https://github.com/glfw/glfw.git
synced 2024-11-25 19:42:00 +00:00
Made glfwGetCursorPos query system directly.
Fixes #103. Fixes #153. Fixes #193. Fixes #355. Fixes #381.
This commit is contained in:
parent
641761ddb0
commit
d459145d28
@ -92,6 +92,8 @@ GLFW bundles a number of dependencies in the `deps/` directory.
|
||||
the default behavior
|
||||
- Changed static library to build as position independent code for easier use
|
||||
from the Rust language
|
||||
- Changed `glfwGetCursorPos` to query the system directly for all cursor modes
|
||||
except captured mode
|
||||
- Bugfix: The debug context attribute was set from `GL_ARB_debug_output` even
|
||||
when a debug context had not been requested
|
||||
- Bugfix: The particles example was not linked against the threading library
|
||||
|
@ -228,10 +228,6 @@ double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
@endcode
|
||||
|
||||
This function only returns cached cursor positions. It does not poll the
|
||||
system for the current position. Whenever you poll state, you risk missing the
|
||||
state change you are looking for.
|
||||
|
||||
|
||||
@subsection input_cursor_mode Cursor modes
|
||||
|
||||
|
@ -81,6 +81,13 @@ The support for EGL is now stable, successfully running on PandaBoards, Mesa,
|
||||
ANGLE, Wayland, AMD EGL and others.
|
||||
|
||||
|
||||
@subsection news_31_getcursorpos Direct query for cursor position
|
||||
|
||||
GLFW now queries the system cursor position directly when you call @ref
|
||||
glfwGetCursorPos instead of returning cached data, except for when the window is
|
||||
in captured cursor mode.
|
||||
|
||||
|
||||
@section news_30 New features in version 3.0
|
||||
|
||||
@subsection news_30_cmake CMake build system
|
||||
|
@ -2573,12 +2573,12 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
|
||||
*/
|
||||
GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
|
||||
|
||||
/*! @brief Retrieves the last reported cursor position, relative to the client
|
||||
* area of the window.
|
||||
/*! @brief Retrieves the position of the cursor relative to the client area of
|
||||
* the window.
|
||||
*
|
||||
* This function returns the last reported position of the cursor, in screen
|
||||
* coordinates, relative to the upper-left corner of the client area of the
|
||||
* specified 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
|
||||
* window.
|
||||
*
|
||||
* If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
|
||||
* position is unbounded and limited only by the minimum and maximum values of
|
||||
|
@ -63,6 +63,11 @@ typedef struct _GLFWwindowNS
|
||||
id view;
|
||||
unsigned int modifierFlags;
|
||||
|
||||
// The total sum of the distances the cursor has been warped
|
||||
// since the last cursor motion event was processed
|
||||
// This is kept to counteract Cocoa doing the same internally
|
||||
double warpDeltaX, warpDeltaY;
|
||||
|
||||
} _GLFWwindowNS;
|
||||
|
||||
|
||||
|
@ -156,25 +156,31 @@ static NSRect convertRectToBacking(_GLFWwindow* window, NSRect contentRect)
|
||||
|
||||
- (void)windowDidResize:(NSNotification *)notification
|
||||
{
|
||||
if (_glfw.focusedWindow == window &&
|
||||
window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
const NSRect fbRect = convertRectToBacking(window, contentRect);
|
||||
|
||||
_glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);
|
||||
_glfwInputWindowSize(window, contentRect.size.width, contentRect.size.height);
|
||||
_glfwInputWindowDamage(window);
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
- (void)windowDidMove:(NSNotification *)notification
|
||||
{
|
||||
if (_glfw.focusedWindow == window &&
|
||||
window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
int x, y;
|
||||
_glfwPlatformGetWindowPos(window, &x, &y);
|
||||
_glfwInputWindowPos(window, x, y);
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
- (void)windowDidMiniaturize:(NSNotification *)notification
|
||||
@ -192,6 +198,12 @@ static NSRect convertRectToBacking(_GLFWwindow* window, NSRect contentRect)
|
||||
if (window->monitor)
|
||||
enterFullscreenMode(window);
|
||||
|
||||
if (_glfw.focusedWindow == window &&
|
||||
window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
_glfwInputWindowFocus(window, GL_TRUE);
|
||||
_glfwPlatformApplyCursorMode(window);
|
||||
}
|
||||
@ -366,14 +378,21 @@ static int translateKey(unsigned int key)
|
||||
- (void)mouseMoved:(NSEvent *)event
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwInputCursorMotion(window, [event deltaX], [event deltaY]);
|
||||
{
|
||||
_glfwInputCursorMotion(window,
|
||||
[event deltaX] - window->ns.warpDeltaX,
|
||||
[event deltaY] - window->ns.warpDeltaY);
|
||||
}
|
||||
else
|
||||
{
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
const NSPoint p = [event locationInWindow];
|
||||
const NSPoint pos = [event locationInWindow];
|
||||
|
||||
_glfwInputCursorMotion(window, p.x, contentRect.size.height - p.y);
|
||||
_glfwInputCursorMotion(window, pos.x, contentRect.size.height - pos.y);
|
||||
}
|
||||
|
||||
window->ns.warpDeltaX = 0;
|
||||
window->ns.warpDeltaY = 0;
|
||||
}
|
||||
|
||||
- (void)rightMouseDown:(NSEvent *)event
|
||||
@ -563,11 +582,10 @@ static int translateKey(unsigned int key)
|
||||
NSPasteboard* pasteboard = [sender draggingPasteboard];
|
||||
NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
|
||||
int height;
|
||||
_glfwPlatformGetWindowSize(window, NULL, &height);
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
_glfwInputCursorMotion(window,
|
||||
[sender draggingLocation].x,
|
||||
height - [sender draggingLocation].y);
|
||||
contentRect.size.height - [sender draggingLocation].y);
|
||||
|
||||
const int count = [files count];
|
||||
if (count)
|
||||
@ -1098,10 +1116,27 @@ void _glfwPlatformPostEmptyEvent(void)
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
{
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
|
||||
|
||||
if (xpos)
|
||||
*xpos = pos.x;
|
||||
if (ypos)
|
||||
*ypos = contentRect.size.height - pos.y - 1;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
{
|
||||
updateModeCursor(window);
|
||||
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
|
||||
|
||||
window->ns.warpDeltaX += x - pos.x;
|
||||
window->ns.warpDeltaY += y - contentRect.size.height + pos.y;
|
||||
|
||||
if (window->monitor)
|
||||
{
|
||||
CGDisplayMoveCursorToPoint(window->monitor->ns.displayID,
|
||||
@ -1109,7 +1144,6 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
}
|
||||
else
|
||||
{
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
const NSPoint localPoint = NSMakePoint(x, contentRect.size.height - y - 1);
|
||||
const NSPoint globalPoint = [window->ns.object convertBaseToScreen:localPoint];
|
||||
|
||||
@ -1123,10 +1157,7 @@ void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
|
||||
updateModeCursor(window);
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
centerCursor(window);
|
||||
}
|
||||
else
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
}
|
||||
@ -1192,10 +1223,10 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
|
||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||
{
|
||||
const NSPoint p = [window->ns.object mouseLocationOutsideOfEventStream];
|
||||
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_NORMAL &&
|
||||
[window->ns.view mouse:p inRect:[window->ns.view frame]])
|
||||
[window->ns.view mouse:pos inRect:[window->ns.view frame]])
|
||||
{
|
||||
if (cursor)
|
||||
[(NSCursor*) cursor->ns.object set];
|
||||
|
56
src/input.c
56
src/input.c
@ -59,20 +59,23 @@ static void setCursorMode(_GLFWwindow* window, int newMode)
|
||||
{
|
||||
if (oldMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
window->cursorPosX = _glfw.cursorPosX;
|
||||
window->cursorPosY = _glfw.cursorPosY;
|
||||
|
||||
_glfwPlatformSetCursorPos(window, _glfw.cursorPosX, _glfw.cursorPosY);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.cursorPosX,
|
||||
_glfw.cursorPosY);
|
||||
}
|
||||
else if (newMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
_glfw.cursorPosX = window->cursorPosX;
|
||||
_glfw.cursorPosY = window->cursorPosY;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.cursorPosX,
|
||||
&_glfw.cursorPosY);
|
||||
|
||||
window->cursorPosX = _glfw.cursorPosX;
|
||||
window->cursorPosY = _glfw.cursorPosY;
|
||||
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
|
||||
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
|
||||
}
|
||||
|
||||
_glfwPlatformApplyCursorMode(window);
|
||||
@ -198,22 +201,13 @@ void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y)
|
||||
|
||||
window->cursorPosX += x;
|
||||
window->cursorPosY += y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->cursorPosX == x && window->cursorPosY == y)
|
||||
return;
|
||||
|
||||
window->cursorPosX = x;
|
||||
window->cursorPosY = y;
|
||||
x = window->cursorPosX;
|
||||
y = window->cursorPosY;
|
||||
}
|
||||
|
||||
if (window->callbacks.cursorPos)
|
||||
{
|
||||
window->callbacks.cursorPos((GLFWwindow*) window,
|
||||
window->cursorPosX,
|
||||
window->cursorPosY);
|
||||
}
|
||||
window->callbacks.cursorPos((GLFWwindow*) window, x, y);
|
||||
}
|
||||
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, int entered)
|
||||
@ -332,10 +326,15 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
if (xpos)
|
||||
*xpos = window->cursorPosX;
|
||||
if (ypos)
|
||||
*ypos = window->cursorPosY;
|
||||
}
|
||||
else
|
||||
_glfwPlatformGetCursorPos(window, xpos, ypos);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
|
||||
@ -347,20 +346,17 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
|
||||
if (_glfw.focusedWindow != window)
|
||||
return;
|
||||
|
||||
// Don't do anything if the cursor position did not change
|
||||
if (xpos == window->cursorPosX && ypos == window->cursorPosY)
|
||||
return;
|
||||
|
||||
// Set GLFW cursor position
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
// Only update the accumulated position if the cursor is disabled
|
||||
window->cursorPosX = xpos;
|
||||
window->cursorPosY = ypos;
|
||||
|
||||
// Do not move physical cursor if it is disabled
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
// Update physical cursor position
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update system cursor position
|
||||
_glfwPlatformSetCursorPos(window, xpos, ypos);
|
||||
}
|
||||
}
|
||||
|
||||
GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
|
||||
|
@ -410,6 +410,11 @@ void _glfwPlatformTerminate(void);
|
||||
*/
|
||||
const char* _glfwPlatformGetVersionString(void);
|
||||
|
||||
/*! @copydoc glfwGetCursorPos
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
|
||||
|
||||
/*! @copydoc glfwSetCursorPos
|
||||
* @ingroup platform
|
||||
*/
|
||||
|
@ -158,10 +158,10 @@ typedef struct _GLFWwindowWin32
|
||||
DWORD dwStyle;
|
||||
DWORD dwExStyle;
|
||||
|
||||
GLboolean cursorCentered;
|
||||
GLboolean cursorInside;
|
||||
GLboolean cursorHidden;
|
||||
int oldCursorX, oldCursorY;
|
||||
|
||||
// The last received cursor position, regardless of source
|
||||
int cursorPosX, cursorPosY;
|
||||
|
||||
} _GLFWwindowWin32;
|
||||
|
||||
|
@ -55,15 +55,8 @@ static void hideCursor(_GLFWwindow* window)
|
||||
{
|
||||
POINT pos;
|
||||
|
||||
ReleaseCapture();
|
||||
ClipCursor(NULL);
|
||||
|
||||
if (window->win32.cursorHidden)
|
||||
{
|
||||
ShowCursor(TRUE);
|
||||
window->win32.cursorHidden = GL_FALSE;
|
||||
}
|
||||
|
||||
if (GetCursorPos(&pos))
|
||||
{
|
||||
if (WindowFromPoint(pos) == window->win32.handle)
|
||||
@ -75,14 +68,15 @@ static void hideCursor(_GLFWwindow* window)
|
||||
//
|
||||
static void disableCursor(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->win32.cursorHidden)
|
||||
{
|
||||
ShowCursor(FALSE);
|
||||
window->win32.cursorHidden = GL_TRUE;
|
||||
}
|
||||
POINT pos;
|
||||
|
||||
updateClipRect(window);
|
||||
SetCapture(window->win32.handle);
|
||||
|
||||
if (GetCursorPos(&pos))
|
||||
{
|
||||
if (WindowFromPoint(pos) == window->win32.handle)
|
||||
SetCursor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Restores the mouse cursor
|
||||
@ -91,15 +85,8 @@ static void restoreCursor(_GLFWwindow* window)
|
||||
{
|
||||
POINT pos;
|
||||
|
||||
ReleaseCapture();
|
||||
ClipCursor(NULL);
|
||||
|
||||
if (window->win32.cursorHidden)
|
||||
{
|
||||
ShowCursor(TRUE);
|
||||
window->win32.cursorHidden = GL_FALSE;
|
||||
}
|
||||
|
||||
if (GetCursorPos(&pos))
|
||||
{
|
||||
if (WindowFromPoint(pos) == window->win32.handle)
|
||||
@ -439,34 +426,23 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
const int newCursorX = GET_X_LPARAM(lParam);
|
||||
const int newCursorY = GET_Y_LPARAM(lParam);
|
||||
|
||||
if (newCursorX != window->win32.oldCursorX ||
|
||||
newCursorY != window->win32.oldCursorY)
|
||||
{
|
||||
int x, y;
|
||||
const int x = GET_X_LPARAM(lParam);
|
||||
const int y = GET_Y_LPARAM(lParam);
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
if (_glfw.focusedWindow != window)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
x = newCursorX - window->win32.oldCursorX;
|
||||
y = newCursorY - window->win32.oldCursorY;
|
||||
_glfwInputCursorMotion(window,
|
||||
x - window->win32.cursorPosX,
|
||||
y - window->win32.cursorPosY);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = newCursorX;
|
||||
y = newCursorY;
|
||||
}
|
||||
|
||||
window->win32.oldCursorX = newCursorX;
|
||||
window->win32.oldCursorY = newCursorY;
|
||||
window->win32.cursorCentered = GL_FALSE;
|
||||
|
||||
_glfwInputCursorMotion(window, x, y);
|
||||
}
|
||||
|
||||
window->win32.cursorPosX = x;
|
||||
window->win32.cursorPosY = y;
|
||||
|
||||
if (!window->win32.cursorInside)
|
||||
{
|
||||
@ -1058,13 +1034,11 @@ void _glfwPlatformPollEvents(void)
|
||||
}
|
||||
|
||||
// Did the cursor move in an focused window that has disabled the cursor
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED &&
|
||||
!window->win32.cursorCentered)
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
|
||||
window->win32.cursorCentered = GL_TRUE;
|
||||
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1082,14 +1056,31 @@ void _glfwPlatformPostEmptyEvent(void)
|
||||
PostMessage(window->win32.handle, WM_NULL, 0, 0);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
{
|
||||
POINT pos;
|
||||
|
||||
if (GetCursorPos(&pos))
|
||||
{
|
||||
ScreenToClient(window->win32.handle, &pos);
|
||||
|
||||
if (xpos)
|
||||
*xpos = pos.x;
|
||||
if (ypos)
|
||||
*ypos = pos.y;
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
POINT pos = { (int) xpos, (int) ypos };
|
||||
|
||||
// Store the new position so it can be recognized later
|
||||
window->win32.cursorPosX = pos.x;
|
||||
window->win32.cursorPosY = pos.y;
|
||||
|
||||
ClientToScreen(window->win32.handle, &pos);
|
||||
SetCursorPos(pos.x, pos.y);
|
||||
|
||||
window->win32.oldCursorX = (int) xpos;
|
||||
window->win32.oldCursorY = (int) ypos;
|
||||
}
|
||||
|
||||
void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
|
||||
|
@ -1066,32 +1066,28 @@ static void processEvent(XEvent *event)
|
||||
|
||||
case MotionNotify:
|
||||
{
|
||||
if (event->xmotion.x != window->x11.warpPosX ||
|
||||
event->xmotion.y != window->x11.warpPosY)
|
||||
const int x = event->xmotion.x;
|
||||
const int y = event->xmotion.y;
|
||||
|
||||
if (x != window->x11.warpPosX || y != window->x11.warpPosY)
|
||||
{
|
||||
// The cursor was moved by something other than GLFW
|
||||
|
||||
int x, y;
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
if (_glfw.focusedWindow != window)
|
||||
break;
|
||||
|
||||
x = event->xmotion.x - window->x11.cursorPosX;
|
||||
y = event->xmotion.y - window->x11.cursorPosY;
|
||||
_glfwInputCursorMotion(window,
|
||||
x - window->x11.cursorPosX,
|
||||
y - window->x11.cursorPosY);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = event->xmotion.x;
|
||||
y = event->xmotion.y;
|
||||
}
|
||||
|
||||
_glfwInputCursorMotion(window, x, y);
|
||||
}
|
||||
|
||||
window->x11.cursorPosX = event->xmotion.x;
|
||||
window->x11.cursorPosY = event->xmotion.y;
|
||||
window->x11.cursorPosX = x;
|
||||
window->x11.cursorPosY = y;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1744,6 +1740,23 @@ void _glfwPlatformPostEmptyEvent(void)
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
{
|
||||
Window root, child;
|
||||
int rootX, rootY, childX, childY;
|
||||
unsigned int mask;
|
||||
|
||||
XQueryPointer(_glfw.x11.display, window->x11.handle,
|
||||
&root, &child,
|
||||
&rootX, &rootY, &childX, &childY,
|
||||
&mask);
|
||||
|
||||
if (xpos)
|
||||
*xpos = childX;
|
||||
if (ypos)
|
||||
*ypos = childY;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
{
|
||||
// Store the new position so it can be recognized later
|
||||
|
Loading…
Reference in New Issue
Block a user