|
@@ -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; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|