X11: Fix event time wrapping

Related to #1012.
This commit is contained in:
Camilla Löwy 2017-09-14 15:03:06 +02:00
parent 138b10eb28
commit 750ac64245
2 changed files with 21 additions and 10 deletions

View File

@ -225,9 +225,9 @@ typedef struct _GLFWlibraryX11
double restoreCursorPosX, restoreCursorPosY; double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active // The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow; _GLFWwindow* disabledCursorWindow;
// State for accumulating a non-wrapping event time
// The time of the last event Time lastTimestamp;
Time lastEventTime; uint64_t eventTime;
// Window manager atoms // Window manager atoms
Atom WM_PROTOCOLS; Atom WM_PROTOCOLS;

View File

@ -1034,6 +1034,14 @@ static unsigned int decodeUTF8(const char** s)
} }
#endif /*X_HAVE_UTF8_STRING*/ #endif /*X_HAVE_UTF8_STRING*/
// Updates the event time with the specified timestamp
//
static void updateEventTime(Time timestamp)
{
_glfw.x11.eventTime += timestamp - _glfw.x11.lastTimestamp;
_glfw.x11.lastTimestamp = timestamp;
}
// Process the specified X event // Process the specified X event
// //
static void processEvent(XEvent *event) static void processEvent(XEvent *event)
@ -1076,6 +1084,7 @@ static void processEvent(XEvent *event)
const double* values = re->raw_values; const double* values = re->raw_values;
double xpos = window->virtualCursorPosX; double xpos = window->virtualCursorPosX;
double ypos = window->virtualCursorPosY; double ypos = window->virtualCursorPosY;
updateEventTime(re->time);
if (XIMaskIsSet(re->valuators.mask, 0)) if (XIMaskIsSet(re->valuators.mask, 0))
{ {
@ -1121,7 +1130,7 @@ static void processEvent(XEvent *event)
const int key = translateKey(keycode); const int key = translateKey(keycode);
const int mods = translateState(event->xkey.state); const int mods = translateState(event->xkey.state);
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
_glfw.x11.lastEventTime = event->xkey.time; updateEventTime(event->xkey.time);
if (window->x11.ic) if (window->x11.ic)
{ {
@ -1215,7 +1224,7 @@ static void processEvent(XEvent *event)
{ {
const int key = translateKey(keycode); const int key = translateKey(keycode);
const int mods = translateState(event->xkey.state); const int mods = translateState(event->xkey.state);
_glfw.x11.lastEventTime = event->xkey.time; updateEventTime(event->xkey.time);
if (!_glfw.x11.xkb.detectable) if (!_glfw.x11.xkb.detectable)
{ {
@ -1256,7 +1265,7 @@ static void processEvent(XEvent *event)
case ButtonPress: case ButtonPress:
{ {
const int mods = translateState(event->xbutton.state); const int mods = translateState(event->xbutton.state);
_glfw.x11.lastEventTime = event->xbutton.time; updateEventTime(event->xbutton.time);
if (event->xbutton.button == Button1) if (event->xbutton.button == Button1)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
@ -1291,7 +1300,7 @@ static void processEvent(XEvent *event)
case ButtonRelease: case ButtonRelease:
{ {
const int mods = translateState(event->xbutton.state); const int mods = translateState(event->xbutton.state);
_glfw.x11.lastEventTime = event->xbutton.time; updateEventTime(event->xbutton.time);
if (event->xbutton.button == Button1) if (event->xbutton.button == Button1)
{ {
@ -1329,6 +1338,8 @@ static void processEvent(XEvent *event)
case EnterNotify: case EnterNotify:
{ {
updateEventTime(event->xcrossing.time);
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise // HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
// ignore the defined cursor for hidden cursor mode // ignore the defined cursor for hidden cursor mode
if (window->cursorMode == GLFW_CURSOR_HIDDEN) if (window->cursorMode == GLFW_CURSOR_HIDDEN)
@ -1340,6 +1351,7 @@ static void processEvent(XEvent *event)
case LeaveNotify: case LeaveNotify:
{ {
updateEventTime(event->xcrossing.time);
_glfwInputCursorEnter(window, GLFW_FALSE); _glfwInputCursorEnter(window, GLFW_FALSE);
return; return;
} }
@ -1348,7 +1360,7 @@ static void processEvent(XEvent *event)
{ {
const int x = event->xmotion.x; const int x = event->xmotion.x;
const int y = event->xmotion.y; const int y = event->xmotion.y;
_glfw.x11.lastEventTime = event->xmotion.time; updateEventTime(event->xmotion.time);
if (x != window->x11.warpCursorPosX || y != window->x11.warpCursorPosY) if (x != window->x11.warpCursorPosX || y != window->x11.warpCursorPosY)
{ {
@ -2435,8 +2447,7 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
double _glfwPlatformGetEventTime(void) double _glfwPlatformGetEventTime(void)
{ {
/* X11 events are stored in milliseconds */ return (double) _glfw.x11.eventTime / 1000.0;
return (double) _glfw.x11.lastEventTime / 1000.0;
} }
void _glfwPlatformPollEvents(void) void _glfwPlatformPollEvents(void)