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:
parent
0e846883bf
commit
797ee8d8e3
@ -99,6 +99,8 @@ typedef struct _GLFWlibraryNS
|
||||
short int publicKeys[256];
|
||||
short int nativeKeys[GLFW_KEY_LAST + 1];
|
||||
char* clipboardString;
|
||||
// Where to place the cursor when re-enabled
|
||||
double restoreCursorPosX, restoreCursorPosY;
|
||||
|
||||
struct {
|
||||
CFBundleRef bundle;
|
||||
|
@ -85,6 +85,21 @@ static void centerCursor(_GLFWwindow *window)
|
||||
_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
|
||||
// coordinate systems
|
||||
//
|
||||
@ -394,7 +409,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
|
||||
- (void)cursorUpdate:(NSEvent *)event
|
||||
{
|
||||
_glfwPlatformSetCursorMode(window, window->cursorMode);
|
||||
updateCursorImage(window, window->cursorMode);
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
@ -422,16 +437,19 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
_glfwInputCursorMotion(window,
|
||||
[event deltaX] - window->ns.cursorWarpDeltaX,
|
||||
[event deltaY] - window->ns.cursorWarpDeltaY);
|
||||
const double dx = [event deltaX] - window->ns.cursorWarpDeltaX;
|
||||
const double dy = [event deltaY] - window->ns.cursorWarpDeltaY;
|
||||
|
||||
_glfwInputCursorPos(window,
|
||||
window->virtualCursorPosX + dx,
|
||||
window->virtualCursorPosY + dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
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;
|
||||
@ -607,9 +625,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
_glfwInputCursorMotion(window,
|
||||
[sender draggingLocation].x,
|
||||
contentRect.size.height - [sender draggingLocation].y);
|
||||
_glfwInputCursorPos(window,
|
||||
[sender draggingLocation].x,
|
||||
contentRect.size.height - [sender draggingLocation].y);
|
||||
|
||||
const int count = [files count];
|
||||
if (count)
|
||||
@ -1033,6 +1051,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
_glfwPlatformFocusWindow(window);
|
||||
if (!acquireMonitor(window))
|
||||
return GLFW_FALSE;
|
||||
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -1397,7 +1417,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
|
||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
{
|
||||
_glfwPlatformSetCursorMode(window, window->cursorMode);
|
||||
updateCursorImage(window, window->cursorMode);
|
||||
|
||||
const NSRect contentRect = [window->ns.view frame];
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.ns.restoreCursorPosX,
|
||||
&_glfw.ns.restoreCursorPosY);
|
||||
centerCursor(window);
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
else
|
||||
}
|
||||
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.ns.restoreCursorPosX,
|
||||
_glfw.ns.restoreCursorPosY);
|
||||
}
|
||||
|
||||
updateCursorImage(window, mode);
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
||||
|
63
src/input.c
63
src/input.c
@ -37,48 +37,27 @@
|
||||
|
||||
// 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 (newMode != GLFW_CURSOR_NORMAL &&
|
||||
newMode != GLFW_CURSOR_HIDDEN &&
|
||||
newMode != GLFW_CURSOR_DISABLED)
|
||||
if (mode != GLFW_CURSOR_NORMAL &&
|
||||
mode != GLFW_CURSOR_HIDDEN &&
|
||||
mode != GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid cursor mode %i", newMode);
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid cursor mode %i", mode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldMode == newMode)
|
||||
if (window->cursorMode == mode)
|
||||
return;
|
||||
|
||||
window->cursorMode = newMode;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&window->virtualCursorPosX,
|
||||
&window->virtualCursorPosY);
|
||||
|
||||
if (_glfw.cursorWindow == window)
|
||||
{
|
||||
if (oldMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.restoreCursorPosX,
|
||||
_glfw.restoreCursorPosY);
|
||||
}
|
||||
else if (newMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformSetCursorMode(window, mode);
|
||||
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_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);
|
||||
}
|
||||
window->cursorMode = mode;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y)
|
||||
void _glfwInputCursorPos(_GLFWwindow* window, double x, double y)
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
if (x == 0.0 && y == 0.0)
|
||||
return;
|
||||
if (window->virtualCursorPosX == x && window->virtualCursorPosY == y)
|
||||
return;
|
||||
|
||||
window->virtualCursorPosX += x;
|
||||
window->virtualCursorPosY += y;
|
||||
|
||||
x = window->virtualCursorPosX;
|
||||
y = window->virtualCursorPosY;
|
||||
}
|
||||
window->virtualCursorPosX = x;
|
||||
window->virtualCursorPosY = y;
|
||||
|
||||
if (window->callbacks.cursorPos)
|
||||
window->callbacks.cursorPos((GLFWwindow*) window, x, y);
|
||||
@ -490,9 +463,9 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
_glfwPlatformSetCursor(window, cursor);
|
||||
|
||||
window->cursor = cursor;
|
||||
|
||||
_glfwPlatformSetCursor(window, cursor);
|
||||
}
|
||||
|
||||
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
|
||||
|
@ -437,9 +437,6 @@ struct _GLFWlibrary
|
||||
int refreshRate;
|
||||
} hints;
|
||||
|
||||
// Where to place the cursor when re-enabled
|
||||
double restoreCursorPosX, restoreCursorPosY;
|
||||
|
||||
_GLFWcursor* cursorListHead;
|
||||
|
||||
_GLFWwindow* windowListHead;
|
||||
@ -906,7 +903,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
|
||||
* of the client area of the window.
|
||||
* @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.
|
||||
* @param[in] window The window that received the event.
|
||||
|
@ -208,8 +208,7 @@ static void handlePointerMotion(_GLFWwindow* window,
|
||||
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);
|
||||
|
||||
if (current_x != x || current_y != y)
|
||||
_glfwInputCursorMotion(window, x, y);
|
||||
_glfwInputCursorPos(window, x, y);
|
||||
if (dx != 0 || dy != 0)
|
||||
_glfwInputScroll(window, dx, dy);
|
||||
}
|
||||
|
@ -252,6 +252,8 @@ typedef struct _GLFWlibraryWin32
|
||||
char keyName[64];
|
||||
short int publicKeys[512];
|
||||
short int nativeKeys[GLFW_KEY_LAST + 1];
|
||||
// Where to place the cursor when re-enabled
|
||||
double restoreCursorPosX, restoreCursorPosY;
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
|
@ -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
|
||||
//
|
||||
static void updateClipRect(_GLFWwindow* window)
|
||||
{
|
||||
RECT clipRect;
|
||||
GetClientRect(window->win32.handle, &clipRect);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
|
||||
ClipCursor(&clipRect);
|
||||
if (window)
|
||||
{
|
||||
RECT clipRect;
|
||||
GetClientRect(window->win32.handle, &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
|
||||
@ -420,10 +474,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
{
|
||||
case WM_SETFOCUS:
|
||||
{
|
||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
||||
|
||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -571,12 +626,15 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (_glfw.cursorWindow != window)
|
||||
break;
|
||||
|
||||
_glfwInputCursorMotion(window,
|
||||
x - window->win32.lastCursorPosX,
|
||||
y - window->win32.lastCursorPosY);
|
||||
const int dx = x - window->win32.lastCursorPosX;
|
||||
const int dy = y - window->win32.lastCursorPosY;
|
||||
|
||||
_glfwInputCursorPos(window,
|
||||
window->virtualCursorPosX + dx,
|
||||
window->virtualCursorPosY + dy);
|
||||
}
|
||||
else
|
||||
_glfwInputCursorMotion(window, x, y);
|
||||
_glfwInputCursorPos(window, x, y);
|
||||
|
||||
window->win32.lastCursorPosX = x;
|
||||
window->win32.lastCursorPosY = y;
|
||||
@ -725,19 +783,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
if (_glfw.cursorWindow == window && LOWORD(lParam) == HTCLIENT)
|
||||
if (LOWORD(lParam) == HTCLIENT)
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_HIDDEN ||
|
||||
window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
SetCursor(NULL);
|
||||
return TRUE;
|
||||
}
|
||||
else if (window->cursor)
|
||||
{
|
||||
SetCursor(window->cursor->win32.handle);
|
||||
return TRUE;
|
||||
}
|
||||
updateCursorImage(window, window->cursorMode);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -767,7 +816,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
|
||||
// Move the mouse to the position of the drop
|
||||
DragQueryPoint(drop, &pt);
|
||||
_glfwInputCursorMotion(window, pt.x, pt.y);
|
||||
_glfwInputCursorPos(window, pt.x, pt.y);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
@ -1007,6 +1056,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
_glfwPlatformFocusWindow(window);
|
||||
if (!acquireMonitor(window))
|
||||
return GLFW_FALSE;
|
||||
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -1444,28 +1495,24 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
|
||||
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
POINT pos;
|
||||
|
||||
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)
|
||||
SetCursor(window->cursor->win32.handle);
|
||||
else
|
||||
SetCursor(LoadCursorW(NULL, IDC_ARROW));
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.win32.restoreCursorPosX,
|
||||
&_glfw.win32.restoreCursorPosY);
|
||||
centerCursor(window);
|
||||
updateClipRect(window);
|
||||
}
|
||||
else
|
||||
SetCursor(NULL);
|
||||
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
updateClipRect(NULL);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.win32.restoreCursorPosX,
|
||||
_glfw.win32.restoreCursorPosY);
|
||||
}
|
||||
|
||||
if (cursorInClientArea(window))
|
||||
updateCursorImage(window, mode);
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
||||
@ -1525,32 +1572,8 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
|
||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||
{
|
||||
RECT area;
|
||||
POINT pos;
|
||||
|
||||
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));
|
||||
if (cursorInClientArea(window))
|
||||
updateCursorImage(window, window->cursorMode);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
||||
|
14
src/window.c
14
src/window.c
@ -219,19 +219,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
}
|
||||
|
||||
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 (!window->monitor)
|
||||
{
|
||||
if (wndconfig.visible)
|
||||
{
|
||||
|
@ -91,9 +91,9 @@ static void pointerHandleMotion(void* data,
|
||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||
}
|
||||
|
||||
_glfwInputCursorMotion(window,
|
||||
wl_fixed_to_double(sx),
|
||||
wl_fixed_to_double(sy));
|
||||
_glfwInputCursorPos(window,
|
||||
wl_fixed_to_double(sx),
|
||||
wl_fixed_to_double(sy));
|
||||
}
|
||||
|
||||
static void pointerHandleButton(void* data,
|
||||
|
@ -784,9 +784,9 @@ static void handleRelativeMotion(void* data,
|
||||
if (window->cursorMode != GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
_glfwInputCursorMotion(window,
|
||||
wl_fixed_to_double(dxUnaccel),
|
||||
wl_fixed_to_double(dyUnaccel));
|
||||
_glfwInputCursorPos(window,
|
||||
window->virtualCursorPosX + wl_fixed_to_double(dxUnaccel),
|
||||
window->virtualCursorPosY + wl_fixed_to_double(dyUnaccel));
|
||||
}
|
||||
|
||||
static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
|
||||
|
@ -118,7 +118,7 @@ typedef struct _GLFWwindowX11
|
||||
int xpos, ypos;
|
||||
|
||||
// The last received cursor position, regardless of source
|
||||
double lastCursorPosX, lastCursorPosY;
|
||||
int lastCursorPosX, lastCursorPosY;
|
||||
// The last position the cursor was warped to by GLFW
|
||||
int warpCursorPosX, warpCursorPosY;
|
||||
|
||||
@ -155,6 +155,8 @@ typedef struct _GLFWlibraryX11
|
||||
short int publicKeys[256];
|
||||
// GLFW key to X11 keycode LUT
|
||||
short int nativeKeys[GLFW_KEY_LAST + 1];
|
||||
// Where to place the cursor when re-enabled
|
||||
double restoreCursorPosX, restoreCursorPosY;
|
||||
|
||||
// Window manager atoms
|
||||
Atom WM_PROTOCOLS;
|
||||
|
@ -387,6 +387,15 @@ static char** parseUriList(char* text, int* count)
|
||||
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)
|
||||
//
|
||||
static GLFWbool createWindow(_GLFWwindow* window,
|
||||
@ -1158,12 +1167,15 @@ static void processEvent(XEvent *event)
|
||||
if (_glfw.cursorWindow != window)
|
||||
return;
|
||||
|
||||
_glfwInputCursorMotion(window,
|
||||
x - window->x11.lastCursorPosX,
|
||||
y - window->x11.lastCursorPosY);
|
||||
const int dx = x - window->x11.lastCursorPosX;
|
||||
const int dy = y - window->x11.lastCursorPosY;
|
||||
|
||||
_glfwInputCursorPos(window,
|
||||
window->virtualCursorPosX + dx,
|
||||
window->virtualCursorPosY + dy);
|
||||
}
|
||||
else
|
||||
_glfwInputCursorMotion(window, x, y);
|
||||
_glfwInputCursorPos(window, x, y);
|
||||
}
|
||||
|
||||
window->x11.lastCursorPosX = x;
|
||||
@ -1265,7 +1277,7 @@ static void processEvent(XEvent *event)
|
||||
int 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
|
||||
XEvent reply;
|
||||
@ -1517,6 +1529,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
updateWindowMode(window);
|
||||
if (!acquireMonitor(window))
|
||||
return GLFW_FALSE;
|
||||
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -1999,11 +2013,7 @@ void _glfwPlatformPollEvents(void)
|
||||
|
||||
_GLFWwindow* window = _glfw.cursorWindow;
|
||||
if (window && window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
|
||||
}
|
||||
centerCursor(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformWaitEvents(void)
|
||||
@ -2082,31 +2092,35 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.x11.restoreCursorPosX,
|
||||
&_glfw.x11.restoreCursorPosY);
|
||||
centerCursor(window);
|
||||
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
window->x11.handle, _glfw.x11.cursor, CurrentTime);
|
||||
}
|
||||
else
|
||||
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
XUngrabPointer(_glfw.x11.display, CurrentTime);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.x11.restoreCursorPosX,
|
||||
_glfw.x11.restoreCursorPosY);
|
||||
}
|
||||
|
||||
if (mode == GLFW_CURSOR_NORMAL)
|
||||
{
|
||||
if (window->cursor)
|
||||
{
|
||||
XDefineCursor(_glfw.x11.display, window->x11.handle,
|
||||
window->cursor->x11.handle);
|
||||
}
|
||||
else
|
||||
XUndefineCursor(_glfw.x11.display, window->x11.handle);
|
||||
}
|
||||
else
|
||||
if (mode == GLFW_CURSOR_NORMAL)
|
||||
{
|
||||
if (window->cursor)
|
||||
{
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user