Made glfwGetCursorPos query system directly.

Fixes #103.
Fixes #153.
Fixes #193.
Fixes #355.
Fixes #381.
This commit is contained in:
Camilla Berglund
2014-02-11 18:24:01 +01:00
parent 641761ddb0
commit d459145d28
11 changed files with 177 additions and 131 deletions
+5
View File
@@ -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;
+49 -18
View File
@@ -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];
+32 -36
View File
@@ -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 (xpos)
*xpos = window->cursorPosX;
if (ypos)
*ypos = window->cursorPosY;
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
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
_glfwPlatformSetCursorPos(window, xpos, ypos);
{
// Only update the accumulated position if the cursor is disabled
window->cursorPosX = xpos;
window->cursorPosY = ypos;
}
else
{
// Update system cursor position
_glfwPlatformSetCursorPos(window, xpos, ypos);
}
}
GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
+5
View File
@@ -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
*/
+3 -3
View File
@@ -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;
+42 -51
View File
@@ -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);
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
if (newCursorX != window->win32.oldCursorX ||
newCursorY != window->win32.oldCursorY)
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
int x, y;
if (_glfw.focusedWindow != window)
break;
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.focusedWindow != window)
return 0;
x = newCursorX - window->win32.oldCursorX;
y = newCursorY - window->win32.oldCursorY;
}
else
{
x = newCursorX;
y = newCursorY;
}
window->win32.oldCursorX = newCursorX;
window->win32.oldCursorY = newCursorY;
window->win32.cursorCentered = GL_FALSE;
_glfwInputCursorMotion(window, x, y);
_glfwInputCursorMotion(window,
x - window->win32.cursorPosX,
y - window->win32.cursorPosY);
}
else
_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)
+27 -14
View File
@@ -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);
_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