Move all cursor positioning to platform code

Due to Wayland, shared code cannot rely on cursor positioning being
supported by the underlying platform.

This implicitly fixes #617 as it moves cursor centering into
_glfwPlatformSetCursorMode, thus separating it from the stale value of
_glfw.cursorWindow.

Fixes #617.
This commit is contained in:
Camilla Berglund 2016-05-25 14:06:02 +02:00
parent 0e846883bf
commit 797ee8d8e3
12 changed files with 205 additions and 182 deletions

View File

@ -99,6 +99,8 @@ typedef struct _GLFWlibraryNS
short int publicKeys[256]; short int publicKeys[256];
short int nativeKeys[GLFW_KEY_LAST + 1]; short int nativeKeys[GLFW_KEY_LAST + 1];
char* clipboardString; char* clipboardString;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
struct { struct {
CFBundleRef bundle; CFBundleRef bundle;

View File

@ -85,6 +85,21 @@ static void centerCursor(_GLFWwindow *window)
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
} }
// Updates the cursor image according to the specified cursor mode
//
static void updateCursorImage(_GLFWwindow* window, int mode)
{
if (mode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
[(NSCursor*) window->cursor->ns.object set];
else
[[NSCursor arrowCursor] set];
}
else
[(NSCursor*) _glfw.ns.cursor set];
}
// Transforms the specified y-coordinate between the CG display and NS screen // Transforms the specified y-coordinate between the CG display and NS screen
// coordinate systems // coordinate systems
// //
@ -394,7 +409,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)cursorUpdate:(NSEvent *)event - (void)cursorUpdate:(NSEvent *)event
{ {
_glfwPlatformSetCursorMode(window, window->cursorMode); updateCursorImage(window, window->cursorMode);
} }
- (void)mouseDown:(NSEvent *)event - (void)mouseDown:(NSEvent *)event
@ -422,16 +437,19 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
{ {
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
_glfwInputCursorMotion(window, const double dx = [event deltaX] - window->ns.cursorWarpDeltaX;
[event deltaX] - window->ns.cursorWarpDeltaX, const double dy = [event deltaY] - window->ns.cursorWarpDeltaY;
[event deltaY] - window->ns.cursorWarpDeltaY);
_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
} }
else else
{ {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSPoint pos = [event locationInWindow]; const NSPoint pos = [event locationInWindow];
_glfwInputCursorMotion(window, pos.x, contentRect.size.height - pos.y); _glfwInputCursorPos(window, pos.x, contentRect.size.height - pos.y);
} }
window->ns.cursorWarpDeltaX = 0; window->ns.cursorWarpDeltaX = 0;
@ -607,9 +625,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType]; NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
_glfwInputCursorMotion(window, _glfwInputCursorPos(window,
[sender draggingLocation].x, [sender draggingLocation].x,
contentRect.size.height - [sender draggingLocation].y); contentRect.size.height - [sender draggingLocation].y);
const int count = [files count]; const int count = [files count];
if (count) if (count)
@ -1033,6 +1051,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
_glfwPlatformFocusWindow(window); _glfwPlatformFocusWindow(window);
if (!acquireMonitor(window)) if (!acquireMonitor(window))
return GLFW_FALSE; return GLFW_FALSE;
centerCursor(window);
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -1397,7 +1417,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{ {
_glfwPlatformSetCursorMode(window, window->cursorMode); updateCursorImage(window, window->cursorMode);
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
@ -1423,20 +1443,23 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{ {
if (mode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
[(NSCursor*) window->cursor->ns.object set];
else
[[NSCursor arrowCursor] set];
}
else
[(NSCursor*) _glfw.ns.cursor set];
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
{
_glfwPlatformGetCursorPos(window,
&_glfw.ns.restoreCursorPosX,
&_glfw.ns.restoreCursorPosY);
centerCursor(window);
CGAssociateMouseAndMouseCursorPosition(false); CGAssociateMouseAndMouseCursorPosition(false);
else }
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
CGAssociateMouseAndMouseCursorPosition(true); CGAssociateMouseAndMouseCursorPosition(true);
_glfwPlatformSetCursorPos(window,
_glfw.ns.restoreCursorPosX,
_glfw.ns.restoreCursorPosY);
}
updateCursorImage(window, mode);
} }
const char* _glfwPlatformGetKeyName(int key, int scancode) const char* _glfwPlatformGetKeyName(int key, int scancode)

View File

@ -37,48 +37,27 @@
// Sets the cursor mode for the specified window // Sets the cursor mode for the specified window
// //
static void setCursorMode(_GLFWwindow* window, int newMode) static void setCursorMode(_GLFWwindow* window, int mode)
{ {
const int oldMode = window->cursorMode; if (mode != GLFW_CURSOR_NORMAL &&
mode != GLFW_CURSOR_HIDDEN &&
if (newMode != GLFW_CURSOR_NORMAL && mode != GLFW_CURSOR_DISABLED)
newMode != GLFW_CURSOR_HIDDEN &&
newMode != GLFW_CURSOR_DISABLED)
{ {
_glfwInputError(GLFW_INVALID_ENUM, "Invalid cursor mode %i", newMode); _glfwInputError(GLFW_INVALID_ENUM, "Invalid cursor mode %i", mode);
return; return;
} }
if (oldMode == newMode) if (window->cursorMode == mode)
return; return;
window->cursorMode = newMode; _glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
if (_glfw.cursorWindow == window) if (_glfw.cursorWindow == window)
{ _glfwPlatformSetCursorMode(window, mode);
if (oldMode == GLFW_CURSOR_DISABLED)
{
_glfwPlatformSetCursorPos(window,
_glfw.restoreCursorPosX,
_glfw.restoreCursorPosY);
}
else if (newMode == GLFW_CURSOR_DISABLED)
{
int width, height;
_glfwPlatformGetCursorPos(window, window->cursorMode = mode;
&_glfw.restoreCursorPosX,
&_glfw.restoreCursorPosY);
window->virtualCursorPosX = _glfw.restoreCursorPosX;
window->virtualCursorPosY = _glfw.restoreCursorPosY;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
}
_glfwPlatformSetCursorMode(window, window->cursorMode);
}
} }
// Set sticky keys mode for the specified window // Set sticky keys mode for the specified window
@ -191,19 +170,13 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods); window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
} }
void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y) void _glfwInputCursorPos(_GLFWwindow* window, double x, double y)
{ {
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->virtualCursorPosX == x && window->virtualCursorPosY == y)
{ return;
if (x == 0.0 && y == 0.0)
return;
window->virtualCursorPosX += x; window->virtualCursorPosX = x;
window->virtualCursorPosY += y; window->virtualCursorPosY = y;
x = window->virtualCursorPosX;
y = window->virtualCursorPosY;
}
if (window->callbacks.cursorPos) if (window->callbacks.cursorPos)
window->callbacks.cursorPos((GLFWwindow*) window, x, y); window->callbacks.cursorPos((GLFWwindow*) window, x, y);
@ -490,9 +463,9 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformSetCursor(window, cursor);
window->cursor = cursor; window->cursor = cursor;
_glfwPlatformSetCursor(window, cursor);
} }
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)

