| @@ -98,7 +98,7 @@ struct Window::Internal { | |||||
| int lastWindowHeight = 0; | int lastWindowHeight = 0; | ||||
| int frame = 0; | int frame = 0; | ||||
| bool ignoreNextMouseDelta = false; | |||||
| double ignoreMouseDeltaUntil = -INFINITY; | |||||
| double monitorRefreshRate = 0.0; | double monitorRefreshRate = 0.0; | ||||
| double frameTime = NAN; | double frameTime = NAN; | ||||
| double lastFrameDuration = NAN; | double lastFrameDuration = NAN; | ||||
| @@ -167,28 +167,15 @@ static void cursorPosCallback(GLFWwindow* win, double xpos, double ypos) { | |||||
| math::Vec mousePos = math::Vec(xpos, ypos).div(APP->window->pixelRatio / APP->window->windowRatio).round(); | math::Vec mousePos = math::Vec(xpos, ypos).div(APP->window->pixelRatio / APP->window->windowRatio).round(); | ||||
| math::Vec mouseDelta = mousePos.minus(APP->window->internal->lastMousePos); | math::Vec mouseDelta = mousePos.minus(APP->window->internal->lastMousePos); | ||||
| // if (glfwGetInputMode(win, GLFW_CURSOR) != GLFW_CURSOR_NORMAL && std::fabs(mouseDelta.y) > 20.0) { | |||||
| // DEBUG("%d (%f, %f) (%f, %f)", APP->window->internal->frame, VEC_ARGS(mousePos), VEC_ARGS(mouseDelta)); | |||||
| // } | |||||
| // Workaround for GLFW warping mouse to a different position when the cursor is locked or unlocked. | // Workaround for GLFW warping mouse to a different position when the cursor is locked or unlocked. | ||||
| if (APP->window->internal->ignoreNextMouseDelta) { | |||||
| APP->window->internal->ignoreNextMouseDelta = false; | |||||
| if (APP->window->internal->ignoreMouseDeltaUntil > APP->window->internal->frameTime) { | |||||
| mouseDelta = math::Vec(); | mouseDelta = math::Vec(); | ||||
| } | } | ||||
| int cursorMode = glfwGetInputMode(win, GLFW_CURSOR); | |||||
| (void) cursorMode; | |||||
| #if defined ARCH_MAC | |||||
| // Workaround for Mac. We can't use GLFW_CURSOR_DISABLED because it's buggy, so implement it on our own. | |||||
| // This is not an ideal implementation. For example, if the user drags off the screen, the new mouse position will be clamped. | |||||
| if (cursorMode == GLFW_CURSOR_HIDDEN) { | |||||
| // CGSetLocalEventsSuppressionInterval(0.0); | |||||
| glfwSetCursorPos(win, APP->window->internal->lastMousePos.x, APP->window->internal->lastMousePos.y); | |||||
| CGAssociateMouseAndMouseCursorPosition(true); | |||||
| mousePos = APP->window->internal->lastMousePos; | |||||
| } | |||||
| // Because sometimes the cursor turns into an arrow when its position is on the boundary of the window | |||||
| glfwSetCursor(win, NULL); | |||||
| #endif | |||||
| APP->window->internal->lastMousePos = mousePos; | APP->window->internal->lastMousePos = mousePos; | ||||
| APP->event->handleHover(mousePos, mouseDelta); | APP->event->handleHover(mousePos, mouseDelta); | ||||
| @@ -647,12 +634,14 @@ void Window::cursorLock() { | |||||
| if (!settings::allowCursorLock) | if (!settings::allowCursorLock) | ||||
| return; | return; | ||||
| #if defined ARCH_MAC | |||||
| glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); | |||||
| #else | |||||
| glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_DISABLED); | glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_DISABLED); | ||||
| // Due to a bug in GLFW, setting GLFW_CURSOR_DISABLED causes a spurious mouse position delta after a few frames. | |||||
| // https://github.com/glfw/glfw/issues/2523 | |||||
| // Emperically, this seems to be up to 3-6 frames at 60 Hz but in fewer frames at lower framerates. | |||||
| #if defined ARCH_MAC | |||||
| internal->ignoreMouseDeltaUntil = internal->frameTime + 0.09; | |||||
| #endif | #endif | ||||
| internal->ignoreNextMouseDelta = true; | |||||
| } | } | ||||
| @@ -661,7 +650,6 @@ void Window::cursorUnlock() { | |||||
| return; | return; | ||||
| glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_NORMAL); | glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_NORMAL); | ||||
| internal->ignoreNextMouseDelta = true; | |||||
| } | } | ||||