View File

@ -437,9 +437,6 @@ struct _GLFWlibrary
int refreshRate; int refreshRate;
} hints; } hints;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
_GLFWcursor* cursorListHead; _GLFWcursor* cursorListHead;
_GLFWwindow* windowListHead; _GLFWwindow* windowListHead;
@ -906,7 +903,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
* of the client area of the window. * of the client area of the window.
* @ingroup event * @ingroup event
*/ */
void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y); void _glfwInputCursorPos(_GLFWwindow* window, double x, double y);
/*! @brief Notifies shared code of a cursor enter/leave event. /*! @brief Notifies shared code of a cursor enter/leave event.
* @param[in] window The window that received the event. * @param[in] window The window that received the event.

View File

@ -208,8 +208,7 @@ static void handlePointerMotion(_GLFWwindow* window,
int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll); int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);
int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll); int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll);
if (current_x != x || current_y != y) _glfwInputCursorPos(window, x, y);
_glfwInputCursorMotion(window, x, y);
if (dx != 0 || dy != 0) if (dx != 0 || dy != 0)
_glfwInputScroll(window, dx, dy); _glfwInputScroll(window, dx, dy);
} }

View File

@ -252,6 +252,8 @@ typedef struct _GLFWlibraryWin32
char keyName[64]; char keyName[64];
short int publicKeys[512]; short int publicKeys[512];
short int nativeKeys[GLFW_KEY_LAST + 1]; short int nativeKeys[GLFW_KEY_LAST + 1];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
struct { struct {
HINSTANCE instance; HINSTANCE instance;

View File

@ -218,15 +218,69 @@ 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);
}
//
//
static GLFWbool cursorInClientArea(_GLFWwindow* window)
{
RECT area;
POINT pos;
if (!GetCursorPos(&pos))
return GLFW_FALSE;
if (WindowFromPoint(pos) != window->win32.handle)
return GLFW_FALSE;
GetClientRect(window->win32.handle, &area);
ClientToScreen(window->win32.handle, (POINT*) &area.left);
ClientToScreen(window->win32.handle, (POINT*) &area.right);
return PtInRect(&area, pos);
}
// Updates the cursor image according to the specified cursor mode
//
static void updateCursorImage(_GLFWwindow* window, int mode)
{
if (mode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
SetCursor(window->cursor->win32.handle);
else
SetCursor(LoadCursorW(NULL, IDC_ARROW));
}
else
{
if (mode == GLFW_CURSOR_DISABLED && _glfw.cursorWindow != window)
SetCursor(LoadCursorW(NULL, IDC_ARROW));
else
SetCursor(NULL);
}
}
// Updates the cursor clip rect // Updates the cursor clip rect
// //
static void updateClipRect(_GLFWwindow* window) static void updateClipRect(_GLFWwindow* window)
{ {
RECT clipRect; if (window)
GetClientRect(window->win32.handle, &clipRect); {
ClientToScreen(window->win32.handle, (POINT*) &clipRect.left); RECT clipRect;
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); GetClientRect(window->win32.handle, &clipRect);
ClipCursor(&clipRect); ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
ClipCursor(&clipRect);
}
else
ClipCursor(NULL);
} }
// Translates a GLFW standard cursor to a resource ID // Translates a GLFW standard cursor to a resource ID
@ -420,10 +474,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{ {
case WM_SETFOCUS: case WM_SETFOCUS:
{ {
_glfwInputWindowFocus(window, GLFW_TRUE);
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
_glfwInputWindowFocus(window, GLFW_TRUE);
return 0; return 0;
} }
@ -571,12 +626,15 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (_glfw.cursorWindow != window) if (_glfw.cursorWindow != window)
break; break;
_glfwInputCursorMotion(window, const int dx = x - window->win32.lastCursorPosX;
x - window->win32.lastCursorPosX, const int dy = y - window->win32.lastCursorPosY;
y - window->win32.lastCursorPosY);
_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
} }
else else
_glfwInputCursorMotion(window, x, y); _glfwInputCursorPos(window, x, y);
window->win32.lastCursorPosX = x; window->win32.lastCursorPosX = x;
window->win32.lastCursorPosY = y; window->win32.lastCursorPosY = y;
@ -725,19 +783,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_SETCURSOR: case WM_SETCURSOR:
{ {
if (_glfw.cursorWindow == window && LOWORD(lParam) == HTCLIENT) if (LOWORD(lParam) == HTCLIENT)
{ {
if (window->cursorMode == GLFW_CURSOR_HIDDEN || updateCursorImage(window, window->cursorMode);
window->cursorMode == GLFW_CURSOR_DISABLED) return TRUE;
{
SetCursor(NULL);
return TRUE;
}
else if (window->cursor)
{
SetCursor(window->cursor->win32.handle);
return TRUE;
}
} }
break; break;
@ -767,7 +816,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// Move the mouse to the position of the drop // Move the mouse to the position of the drop
DragQueryPoint(drop, &pt); DragQueryPoint(drop, &pt);
_glfwInputCursorMotion(window, pt.x, pt.y); _glfwInputCursorPos(window, pt.x, pt.y);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
@ -1007,6 +1056,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
_glfwPlatformFocusWindow(window); _glfwPlatformFocusWindow(window);
if (!acquireMonitor(window)) if (!acquireMonitor(window))
return GLFW_FALSE; return GLFW_FALSE;
centerCursor(window);
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -1444,28 +1495,24 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{ {
POINT pos;
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
updateClipRect(window);
else
ClipCursor(NULL);
if (!GetCursorPos(&pos))
return;
if (WindowFromPoint(pos) != window->win32.handle)
return;
if (mode == GLFW_CURSOR_NORMAL)
{ {
if (window->cursor) _glfwPlatformGetCursorPos(window,
SetCursor(window->cursor->win32.handle); &_glfw.win32.restoreCursorPosX,
else &_glfw.win32.restoreCursorPosY);
SetCursor(LoadCursorW(NULL, IDC_ARROW)); centerCursor(window);
updateClipRect(window);
} }
else else if (window->cursorMode == GLFW_CURSOR_DISABLED)
SetCursor(NULL); {
updateClipRect(NULL);
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY);
}
if (cursorInClientArea(window))
updateCursorImage(window, mode);
} }
const char* _glfwPlatformGetKeyName(int key, int scancode) const char* _glfwPlatformGetKeyName(int key, int scancode)
@ -1525,32 +1572,8 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
RECT area; if (cursorInClientArea(window))
POINT pos; updateCursorImage(window, window->cursorMode);
if (_glfw.cursorWindow != window)
return;
if (window->cursorMode != GLFW_CURSOR_NORMAL)
return;
if (!GetCursorPos(&pos))
return;
if (WindowFromPoint(pos) != window->win32.handle)
return;
GetClientRect(window->win32.handle, &area);
ClientToScreen(window->win32.handle, (POINT*) &area.left);
ClientToScreen(window->win32.handle, (POINT*) &area.right);
if (!PtInRect(&area, pos))
return;
if (cursor)
SetCursor(cursor->win32.handle);
else
SetCursor(LoadCursorW(NULL, IDC_ARROW));
} }
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)

View File

@ -219,19 +219,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
glfwMakeContextCurrent((GLFWwindow*) previous); glfwMakeContextCurrent((GLFWwindow*) previous);
} }
if (window->monitor) if (!window->monitor)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
window->virtualCursorPosX = width / 2;
window->virtualCursorPosY = height / 2;
_glfwPlatformSetCursorPos(window,
window->virtualCursorPosX,
window->virtualCursorPosY);
}
else
{ {
if (wndconfig.visible) if (wndconfig.visible)
{ {

View File

@ -91,9 +91,9 @@ static void pointerHandleMotion(void* data,
window->wl.cursorPosY = wl_fixed_to_double(sy); window->wl.cursorPosY = wl_fixed_to_double(sy);
} }
_glfwInputCursorMotion(window, _glfwInputCursorPos(window,
wl_fixed_to_double(sx), wl_fixed_to_double(sx),
wl_fixed_to_double(sy)); wl_fixed_to_double(sy));
} }
static void pointerHandleButton(void* data, static void pointerHandleButton(void* data,

View File

@ -784,9 +784,9 @@ static void handleRelativeMotion(void* data,
if (window->cursorMode != GLFW_CURSOR_DISABLED) if (window->cursorMode != GLFW_CURSOR_DISABLED)
return; return;
_glfwInputCursorMotion(window, _glfwInputCursorPos(window,
wl_fixed_to_double(dxUnaccel), window->virtualCursorPosX + wl_fixed_to_double(dxUnaccel),
wl_fixed_to_double(dyUnaccel)); window->virtualCursorPosY + wl_fixed_to_double(dyUnaccel));
} }
static const struct zwp_relative_pointer_v1_listener relativePointerListener = { static const struct zwp_relative_pointer_v1_listener relativePointerListener = {

View File

@ -118,7 +118,7 @@ typedef struct _GLFWwindowX11
int xpos, ypos; int xpos, ypos;
// The last received cursor position, regardless of source // The last received cursor position, regardless of source
double lastCursorPosX, lastCursorPosY; int lastCursorPosX, lastCursorPosY;
// The last position the cursor was warped to by GLFW // The last position the cursor was warped to by GLFW
int warpCursorPosX, warpCursorPosY; int warpCursorPosX, warpCursorPosY;
@ -155,6 +155,8 @@ typedef struct _GLFWlibraryX11
short int publicKeys[256]; short int publicKeys[256];
// GLFW key to X11 keycode LUT // GLFW key to X11 keycode LUT
short int nativeKeys[GLFW_KEY_LAST + 1]; short int nativeKeys[GLFW_KEY_LAST + 1];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// Window manager atoms // Window manager atoms
Atom WM_PROTOCOLS; Atom WM_PROTOCOLS;

View File

@ -387,6 +387,15 @@ static char** parseUriList(char* text, int* count)
return paths; return paths;
} }
// 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);
}
// Create the X11 window (and its colormap) // Create the X11 window (and its colormap)
// //
static GLFWbool createWindow(_GLFWwindow* window, static GLFWbool createWindow(_GLFWwindow* window,
@ -1158,12 +1167,15 @@ static void processEvent(XEvent *event)
if (_glfw.cursorWindow != window) if (_glfw.cursorWindow != window)
return; return;
_glfwInputCursorMotion(window, const int dx = x - window->x11.lastCursorPosX;
x - window->x11.lastCursorPosX, const int dy = y - window->x11.lastCursorPosY;
y - window->x11.lastCursorPosY);
_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
} }
else else
_glfwInputCursorMotion(window, x, y); _glfwInputCursorPos(window, x, y);
} }
window->x11.lastCursorPosX = x; window->x11.lastCursorPosX = x;
@ -1265,7 +1277,7 @@ static void processEvent(XEvent *event)
int x, y; int x, y;
_glfwPlatformGetWindowPos(window, &x, &y); _glfwPlatformGetWindowPos(window, &x, &y);
_glfwInputCursorMotion(window, absX - x, absY - y); _glfwInputCursorPos(window, absX - x, absY - y);
// Reply that we are ready to copy the dragged data // Reply that we are ready to copy the dragged data
XEvent reply; XEvent reply;
@ -1517,6 +1529,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
updateWindowMode(window); updateWindowMode(window);
if (!acquireMonitor(window)) if (!acquireMonitor(window))
return GLFW_FALSE; return GLFW_FALSE;
centerCursor(window);
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -1999,11 +2013,7 @@ void _glfwPlatformPollEvents(void)
_GLFWwindow* window = _glfw.cursorWindow; _GLFWwindow* window = _glfw.cursorWindow;
if (window && window->cursorMode == GLFW_CURSOR_DISABLED) if (window && window->cursorMode == GLFW_CURSOR_DISABLED)
{ centerCursor(window);
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
}
} }
void _glfwPlatformWaitEvents(void) void _glfwPlatformWaitEvents(void)
@ -2082,31 +2092,35 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{ {
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
{ {
_glfwPlatformGetCursorPos(window,
&_glfw.x11.restoreCursorPosX,
&_glfw.x11.restoreCursorPosY);
centerCursor(window);
XGrabPointer(_glfw.x11.display, window->x11.handle, True, XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
window->x11.handle, _glfw.x11.cursor, CurrentTime); window->x11.handle, _glfw.x11.cursor, CurrentTime);
} }
else else if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
XUngrabPointer(_glfw.x11.display, CurrentTime); XUngrabPointer(_glfw.x11.display, CurrentTime);
_glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY);
}
if (mode == GLFW_CURSOR_NORMAL) if (mode == GLFW_CURSOR_NORMAL)
{ {
if (window->cursor) if (window->cursor)
{
XDefineCursor(_glfw.x11.display, window->x11.handle,
window->cursor->x11.handle);
}
else
XUndefineCursor(_glfw.x11.display, window->x11.handle);
}
else
{ {
XDefineCursor(_glfw.x11.display, window->x11.handle, XDefineCursor(_glfw.x11.display, window->x11.handle,
_glfw.x11.cursor); window->cursor->x11.handle);
} }
else
XUndefineCursor(_glfw.x11.display, window->x11.handle);
} }
else
XDefineCursor(_glfw.x11.display, window->x11.handle, _glfw.x11.cursor);
} }
const char* _glfwPlatformGetKeyName(int key, int scancode) const char* _glfwPlatformGetKeyName(int key, int scancode)