Explorar o código

Pass the OS event timestamp for keyboard, mouse, and touch events where possible

Currently implemented for Windows and Apple platforms
Sam Lantinga %!s(int64=2) %!d(string=hai) anos
pai
achega
0a3262e819
Modificáronse 62 ficheiros con 441 adicións e 313 borrados
  1. 1 1
      WhatsNew.txt
  2. 3 0
      docs/README-migration.md
  3. 6 6
      src/audio/SDL_audio.c
  4. 1 1
      src/core/android/SDL_android.c
  5. 9 9
      src/core/linux/SDL_evdev.c
  6. 6 6
      src/core/openbsd/SDL_wscons_kbd.c
  7. 10 10
      src/core/openbsd/SDL_wscons_mouse.c
  8. 3 3
      src/core/winrt/SDL_winrtapp_direct3d.cpp
  9. 1 1
      src/events/SDL_clipboardevents.c
  10. 1 0
      src/events/SDL_displayevents.c
  11. 3 5
      src/events/SDL_dropevents.c
  12. 6 2
      src/events/SDL_events.c
  13. 6 3
      src/events/SDL_gesture.c
  14. 22 18
      src/events/SDL_keyboard.c
  15. 4 4
      src/events/SDL_keyboard_c.h
  16. 21 18
      src/events/SDL_mouse.c
  17. 4 4
      src/events/SDL_mouse_c.h
  18. 14 12
      src/events/SDL_touch.c
  19. 2 4
      src/events/SDL_touch_c.h
  20. 1 0
      src/events/SDL_windowevents.c
  21. 8 0
      src/joystick/SDL_gamecontroller.c
  22. 11 3
      src/joystick/SDL_joystick.c
  23. 2 2
      src/joystick/android/SDL_sysjoystick.c
  24. 5 5
      src/main/haiku/SDL_BApp.h
  25. 1 0
      src/render/direct3d/SDL_render_d3d.c
  26. 1 0
      src/render/direct3d11/SDL_render_d3d11.c
  27. 1 0
      src/render/direct3d12/SDL_render_d3d12.c
  28. 1 0
      src/sensor/SDL_sensor.c
  29. 1 0
      src/video/android/SDL_androidevents.c
  30. 2 2
      src/video/android/SDL_androidkeyboard.c
  31. 6 6
      src/video/android/SDL_androidmouse.c
  32. 3 3
      src/video/android/SDL_androidtouch.c
  33. 1 0
      src/video/cocoa/SDL_cocoaevents.h
  34. 18 0
      src/video/cocoa/SDL_cocoaevents.m
  35. 4 4
      src/video/cocoa/SDL_cocoakeyboard.m
  36. 3 3
      src/video/cocoa/SDL_cocoamouse.m
  37. 11 11
      src/video/cocoa/SDL_cocoawindow.m
  38. 8 8
      src/video/emscripten/SDL_emscriptenevents.c
  39. 5 5
      src/video/haiku/SDL_BApp.h
  40. 1 1
      src/video/kmsdrm/SDL_kmsdrmmouse.c
  41. 1 0
      src/video/n3ds/SDL_n3dsevents.c
  42. 2 2
      src/video/n3ds/SDL_n3dstouch.c
  43. 2 2
      src/video/ngage/SDL_ngageevents.cpp
  44. 2 2
      src/video/psp/SDL_pspevents.c
  45. 1 1
      src/video/raspberry/SDL_rpimouse.c
  46. 4 4
      src/video/riscos/SDL_riscosevents.c
  47. 3 0
      src/video/uikit/SDL_uikitevents.h
  48. 22 4
      src/video/uikit/SDL_uikitevents.m
  49. 16 13
      src/video/uikit/SDL_uikitview.m
  50. 5 5
      src/video/uikit/SDL_uikitviewcontroller.m
  51. 28 28
      src/video/vita/SDL_vitakeyboard.c
  52. 7 7
      src/video/vita/SDL_vitamouse.c
  53. 3 3
      src/video/vita/SDL_vitatouch.c
  54. 4 4
      src/video/vita/SDL_vitavideo.c
  55. 14 14
      src/video/wayland/SDL_waylandevents.c
  56. 2 2
      src/video/wayland/SDL_waylandtouch.c
  57. 79 33
      src/video/windows/SDL_windowsevents.c
  58. 1 1
      src/video/windows/SDL_windowsmouse.c
  59. 2 2
      src/video/winrt/SDL_winrtkeyboard.cpp
  60. 9 9
      src/video/winrt/SDL_winrtpointerinput.cpp
  61. 12 12
      src/video/x11/SDL_x11events.c
  62. 5 5
      src/video/x11/SDL_x11xinput2.c

+ 1 - 1
WhatsNew.txt

@@ -35,4 +35,4 @@ General:
 * SDL_GetTicks() now returns a 64-bit value and the tick values should be directly compared instead of using the SDL_TICKS_PASSED macro
 * Added SDL_GetTicksNS() to return the number of nanoseconds since the SDL library initialized
 * Added SDL_DelayNS() to specify a delay in nanoseconds, to the highest precision the system will support
-* The timestamp member of the SDL_Event structure is now in nanoseconds, filled in with SDL_GetTicksNS()
+* The timestamp member of the SDL_Event structure is now in nanoseconds, filled in with the time the event was generated, or the time it was queued if that's not available

+ 3 - 0
docs/README-migration.md

@@ -35,6 +35,9 @@ The SDL3main and SDL3test libraries have been renamed SDL3_main and SDL3_test, r
 
 The `timestamp` member of the SDL_Event structure now represents nanoseconds, and is populated with `SDL_GetTicksNS()`
 
+You should set the `event.common.timestamp` field before passing an event to `SDL_PushEvent()`. If the timestamp is 0 it will be filled in with `SDL_GetTicksNS()`.
+
+
 ## SDL_platform.h
 
 The preprocessor symbol __MACOSX__ has been renamed __MACOS__, and __IPHONEOS__ has been renamed __IOS__

+ 6 - 6
src/audio/SDL_audio.c

@@ -414,8 +414,8 @@ void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpe
         /* Post the event, if desired */
         if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
             SDL_Event event;
-            SDL_zero(event);
-            event.adevice.type = SDL_AUDIODEVICEADDED;
+            event.type = SDL_AUDIODEVICEADDED;
+            event.common.timestamp = 0;
             event.adevice.which = device_index;
             event.adevice.iscapture = iscapture;
             SDL_PushEvent(&event);
@@ -445,8 +445,8 @@ void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
     /* Post the event, if desired */
     if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) {
         SDL_Event event;
-        SDL_zero(event);
-        event.adevice.type = SDL_AUDIODEVICEREMOVED;
+        event.type = SDL_AUDIODEVICEREMOVED;
+        event.common.timestamp = 0;
         event.adevice.which = device->id;
         event.adevice.iscapture = device->iscapture ? 1 : 0;
         SDL_PushEvent(&event);
@@ -497,8 +497,8 @@ void SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle)
     if (!device_was_opened) {
         if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) {
             SDL_Event event;
-            SDL_zero(event);
-            event.adevice.type = SDL_AUDIODEVICEREMOVED;
+            event.type = SDL_AUDIODEVICEREMOVED;
+            event.common.timestamp = 0;
             event.adevice.which = 0;
             event.adevice.iscapture = iscapture ? 1 : 0;
             SDL_PushEvent(&event);

+ 1 - 1
src/core/android/SDL_android.c

@@ -1257,7 +1257,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancod
     JNIEnv *env, jclass cls,
     jchar chUnicode)
 {
-    SDL_SendKeyboardUnicodeKey(chUnicode);
+    SDL_SendKeyboardUnicodeKey(0, chUnicode);
 }
 
 JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(

+ 9 - 9
src/core/linux/SDL_evdev.c

@@ -302,9 +302,9 @@ void SDL_EVDEV_Poll(void)
                     if (events[i].code >= BTN_MOUSE && events[i].code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) {
                         mouse_button = events[i].code - BTN_MOUSE;
                         if (events[i].value == 0) {
-                            SDL_SendMouseButton(mouse->focus, (SDL_MouseID)item->fd, SDL_RELEASED, EVDEV_MouseButtons[mouse_button]);
+                            SDL_SendMouseButton(0, mouse->focus, (SDL_MouseID)item->fd, SDL_RELEASED, EVDEV_MouseButtons[mouse_button]);
                         } else if (events[i].value == 1) {
-                            SDL_SendMouseButton(mouse->focus, (SDL_MouseID)item->fd, SDL_PRESSED, EVDEV_MouseButtons[mouse_button]);
+                            SDL_SendMouseButton(0, mouse->focus, (SDL_MouseID)item->fd, SDL_PRESSED, EVDEV_MouseButtons[mouse_button]);
                         }
                         break;
                     }
@@ -328,9 +328,9 @@ void SDL_EVDEV_Poll(void)
                     scan_code = SDL_EVDEV_translate_keycode(events[i].code);
                     if (scan_code != SDL_SCANCODE_UNKNOWN) {
                         if (events[i].value == 0) {
-                            SDL_SendKeyboardKey(SDL_RELEASED, scan_code);
+                            SDL_SendKeyboardKey(0, SDL_RELEASED, scan_code);
                         } else if (events[i].value == 1 || events[i].value == 2 /* key repeated */) {
-                            SDL_SendKeyboardKey(SDL_PRESSED, scan_code);
+                            SDL_SendKeyboardKey(0, SDL_PRESSED, scan_code);
                         }
                     }
                     SDL_EVDEV_kbd_keycode(_this->kbd, events[i].code, events[i].value);
@@ -446,11 +446,11 @@ void SDL_EVDEV_Poll(void)
                     case SYN_REPORT:
                         /* Send mouse axis changes together to ensure consistency and reduce event processing overhead */
                         if (item->mouse_x != 0 || item->mouse_y != 0) {
-                            SDL_SendMouseMotion(mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, item->mouse_x, item->mouse_y);
+                            SDL_SendMouseMotion(0, mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, item->mouse_x, item->mouse_y);
                             item->mouse_x = item->mouse_y = 0;
                         }
                         if (item->mouse_wheel != 0 || item->mouse_hwheel != 0) {
-                            SDL_SendMouseWheel(mouse->focus, (SDL_MouseID)item->fd,
+                            SDL_SendMouseWheel(0, mouse->focus, (SDL_MouseID)item->fd,
                                                item->mouse_hwheel / (item->high_res_hwheel ? 120.0f : 1.0f),
                                                item->mouse_wheel / (item->high_res_wheel ? 120.0f : 1.0f),
                                                SDL_MOUSEWHEEL_NORMAL);
@@ -480,16 +480,16 @@ void SDL_EVDEV_Poll(void)
                              * be window-relative in that case. */
                             switch (item->touchscreen_data->slots[j].delta) {
                             case EVDEV_TOUCH_SLOTDELTA_DOWN:
-                                SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, SDL_TRUE, norm_x, norm_y, norm_pressure);
+                                SDL_SendTouch(0, item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, SDL_TRUE, norm_x, norm_y, norm_pressure);
                                 item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE;
                                 break;
                             case EVDEV_TOUCH_SLOTDELTA_UP:
-                                SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, SDL_FALSE, norm_x, norm_y, norm_pressure);
+                                SDL_SendTouch(0, item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, SDL_FALSE, norm_x, norm_y, norm_pressure);
                                 item->touchscreen_data->slots[j].tracking_id = -1;
                                 item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE;
                                 break;
                             case EVDEV_TOUCH_SLOTDELTA_MOVE:
-                                SDL_SendTouchMotion(item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, norm_x, norm_y, norm_pressure);
+                                SDL_SendTouchMotion(0, item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, norm_x, norm_y, norm_pressure);
                                 item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE;
                                 break;
                             default:

+ 6 - 6
src/core/openbsd/SDL_wscons_kbd.c

@@ -553,22 +553,22 @@ static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_
     switch (keyDesc.command) {
     case KS_Cmd_ScrollBack:
     {
-        SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEUP);
+        SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEUP);
         return;
     }
     case KS_Cmd_ScrollFwd:
     {
-        SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEDOWN);
+        SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEDOWN);
         return;
     }
     }
     for (i = 0; i < sizeof(conversion_table) / sizeof(struct wscons_keycode_to_SDL); i++) {
         if (conversion_table[i].sourcekey == group[0]) {
-            SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, conversion_table[i].targetKey);
+            SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, conversion_table[i].targetKey);
             return;
         }
     }
-    SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_UNKNOWN);
+    SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_UNKNOWN);
 }
 
 static void updateKeyboard(SDL_WSCONS_input_data *input)
@@ -802,13 +802,13 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
             } break;
             case WSCONS_EVENT_ALL_KEYS_UP:
                 for (i = 0; i < SDL_NUM_SCANCODES; i++) {
-                    SDL_SendKeyboardKey(SDL_RELEASED, i);
+                    SDL_SendKeyboardKey(0, SDL_RELEASED, i);
                 }
                 break;
             }
 
             if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7)
-                SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value);
+                SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value);
             else
                 Translate_to_keycode(input, type, events[i].value);
 

+ 10 - 10
src/core/openbsd/SDL_wscons_mouse.c

@@ -74,13 +74,13 @@ void updateMouse(SDL_WSCONS_mouse_input_data *inputData)
             {
                 switch (events[i].value) {
                 case 0: /* Left Mouse Button. */
-                    SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_LEFT);
+                    SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_LEFT);
                     break;
                 case 1: /* Middle Mouse Button. */
-                    SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_MIDDLE);
+                    SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_MIDDLE);
                     break;
                 case 2: /* Right Mouse Button. */
-                    SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_RIGHT);
+                    SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_RIGHT);
                     break;
                 }
             } break;
@@ -88,34 +88,34 @@ void updateMouse(SDL_WSCONS_mouse_input_data *inputData)
             {
                 switch (events[i].value) {
                 case 0: /* Left Mouse Button. */
-                    SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_LEFT);
+                    SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_LEFT);
                     break;
                 case 1: /* Middle Mouse Button. */
-                    SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_MIDDLE);
+                    SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_MIDDLE);
                     break;
                 case 2: /* Right Mouse Button. */
-                    SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_RIGHT);
+                    SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_RIGHT);
                     break;
                 }
             } break;
             case WSCONS_EVENT_MOUSE_DELTA_X:
             {
-                SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, events[i].value, 0);
+                SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, events[i].value, 0);
                 break;
             }
             case WSCONS_EVENT_MOUSE_DELTA_Y:
             {
-                SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, 0, -events[i].value);
+                SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, 0, -events[i].value);
                 break;
             }
             case WSCONS_EVENT_MOUSE_DELTA_W:
             {
-                SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
+                SDL_SendMouseWheel(0, mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
                 break;
             }
             case WSCONS_EVENT_MOUSE_DELTA_Z:
             {
-                SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL);
+                SDL_SendMouseWheel(0, mouse->focus, mouse->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL);
                 break;
             }
             }

+ 3 - 3
src/core/winrt/SDL_winrtapp_direct3d.cpp

@@ -552,7 +552,7 @@ void SDL_WinRTApp::OnWindowActivated(CoreWindow ^ sender, WindowActivatedEventAr
              */
 #if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION >= NTDDI_WINBLUE)
             Point cursorPos = WINRT_TransformCursorPosition(window, sender->PointerPosition, TransformToSDLWindowSize);
-            SDL_SendMouseMotion(window, 0, 0, (int)cursorPos.X, (int)cursorPos.Y);
+            SDL_SendMouseMotion(0, window, 0, 0, (int)cursorPos.X, (int)cursorPos.Y);
 #endif
 
             /* TODO, WinRT: see if the Win32 bugfix from https://hg.libsdl.org/SDL/rev/d278747da408 needs to be applied (on window activation) */
@@ -743,8 +743,8 @@ void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow ^ sender, W
 template <typename BackButtonEventArgs>
 static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args)
 {
-    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
-    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
+    SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_AC_BACK);
+    SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_AC_BACK);
 
     if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) {
         args->Handled = true;

+ 1 - 1
src/events/SDL_clipboardevents.c

@@ -34,7 +34,7 @@ int SDL_SendClipboardUpdate(void)
     if (SDL_GetEventState(SDL_CLIPBOARDUPDATE) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_CLIPBOARDUPDATE;
-
+        event.common.timestamp = 0;
         posted = (SDL_PushEvent(&event) > 0);
     }
     return posted;

+ 1 - 0
src/events/SDL_displayevents.c

@@ -45,6 +45,7 @@ int SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data
     if (SDL_GetEventState(SDL_DISPLAYEVENT) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_DISPLAYEVENT;
+        event.common.timestamp = 0;
         event.display.event = displayevent;
         event.display.display = SDL_GetIndexOfDisplay(display);
         event.display.data1 = data1;

+ 3 - 5
src/events/SDL_dropevents.c

@@ -40,11 +40,8 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
         if (need_begin) {
             SDL_zero(event);
             event.type = SDL_DROPBEGIN;
-
-            if (window) {
-                event.drop.windowID = window->id;
-            }
-
+            event.common.timestamp = 0;
+            event.drop.windowID = window ? window->id : 0;
             posted = (SDL_PushEvent(&event) > 0);
             if (!posted) {
                 return 0;
@@ -58,6 +55,7 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
 
         SDL_zero(event);
         event.type = evtype;
+        event.common.timestamp = 0;
         event.drop.file = data ? SDL_strdup(data) : NULL;
         event.drop.windowID = window ? window->id : 0;
         posted = (SDL_PushEvent(&event) > 0);

+ 6 - 2
src/events/SDL_events.c

@@ -948,8 +948,8 @@ static void SDL_PumpEventsInternal(SDL_bool push_sentinel)
     if (push_sentinel && SDL_GetEventState(SDL_POLLSENTINEL) == SDL_ENABLE) {
         SDL_Event sentinel;
 
-        SDL_zero(sentinel);
         sentinel.type = SDL_POLLSENTINEL;
+        sentinel.common.timestamp = 0;
         SDL_PushEvent(&sentinel);
     }
 }
@@ -1192,7 +1192,9 @@ int SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
 
 int SDL_PushEvent(SDL_Event *event)
 {
-    event->common.timestamp = SDL_GetTicksNS();
+    if (!event->common.timestamp) {
+        event->common.timestamp = SDL_GetTicksNS();
+    }
 
     if (SDL_EventOK.callback || SDL_event_watchers_count > 0) {
         if (SDL_event_watchers_lock == NULL || SDL_LockMutex(SDL_event_watchers_lock) == 0) {
@@ -1414,6 +1416,7 @@ int SDL_SendAppEvent(SDL_EventType eventType)
     if (SDL_GetEventState(eventType) == SDL_ENABLE) {
         SDL_Event event;
         event.type = eventType;
+        event.common.timestamp = 0;
         posted = (SDL_PushEvent(&event) > 0);
     }
     return posted;
@@ -1428,6 +1431,7 @@ int SDL_SendSysWMEvent(SDL_SysWMmsg *message)
         SDL_Event event;
         SDL_memset(&event, 0, sizeof(event));
         event.type = SDL_SYSWMEVENT;
+        event.common.timestamp = 0;
         event.syswm.msg = message;
         posted = (SDL_PushEvent(&event) > 0);
     }

+ 6 - 3
src/events/SDL_gesture.c

@@ -525,7 +525,8 @@ static void SDL_SendGestureMulti(SDL_GestureTouch *touch, float dTheta, float dD
 {
     if (SDL_GetEventState(SDL_MULTIGESTURE) == SDL_ENABLE) {
         SDL_Event event;
-        event.mgesture.type = SDL_MULTIGESTURE;
+        event.type = SDL_MULTIGESTURE;
+        event.common.timestamp = 0;
         event.mgesture.touchId = touch->id;
         event.mgesture.x = touch->centroid.x;
         event.mgesture.y = touch->centroid.y;
@@ -542,7 +543,8 @@ static void SDL_SendGestureDollar(SDL_GestureTouch *touch,
 {
     if (SDL_GetEventState(SDL_DOLLARGESTURE) == SDL_ENABLE) {
         SDL_Event event;
-        event.dgesture.type = SDL_DOLLARGESTURE;
+        event.type = SDL_DOLLARGESTURE;
+        event.common.timestamp = 0;
         event.dgesture.touchId = touch->id;
         event.dgesture.x = touch->centroid.x;
         event.dgesture.y = touch->centroid.y;
@@ -558,7 +560,8 @@ static void SDL_SendDollarRecord(SDL_GestureTouch *touch, SDL_GestureID gestureI
 {
     if (SDL_GetEventState(SDL_DOLLARRECORD) == SDL_ENABLE) {
         SDL_Event event;
-        event.dgesture.type = SDL_DOLLARRECORD;
+        event.type = SDL_DOLLARRECORD;
+        event.common.timestamp = 0;
         event.dgesture.touchId = touch->id;
         event.dgesture.gestureId = gestureId;
         SDL_PushEvent(&event);

+ 22 - 18
src/events/SDL_keyboard.c

@@ -681,7 +681,7 @@ void SDL_ResetKeyboard(void)
 #endif
     for (scancode = (SDL_Scancode)0; scancode < SDL_NUM_SCANCODES; ++scancode) {
         if (keyboard->keystate[scancode] == SDL_PRESSED) {
-            SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+            SDL_SendKeyboardKey(0, SDL_RELEASED, scancode);
         }
     }
 }
@@ -789,7 +789,7 @@ void SDL_SetKeyboardFocus(SDL_Window *window)
     }
 }
 
-static int SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
+static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint8 source, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
 {
     SDL_Keyboard *keyboard = &SDL_keyboard;
     int posted;
@@ -903,7 +903,8 @@ static int SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode s
     posted = 0;
     if (SDL_GetEventState(type) == SDL_ENABLE) {
         SDL_Event event;
-        event.key.type = type;
+        event.type = type;
+        event.common.timestamp = timestamp;
         event.key.state = state;
         event.key.repeat = repeat;
         event.key.keysym.scancode = scancode;
@@ -931,7 +932,7 @@ static int SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode s
     return posted;
 }
 
-int SDL_SendKeyboardUnicodeKey(Uint32 ch)
+int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch)
 {
     SDL_Scancode code = SDL_SCANCODE_UNKNOWN;
     uint16_t mod = 0;
@@ -943,33 +944,33 @@ int SDL_SendKeyboardUnicodeKey(Uint32 ch)
 
     if (mod & KMOD_SHIFT) {
         /* If the character uses shift, press shift down */
-        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
+        SDL_SendKeyboardKey(timestamp, SDL_PRESSED, SDL_SCANCODE_LSHIFT);
     }
 
     /* Send a keydown and keyup for the character */
-    SDL_SendKeyboardKey(SDL_PRESSED, code);
-    SDL_SendKeyboardKey(SDL_RELEASED, code);
+    SDL_SendKeyboardKey(timestamp, SDL_PRESSED, code);
+    SDL_SendKeyboardKey(timestamp, SDL_RELEASED, code);
 
     if (mod & KMOD_SHIFT) {
         /* If the character uses shift, release shift */
-        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
+        SDL_SendKeyboardKey(timestamp, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
     }
     return 0;
 }
 
-int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
+int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
 {
-    return SDL_SendKeyboardKeyInternal(KEYBOARD_HARDWARE, state, scancode, SDLK_UNKNOWN);
+    return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, SDLK_UNKNOWN);
 }
 
-int SDL_SendKeyboardKeyAndKeycode(Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
+int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
 {
-    return SDL_SendKeyboardKeyInternal(KEYBOARD_HARDWARE, state, scancode, keycode);
+    return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, keycode);
 }
 
-int SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode)
+int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode)
 {
-    return SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode, SDLK_UNKNOWN);
+    return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode, SDLK_UNKNOWN);
 }
 
 void SDL_ReleaseAutoReleaseKeys(void)
@@ -980,7 +981,7 @@ void SDL_ReleaseAutoReleaseKeys(void)
     if (keyboard->autorelease_pending) {
         for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
             if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) {
-                SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode, SDLK_UNKNOWN);
+                SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode, SDLK_UNKNOWN);
             }
         }
         keyboard->autorelease_pending = SDL_FALSE;
@@ -1017,7 +1018,8 @@ int SDL_SendKeyboardText(const char *text)
         SDL_Event event;
         size_t pos = 0, advance, length = SDL_strlen(text);
 
-        event.text.type = SDL_TEXTINPUT;
+        event.type = SDL_TEXTINPUT;
+        event.common.timestamp = 0;
         event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
         while (pos < length) {
             advance = SDL_utf8strlcpy(event.text.text, text + pos, SDL_arraysize(event.text.text));
@@ -1043,13 +1045,15 @@ int SDL_SendEditingText(const char *text, int start, int length)
 
         if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE) &&
             SDL_strlen(text) >= SDL_arraysize(event.text.text)) {
-            event.editExt.type = SDL_TEXTEDITING_EXT;
+            event.type = SDL_TEXTEDITING_EXT;
+            event.common.timestamp = 0;
             event.editExt.windowID = keyboard->focus ? keyboard->focus->id : 0;
             event.editExt.text = text ? SDL_strdup(text) : NULL;
             event.editExt.start = start;
             event.editExt.length = length;
         } else {
-            event.edit.type = SDL_TEXTEDITING;
+            event.type = SDL_TEXTEDITING;
+            event.common.timestamp = 0;
             event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
             event.edit.start = start;
             event.edit.length = length;

+ 4 - 4
src/events/SDL_keyboard_c.h

@@ -47,15 +47,15 @@ extern void SDL_SetKeyboardFocus(SDL_Window *window);
 /* Send a character from an on-screen keyboard as scancode and modifier key events,
    currently assuming ASCII characters on a US keyboard layout
  */
-extern int SDL_SendKeyboardUnicodeKey(Uint32 ch);
+extern int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch);
 
 /* Send a keyboard key event */
-extern int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode);
-extern int SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode);
+extern int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode);
+extern int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode);
 
 /* This is for platforms that don't know the keymap but can report scancode and keycode directly.
    Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */
-extern int SDL_SendKeyboardKeyAndKeycode(Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode);
+extern int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode);
 
 /* Release all the autorelease keys */
 extern void SDL_ReleaseAutoReleaseKeys(void);

+ 21 - 18
src/events/SDL_mouse.c

@@ -37,7 +37,7 @@ static SDL_Mouse SDL_mouse;
 /* for mapping mouse events to touch */
 static SDL_bool track_mouse_down = SDL_FALSE;
 
-static int SDL_PrivateSendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y);
+static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y);
 
 static void SDLCALL SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
 {
@@ -261,7 +261,7 @@ SDL_ResetMouse(void)
 
     for (i = 1; i <= sizeof(buttonState)*8; ++i) {
         if (buttonState & SDL_BUTTON(i)) {
-            SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, i);
+            SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, i);
         }
     }
     SDL_assert(GetButtonState(mouse, SDL_FALSE) == 0);
@@ -324,7 +324,7 @@ static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, int x, int y, Uint32 bu
             SDL_Log("Mouse left window, synthesizing move & focus lost event\n");
 #endif
             if (send_mouse_motion) {
-                SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
+                SDL_PrivateSendMouseMotion(0, window, mouse->mouseID, 0, x, y);
             }
             SDL_SetMouseFocus(NULL);
         }
@@ -337,13 +337,13 @@ static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, int x, int y, Uint32 bu
 #endif
         SDL_SetMouseFocus(window);
         if (send_mouse_motion) {
-            SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
+            SDL_PrivateSendMouseMotion(0, window, mouse->mouseID, 0, x, y);
         }
     }
     return SDL_TRUE;
 }
 
-int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
+int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
 {
     if (window && !relative) {
         SDL_Mouse *mouse = SDL_GetMouse();
@@ -352,7 +352,7 @@ int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, i
         }
     }
 
-    return SDL_PrivateSendMouseMotion(window, mouseID, relative, x, y);
+    return SDL_PrivateSendMouseMotion(timestamp, window, mouseID, relative, x, y);
 }
 
 static int GetScaledMouseDelta(float scale, int value, float *accum)
@@ -463,7 +463,7 @@ static void GetScaledMouseDeltas(SDL_Mouse *mouse, int *x, int *y)
     }
 }
 
-static int SDL_PrivateSendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
+static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
     int posted;
@@ -476,7 +476,7 @@ static int SDL_PrivateSendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, i
             if (window) {
                 float fx = (float)x / (float)window->w;
                 float fy = (float)y / (float)window->h;
-                SDL_SendTouchMotion(SDL_MOUSE_TOUCHID, 0, window, fx, fy, 1.0f);
+                SDL_SendTouchMotion(timestamp, SDL_MOUSE_TOUCHID, 0, window, fx, fy, 1.0f);
             }
         }
     }
@@ -504,7 +504,7 @@ static int SDL_PrivateSendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, i
                 if (mouse->WarpMouse) {
                     mouse->WarpMouse(window, center_x, center_y);
                 } else {
-                    SDL_PrivateSendMouseMotion(window, mouseID, 0, center_x, center_y);
+                    SDL_PrivateSendMouseMotion(timestamp, window, mouseID, 0, center_x, center_y);
                 }
             }
         }
@@ -603,7 +603,8 @@ static int SDL_PrivateSendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, i
     posted = 0;
     if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE) {
         SDL_Event event;
-        event.motion.type = SDL_MOUSEMOTION;
+        event.type = SDL_MOUSEMOTION;
+        event.common.timestamp = timestamp;
         event.motion.windowID = mouse->focus ? mouse->focus->id : 0;
         event.motion.which = mouseID;
         /* Set us pending (or clear during a normal mouse movement event) as having triggered */
@@ -668,7 +669,7 @@ static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button)
     return &mouse->clickstate[button];
 }
 
-static int SDL_PrivateSendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
+static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
     int posted;
@@ -693,7 +694,7 @@ static int SDL_PrivateSendMouseButton(SDL_Window *window, SDL_MouseID mouseID, U
             if (window) {
                 float fx = (float)mouse->x / (float)window->w;
                 float fy = (float)mouse->y / (float)window->h;
-                SDL_SendTouch(SDL_MOUSE_TOUCHID, 0, window, track_mouse_down, fx, fy, 1.0f);
+                SDL_SendTouch(timestamp, SDL_MOUSE_TOUCHID, 0, window, track_mouse_down, fx, fy, 1.0f);
             }
         }
     }
@@ -760,6 +761,7 @@ static int SDL_PrivateSendMouseButton(SDL_Window *window, SDL_MouseID mouseID, U
     if (SDL_GetEventState(type) == SDL_ENABLE) {
         SDL_Event event;
         event.type = type;
+        event.common.timestamp = timestamp;
         event.button.windowID = mouse->focus ? mouse->focus->id : 0;
         event.button.which = mouseID;
         event.button.state = state;
@@ -783,18 +785,18 @@ static int SDL_PrivateSendMouseButton(SDL_Window *window, SDL_MouseID mouseID, U
     return posted;
 }
 
-int SDL_SendMouseButtonClicks(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
+int SDL_SendMouseButtonClicks(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
 {
     clicks = SDL_max(clicks, 0);
-    return SDL_PrivateSendMouseButton(window, mouseID, state, button, clicks);
+    return SDL_PrivateSendMouseButton(timestamp, window, mouseID, state, button, clicks);
 }
 
-int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
+int SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
 {
-    return SDL_PrivateSendMouseButton(window, mouseID, state, button, -1);
+    return SDL_PrivateSendMouseButton(timestamp, window, mouseID, state, button, -1);
 }
 
-int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
+int SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
     int posted;
@@ -851,6 +853,7 @@ int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y
     if (SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_MOUSEWHEEL;
+        event.common.timestamp = timestamp;
         event.wheel.windowID = mouse->focus ? mouse->focus->id : 0;
         event.wheel.which = mouseID;
         event.wheel.x = integral_x;
@@ -1026,7 +1029,7 @@ void SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ign
         (!mouse->relative_mode || mouse->relative_mode_warp)) {
         mouse->WarpMouse(window, x, y);
     } else {
-        SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
+        SDL_PrivateSendMouseMotion(0, window, mouse->mouseID, 0, x, y);
     }
 }
 

+ 4 - 4
src/events/SDL_mouse_c.h

@@ -145,16 +145,16 @@ extern int SDL_UpdateMouseCapture(SDL_bool force_release);
 extern int SDL_SetMouseSystemScale(int num_values, const float *values);
 
 /* Send a mouse motion event */
-extern int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y);
+extern int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y);
 
 /* Send a mouse button event */
-extern int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button);
+extern int SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button);
 
 /* Send a mouse button event with a click count */
-extern int SDL_SendMouseButtonClicks(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks);
+extern int SDL_SendMouseButtonClicks(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks);
 
 /* Send a mouse wheel event */
-extern int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction);
+extern int SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction);
 
 /* Warp the mouse within the window, potentially overriding relative mode */
 extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode);

+ 14 - 12
src/events/SDL_touch.c

@@ -237,8 +237,7 @@ static int SDL_DelFinger(SDL_Touch *touch, SDL_FingerID fingerid)
     return 0;
 }
 
-int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
-                  SDL_bool down, float x, float y, float pressure)
+int SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_bool down, float x, float y, float pressure)
 {
     int posted;
     SDL_Finger *finger;
@@ -279,12 +278,12 @@ int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
                             if (pos_y > window->h - 1) {
                                 pos_y = window->h - 1;
                             }
-                            SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
-                            SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
+                            SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
+                            SDL_SendMouseButton(timestamp, window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
                         }
                     } else {
                         if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
-                            SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
+                            SDL_SendMouseButton(timestamp, window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
                         }
                     }
                 }
@@ -316,7 +315,7 @@ int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
         if (finger) {
             /* This finger is already down.
                Assume the finger-up for the previous touch was lost, and send it. */
-            SDL_SendTouch(id, fingerid, window, SDL_FALSE, x, y, pressure);
+            SDL_SendTouch(timestamp, id, fingerid, window, SDL_FALSE, x, y, pressure);
         }
 
         if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) {
@@ -326,7 +325,8 @@ int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
         posted = 0;
         if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
             SDL_Event event;
-            event.tfinger.type = SDL_FINGERDOWN;
+            event.type = SDL_FINGERDOWN;
+            event.common.timestamp = timestamp;
             event.tfinger.touchId = id;
             event.tfinger.fingerId = fingerid;
             event.tfinger.x = x;
@@ -346,7 +346,8 @@ int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
         posted = 0;
         if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
             SDL_Event event;
-            event.tfinger.type = SDL_FINGERUP;
+            event.type = SDL_FINGERUP;
+            event.common.timestamp = timestamp;
             event.tfinger.touchId = id;
             event.tfinger.fingerId = fingerid;
             /* I don't trust the coordinates passed on fingerUp */
@@ -364,7 +365,7 @@ int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
     return posted;
 }
 
-int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
+int SDL_SendTouchMotion(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
                         float x, float y, float pressure)
 {
     SDL_Touch *touch;
@@ -401,7 +402,7 @@ int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *windo
                         if (pos_y > window->h - 1) {
                             pos_y = window->h - 1;
                         }
-                        SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
+                        SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
                     }
                 }
             }
@@ -418,7 +419,7 @@ int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *windo
 
     finger = SDL_GetFinger(touch, fingerid);
     if (finger == NULL) {
-        return SDL_SendTouch(id, fingerid, window, SDL_TRUE, x, y, pressure);
+        return SDL_SendTouch(timestamp, id, fingerid, window, SDL_TRUE, x, y, pressure);
     }
 
     xrel = x - finger->x;
@@ -442,7 +443,8 @@ int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *windo
     posted = 0;
     if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
         SDL_Event event;
-        event.tfinger.type = SDL_FINGERMOTION;
+        event.type = SDL_FINGERMOTION;
+        event.common.timestamp = timestamp;
         event.tfinger.touchId = id;
         event.tfinger.fingerId = fingerid;
         event.tfinger.x = x;

+ 2 - 4
src/events/SDL_touch_c.h

@@ -43,12 +43,10 @@ extern int SDL_AddTouch(SDL_TouchID id, SDL_TouchDeviceType type, const char *na
 extern SDL_Touch *SDL_GetTouch(SDL_TouchID id);
 
 /* Send a touch down/up event for a touch */
-extern int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
-                         SDL_bool down, float x, float y, float pressure);
+extern int SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_bool down, float x, float y, float pressure);
 
 /* Send a touch motion event for a touch */
-extern int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
-                               float x, float y, float pressure);
+extern int SDL_SendTouchMotion(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure);
 
 /* Remove a touch */
 extern void SDL_DelTouch(SDL_TouchID id);

+ 1 - 0
src/events/SDL_windowevents.c

@@ -187,6 +187,7 @@ int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1,
     if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_WINDOWEVENT;
+        event.common.timestamp = 0;
         event.window.event = windowevent;
         event.window.data1 = data1;
         event.window.data2 = data2;

+ 8 - 0
src/joystick/SDL_gamecontroller.c

@@ -405,7 +405,9 @@ static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event *eve
     {
         if (SDL_IsGameController(event->jdevice.which)) {
             SDL_Event deviceevent;
+
             deviceevent.type = SDL_CONTROLLERDEVICEADDED;
+            deviceevent.common.timestamp = 0;
             deviceevent.cdevice.which = event->jdevice.which;
             SDL_PushEvent(&deviceevent);
         }
@@ -426,6 +428,7 @@ static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event *eve
             SDL_Event deviceevent;
 
             deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
+            deviceevent.common.timestamp = 0;
             deviceevent.cdevice.which = event->jdevice.which;
             SDL_PushEvent(&deviceevent);
         }
@@ -1189,7 +1192,9 @@ static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pContro
 
             {
                 SDL_Event event;
+
                 event.type = SDL_CONTROLLERDEVICEREMAPPED;
+                event.common.timestamp = 0;
                 event.cdevice.which = gamecontrollerlist->joystick->instance_id;
                 SDL_PushEvent(&event);
             }
@@ -1834,6 +1839,7 @@ int SDL_GameControllerInit(void)
         if (SDL_IsGameController(i)) {
             SDL_Event deviceevent;
             deviceevent.type = SDL_CONTROLLERDEVICEADDED;
+            deviceevent.common.timestamp = 0;
             deviceevent.cdevice.which = i;
             SDL_PushEvent(&deviceevent);
         }
@@ -2863,6 +2869,7 @@ static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL
     if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_CONTROLLERAXISMOTION;
+        event.common.timestamp = 0;
         event.caxis.which = gamecontroller->joystick->instance_id;
         event.caxis.axis = axis;
         event.caxis.value = value;
@@ -2898,6 +2905,7 @@ static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, S
         /* Invalid state -- bail */
         return 0;
     }
+    event.common.timestamp = 0;
 #endif /* !SDL_EVENTS_DISABLED */
 
     if (button == SDL_CONTROLLER_BUTTON_GUIDE) {

+ 11 - 3
src/joystick/SDL_joystick.c

@@ -1307,6 +1307,7 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
         SDL_Event event;
 
         event.type = SDL_JOYDEVICEADDED;
+        event.common.timestamp = 0;
 
         if (SDL_GetEventState(event.type) == SDL_ENABLE) {
             event.jdevice.which = device_index;
@@ -1430,8 +1431,8 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
     }
 
 #if !SDL_EVENTS_DISABLED
-    SDL_zero(event);
     event.type = SDL_JOYDEVICEREMOVED;
+    event.common.timestamp = 0;
 
     if (SDL_GetEventState(event.type) == SDL_ENABLE) {
         event.jdevice.which = device_instance;
@@ -1507,6 +1508,7 @@ int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
     if (SDL_GetEventState(SDL_JOYAXISMOTION) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_JOYAXISMOTION;
+        event.common.timestamp = 0;
         event.jaxis.which = joystick->instance_id;
         event.jaxis.axis = axis;
         event.jaxis.value = value;
@@ -1549,7 +1551,8 @@ int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
 #if !SDL_EVENTS_DISABLED
     if (SDL_GetEventState(SDL_JOYHATMOTION) == SDL_ENABLE) {
         SDL_Event event;
-        event.jhat.type = SDL_JOYHATMOTION;
+        event.type = SDL_JOYHATMOTION;
+        event.common.timestamp = 0;
         event.jhat.which = joystick->instance_id;
         event.jhat.hat = hat;
         event.jhat.value = value;
@@ -1587,7 +1590,8 @@ int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball,
 #if !SDL_EVENTS_DISABLED
     if (SDL_GetEventState(SDL_JOYBALLMOTION) == SDL_ENABLE) {
         SDL_Event event;
-        event.jball.type = SDL_JOYBALLMOTION;
+        event.type = SDL_JOYBALLMOTION;
+        event.common.timestamp = 0;
         event.jball.which = joystick->instance_id;
         event.jball.ball = ball;
         event.jball.xrel = xrel;
@@ -1617,6 +1621,7 @@ int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
         /* Invalid state -- bail */
         return 0;
     }
+    event.common.timestamp = 0;
 #endif /* !SDL_EVENTS_DISABLED */
 
     SDL_AssertJoysticksLocked();
@@ -2843,6 +2848,7 @@ void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLe
         if (SDL_GetEventState(SDL_JOYBATTERYUPDATED) == SDL_ENABLE) {
             SDL_Event event;
             event.type = SDL_JOYBATTERYUPDATED;
+            event.common.timestamp = 0;
             event.jbattery.which = joystick->instance_id;
             event.jbattery.level = ePowerLevel;
             SDL_PushEvent(&event);
@@ -2938,6 +2944,7 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
     if (SDL_GetEventState(event_type) == SDL_ENABLE) {
         SDL_Event event;
         event.type = event_type;
+        event.common.timestamp = 0;
         event.ctouchpad.which = joystick->instance_id;
         event.ctouchpad.touchpad = touchpad;
         event.ctouchpad.finger = finger;
@@ -2978,6 +2985,7 @@ int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, Uint6
                 if (SDL_GetEventState(SDL_CONTROLLERSENSORUPDATE) == SDL_ENABLE) {
                     SDL_Event event;
                     event.type = SDL_CONTROLLERSENSORUPDATE;
+                    event.common.timestamp = 0;
                     event.csensor.which = joystick->instance_id;
                     event.csensor.sensor = type;
                     num_values = SDL_min(num_values, SDL_arraysize(event.csensor.data));

+ 2 - 2
src/joystick/android/SDL_sysjoystick.c

@@ -204,7 +204,7 @@ int Android_OnPadDown(int device_id, int keycode)
         if (item && item->joystick) {
             SDL_PrivateJoystickButton(item->joystick, button, SDL_PRESSED);
         } else {
-            SDL_SendKeyboardKey(SDL_PRESSED, button_to_scancode(button));
+            SDL_SendKeyboardKey(0, SDL_PRESSED, button_to_scancode(button));
         }
         SDL_UnlockJoysticks();
         return 0;
@@ -223,7 +223,7 @@ int Android_OnPadUp(int device_id, int keycode)
         if (item && item->joystick) {
             SDL_PrivateJoystickButton(item->joystick, button, SDL_RELEASED);
         } else {
-            SDL_SendKeyboardKey(SDL_RELEASED, button_to_scancode(button));
+            SDL_SendKeyboardKey(0, SDL_RELEASED, button_to_scancode(button));
         }
         SDL_UnlockJoysticks();
         return 0;

+ 5 - 5
src/main/haiku/SDL_BApp.h

@@ -254,12 +254,12 @@ class SDL_BApp : public BApplication
             SDL_GetWindowPosition(win, &winPosX, &winPosY);
             int dx = x - (winWidth / 2);
             int dy = y - (winHeight / 2);
-            SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy);
+            SDL_SendMouseMotion(0, win, 0, SDL_GetMouse()->relative_mode, dx, dy);
             set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2));
             if (!be_app->IsCursorHidden())
                 be_app->HideCursor();
         } else {
-            SDL_SendMouseMotion(win, 0, 0, x, y);
+            SDL_SendMouseMotion(0, win, 0, 0, x, y);
             if (SDL_ShowCursor(-1) && be_app->IsCursorHidden())
                 be_app->ShowCursor();
         }
@@ -277,7 +277,7 @@ class SDL_BApp : public BApplication
             return;
         }
         win = GetSDLWindow(winID);
-        SDL_SendMouseButton(win, 0, state, button);
+        SDL_SendMouseButton(0, win, 0, state, button);
     }
 
     void _HandleMouseWheel(BMessage *msg)
@@ -292,7 +292,7 @@ class SDL_BApp : public BApplication
             return;
         }
         win = GetSDLWindow(winID);
-        SDL_SendMouseWheel(win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
+        SDL_SendMouseWheel(0, win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
     }
 
     void _HandleKey(BMessage *msg)
@@ -309,7 +309,7 @@ class SDL_BApp : public BApplication
             return;
         }
         HAIKU_SetKeyState(scancode, state);
-        SDL_SendKeyboardKey(state, HAIKU_GetScancodeFromBeKey(scancode));
+        SDL_SendKeyboardKey(0, state, HAIKU_GetScancodeFromBeKey(scancode));
 
         if (state == SDL_PRESSED && SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
             const int8 *keyUtf8;

+ 1 - 0
src/render/direct3d/SDL_render_d3d.c

@@ -1520,6 +1520,7 @@ static int D3D_Reset(SDL_Renderer *renderer)
     {
         SDL_Event event;
         event.type = SDL_RENDER_TARGETS_RESET;
+        event.common.timestamp = 0;
         SDL_PushEvent(&event);
     }
 

+ 1 - 0
src/render/direct3d11/SDL_render_d3d11.c

@@ -875,6 +875,7 @@ D3D11_HandleDeviceLost(SDL_Renderer *renderer)
     {
         SDL_Event event;
         event.type = SDL_RENDER_DEVICE_RESET;
+        event.common.timestamp = 0;
         SDL_PushEvent(&event);
     }
 

+ 1 - 0
src/render/direct3d12/SDL_render_d3d12.c

@@ -1233,6 +1233,7 @@ D3D12_HandleDeviceLost(SDL_Renderer *renderer)
     {
         SDL_Event event;
         event.type = SDL_RENDER_DEVICE_RESET;
+        event.common.timestamp = 0;
         SDL_PushEvent(&event);
     }
 

+ 1 - 0
src/sensor/SDL_sensor.c

@@ -492,6 +492,7 @@ int SDL_PrivateSensorUpdate(SDL_Sensor *sensor, Uint64 timestamp_us, float *data
     if (SDL_GetEventState(SDL_SENSORUPDATE) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_SENSORUPDATE;
+        event.common.timestamp = 0;
         event.sensor.which = sensor->instance_id;
         num_values = SDL_min(num_values, SDL_arraysize(event.sensor.data));
         SDL_memset(event.sensor.data, 0, sizeof(event.sensor.data));

+ 1 - 0
src/video/android/SDL_androidevents.c

@@ -78,6 +78,7 @@ static void android_egl_context_restore(SDL_Window *window)
             data->egl_context = (EGLContext)SDL_GL_CreateContext(window);
             SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context);
             event.type = SDL_RENDER_DEVICE_RESET;
+            event.common.timestamp = 0;
             SDL_PushEvent(&event);
         }
         data->backup_done = 0;

+ 2 - 2
src/video/android/SDL_androidkeyboard.c

@@ -328,12 +328,12 @@ static SDL_Scancode TranslateKeycode(int keycode)
 
 int Android_OnKeyDown(int keycode)
 {
-    return SDL_SendKeyboardKey(SDL_PRESSED, TranslateKeycode(keycode));
+    return SDL_SendKeyboardKey(0, SDL_PRESSED, TranslateKeycode(keycode));
 }
 
 int Android_OnKeyUp(int keycode)
 {
-    return SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode(keycode));
+    return SDL_SendKeyboardKey(0, SDL_RELEASED, TranslateKeycode(keycode));
 }
 
 SDL_bool

+ 6 - 6
src/video/android/SDL_androidmouse.c

@@ -224,25 +224,25 @@ void Android_OnMouse(SDL_Window *window, int state, int action, float x, float y
         changes = state & ~last_state;
         button = TranslateButton(changes);
         last_state = state;
-        SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y);
-        SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
+        SDL_SendMouseMotion(0, window, 0, relative, (int)x, (int)y);
+        SDL_SendMouseButton(0, window, 0, SDL_PRESSED, button);
         break;
 
     case ACTION_UP:
         changes = last_state & ~state;
         button = TranslateButton(changes);
         last_state = state;
-        SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y);
-        SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
+        SDL_SendMouseMotion(0, window, 0, relative, (int)x, (int)y);
+        SDL_SendMouseButton(0, window, 0, SDL_RELEASED, button);
         break;
 
     case ACTION_MOVE:
     case ACTION_HOVER_MOVE:
-        SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y);
+        SDL_SendMouseMotion(0, window, 0, relative, (int)x, (int)y);
         break;
 
     case ACTION_SCROLL:
-        SDL_SendMouseWheel(window, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
+        SDL_SendMouseWheel(0, window, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
         break;
 
     default:

+ 3 - 3
src/video/android/SDL_androidtouch.c

@@ -65,16 +65,16 @@ void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_fin
     switch (action) {
     case ACTION_DOWN:
     case ACTION_POINTER_DOWN:
-        SDL_SendTouch(touchDeviceId, fingerId, window, SDL_TRUE, x, y, p);
+        SDL_SendTouch(0, touchDeviceId, fingerId, window, SDL_TRUE, x, y, p);
         break;
 
     case ACTION_MOVE:
-        SDL_SendTouchMotion(touchDeviceId, fingerId, window, x, y, p);
+        SDL_SendTouchMotion(0, touchDeviceId, fingerId, window, x, y, p);
         break;
 
     case ACTION_UP:
     case ACTION_POINTER_UP:
-        SDL_SendTouch(touchDeviceId, fingerId, window, SDL_FALSE, x, y, p);
+        SDL_SendTouch(0, touchDeviceId, fingerId, window, SDL_FALSE, x, y, p);
         break;
 
     default:

+ 1 - 0
src/video/cocoa/SDL_cocoaevents.h

@@ -24,6 +24,7 @@
 #define SDL_cocoaevents_h_
 
 extern void Cocoa_RegisterApp(void);
+extern Uint64 Cocoa_GetEventTimestamp(NSTimeInterval nsTimestamp);
 extern void Cocoa_PumpEvents(_THIS);
 extern int Cocoa_WaitEventTimeout(_THIS, Sint64 timeoutNS);
 extern void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window);

+ 18 - 0
src/video/cocoa/SDL_cocoaevents.m

@@ -502,6 +502,24 @@ void Cocoa_RegisterApp(void)
     }
 }
 
+Uint64 Cocoa_GetEventTimestamp(NSTimeInterval nsTimestamp)
+{
+    static Uint64 timestamp_offset;
+    Uint64 timestamp = (Uint64)(nsTimestamp * SDL_NS_PER_SECOND);
+    Uint64 now = SDL_GetTicksNS();
+
+    if (!timestamp_offset) {
+        timestamp_offset = (now - timestamp);
+    }
+    timestamp += timestamp_offset;
+
+    if (timestamp > now) {
+        timestamp_offset -= (timestamp - now);
+        timestamp = now;
+    }
+    return timestamp;
+}
+
 int Cocoa_PumpEventsUntilDate(_THIS, NSDate *expiration, bool accumulate)
 {
     for (;;) {

+ 4 - 4
src/video/cocoa/SDL_cocoakeyboard.m

@@ -220,9 +220,9 @@ static void HandleModifiers(_THIS, unsigned short scancode, unsigned int modifie
     for (int i = 0; i < 12; i++) {
         if (code == codes[i]) {
             if (modifierFlags & modifiers[i]) {
-                SDL_SendKeyboardKey(SDL_PRESSED, code);
+                SDL_SendKeyboardKey(0, SDL_PRESSED, code);
             } else {
-                SDL_SendKeyboardKey(SDL_RELEASED, code);
+                SDL_SendKeyboardKey(0, SDL_RELEASED, code);
             }
         }
     }
@@ -399,7 +399,7 @@ void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
             UpdateKeymap(data, SDL_TRUE);
         }
 
-        SDL_SendKeyboardKey(SDL_PRESSED, code);
+        SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), SDL_PRESSED, code);
 #ifdef DEBUG_SCANCODES
         if (code == SDL_SCANCODE_UNKNOWN) {
             SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list <https://discourse.libsdl.org/> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
@@ -418,7 +418,7 @@ void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
         }
         break;
     case NSEventTypeKeyUp:
-        SDL_SendKeyboardKey(SDL_RELEASED, code);
+        SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), SDL_RELEASED, code);
         break;
     case NSEventTypeFlagsChanged:
         HandleModifiers(_this, scancode, (unsigned int)[event modifierFlags]);

+ 3 - 3
src/video/cocoa/SDL_cocoamouse.m

@@ -278,7 +278,7 @@ static int Cocoa_WarpMouseGlobal(int x, int y)
         SDL_SetMouseFocus(win);
         if (win) {
             SDL_assert(win == mouse->focus);
-            SDL_SendMouseMotion(win, mouse->mouseID, 0, x - win->x, y - win->y);
+            SDL_SendMouseMotion(0, win, mouse->mouseID, 0, x - win->x, y - win->y);
         }
     }
 
@@ -495,7 +495,7 @@ void Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
         DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], deltaX, deltaY);
     }
 
-    SDL_SendMouseMotion(mouse->focus, mouseID, 1, (int)deltaX, (int)deltaY);
+    SDL_SendMouseMotion(Cocoa_GetEventTimestamp([event timestamp]), mouse->focus, mouseID, 1, (int)deltaX, (int)deltaY);
 }
 
 void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
@@ -532,7 +532,7 @@ void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
         }
     }
 
-    SDL_SendMouseWheel(window, mouseID, x, y, direction);
+    SDL_SendMouseWheel(Cocoa_GetEventTimestamp([event timestamp]), window, mouseID, x, y, direction);
 }
 
 void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y)

+ 11 - 11
src/video/cocoa/SDL_cocoawindow.m

@@ -190,7 +190,7 @@
         x = (int)point.x;
         y = (int)(sdlwindow->h - point.y);
         if (x >= 0 && x < sdlwindow->w && y >= 0 && y < sdlwindow->h) {
-            SDL_SendMouseMotion(sdlwindow, mouse->mouseID, 0, x, y);
+            SDL_SendMouseMotion(0, sdlwindow, mouse->mouseID, 0, x, y);
         }
         /* Code addon to update the mouse location */
 
@@ -855,7 +855,7 @@ static void Cocoa_UpdateClipCursor(SDL_Window *window)
         y = (int)(window->h - point.y);
 
         if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
-            SDL_SendMouseMotion(window, mouse->mouseID, 0, x, y);
+            SDL_SendMouseMotion(0, window, mouse->mouseID, 0, x, y);
         }
     }
 
@@ -1133,8 +1133,8 @@ static void Cocoa_UpdateClipCursor(SDL_Window *window)
     const SDL_bool osenabled = ([theEvent modifierFlags] & NSEventModifierFlagCapsLock) ? SDL_TRUE : SDL_FALSE;
     const SDL_bool sdlenabled = (SDL_GetModState() & KMOD_CAPS) ? SDL_TRUE : SDL_FALSE;
     if (osenabled ^ sdlenabled) {
-        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
-        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
+        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
+        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
     }
 }
 - (void)keyDown:(NSEvent *)theEvent
@@ -1193,14 +1193,14 @@ static int Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_
     //  event for the background window, this just makes sure the button is reported at the
     //  correct position in its own event.
     if (focus && ([theEvent window] == ((__bridge SDL_WindowData *)focus->driverdata).nswindow)) {
-        rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks);
+        rc = SDL_SendMouseButtonClicks(Cocoa_GetEventTimestamp([theEvent timestamp]), window, mouseID, state, button, clicks);
     } else {
         const int orig_x = mouse->x;
         const int orig_y = mouse->y;
         const NSPoint point = [theEvent locationInWindow];
         mouse->x = (int)point.x;
         mouse->y = (int)(window->h - point.y);
-        rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks);
+        rc = SDL_SendMouseButtonClicks(Cocoa_GetEventTimestamp([theEvent timestamp]), window, mouseID, state, button, clicks);
         mouse->x = orig_x;
         mouse->y = orig_y;
     }
@@ -1352,7 +1352,7 @@ static int Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_
         }
     }
 
-    SDL_SendMouseMotion(window, mouseID, 0, x, y);
+    SDL_SendMouseMotion(Cocoa_GetEventTimestamp([theEvent timestamp]), window, mouseID, 0, x, y);
 }
 
 - (void)mouseDragged:(NSEvent *)theEvent
@@ -1428,7 +1428,7 @@ static int Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_
              * events from being generated from touch events.
              */
             SDL_Window *window = NULL;
-            SDL_SendTouch(touchID, finger->id, window, SDL_FALSE, 0, 0, 0);
+            SDL_SendTouch(Cocoa_GetEventTimestamp([theEvent timestamp]), touchID, finger->id, window, SDL_FALSE, 0, 0, 0);
         }
     }
 
@@ -1496,14 +1496,14 @@ static int Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_
 
         switch (phase) {
         case NSTouchPhaseBegan:
-            SDL_SendTouch(touchId, fingerId, window, SDL_TRUE, x, y, 1.0f);
+            SDL_SendTouch(Cocoa_GetEventTimestamp([theEvent timestamp]), touchId, fingerId, window, SDL_TRUE, x, y, 1.0f);
             break;
         case NSTouchPhaseEnded:
         case NSTouchPhaseCancelled:
-            SDL_SendTouch(touchId, fingerId, window, SDL_FALSE, x, y, 1.0f);
+            SDL_SendTouch(Cocoa_GetEventTimestamp([theEvent timestamp]), touchId, fingerId, window, SDL_FALSE, x, y, 1.0f);
             break;
         case NSTouchPhaseMoved:
-            SDL_SendTouchMotion(touchId, fingerId, window, x, y, 1.0f);
+            SDL_SendTouchMotion(Cocoa_GetEventTimestamp([theEvent timestamp]), touchId, fingerId, window, x, y, 1.0f);
             break;
         default:
             break;

+ 8 - 8
src/video/emscripten/SDL_emscriptenevents.c

@@ -635,7 +635,7 @@ static EM_BOOL Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEv
         my = mouseEvent->targetY * yscale;
     }
 
-    SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
+    SDL_SendMouseMotion(0, window_data->window, 0, isPointerLocked, mx, my);
     return 0;
 }
 
@@ -671,7 +671,7 @@ static EM_BOOL Emscripten_HandleMouseButton(int eventType, const EmscriptenMouse
         sdl_button_state = SDL_RELEASED;
         sdl_event_type = SDL_MOUSEBUTTONUP;
     }
-    SDL_SendMouseButton(window_data->window, 0, sdl_button_state, sdl_button);
+    SDL_SendMouseButton(0, window_data->window, 0, sdl_button_state, sdl_button);
 
     /* Do not consume the event if the mouse is outside of the canvas. */
     emscripten_get_element_css_size(window_data->canvas_id, &css_w, &css_h);
@@ -697,7 +697,7 @@ static EM_BOOL Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseE
 
         mx = mx * (window_data->window->w / client_w);
         my = my * (window_data->window->h / client_h);
-        SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
+        SDL_SendMouseMotion(0, window_data->window, 0, isPointerLocked, mx, my);
     }
 
     SDL_SetMouseFocus(eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? window_data->window : NULL);
@@ -722,7 +722,7 @@ static EM_BOOL Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent
         break;
     }
 
-    SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, -deltaY, SDL_MOUSEWHEEL_NORMAL);
+    SDL_SendMouseWheel(0, window_data->window, 0, (float)wheelEvent->deltaX, -deltaY, SDL_MOUSEWHEEL_NORMAL);
     return SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE;
 }
 
@@ -766,16 +766,16 @@ static EM_BOOL Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent
         y = touchEvent->touches[i].targetY / client_h;
 
         if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) {
-            SDL_SendTouch(deviceId, id, window_data->window, SDL_TRUE, x, y, 1.0f);
+            SDL_SendTouch(0, deviceId, id, window_data->window, SDL_TRUE, x, y, 1.0f);
 
             /* disable browser scrolling/pinch-to-zoom if app handles touch events */
             if (!preventDefault && SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
                 preventDefault = 1;
             }
         } else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) {
-            SDL_SendTouchMotion(deviceId, id, window_data->window, x, y, 1.0f);
+            SDL_SendTouchMotion(0, deviceId, id, window_data->window, x, y, 1.0f);
         } else {
-            SDL_SendTouch(deviceId, id, window_data->window, SDL_FALSE, x, y, 1.0f);
+            SDL_SendTouch(0, deviceId, id, window_data->window, SDL_FALSE, x, y, 1.0f);
 
             /* block browser's simulated mousedown/mouseup on touchscreen devices */
             preventDefault = 1;
@@ -802,7 +802,7 @@ static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent
     }
 
     if (scancode != SDL_SCANCODE_UNKNOWN) {
-        SDL_SendKeyboardKeyAndKeycode(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode, keycode);
+        SDL_SendKeyboardKeyAndKeycode(0, eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode, keycode);
     }
 
     /* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress

+ 5 - 5
src/video/haiku/SDL_BApp.h

@@ -254,12 +254,12 @@ class SDL_BApp : public BApplication
             SDL_GetWindowPosition(win, &winPosX, &winPosY);
             int dx = x - (winWidth / 2);
             int dy = y - (winHeight / 2);
-            SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy);
+            SDL_SendMouseMotion(0, win, 0, SDL_GetMouse()->relative_mode, dx, dy);
             set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2));
             if (!be_app->IsCursorHidden())
                 be_app->HideCursor();
         } else {
-            SDL_SendMouseMotion(win, 0, 0, x, y);
+            SDL_SendMouseMotion(0, win, 0, 0, x, y);
             if (SDL_ShowCursor(-1) && be_app->IsCursorHidden())
                 be_app->ShowCursor();
         }
@@ -277,7 +277,7 @@ class SDL_BApp : public BApplication
             return;
         }
         win = GetSDLWindow(winID);
-        SDL_SendMouseButton(win, 0, state, button);
+        SDL_SendMouseButton(0, win, 0, state, button);
     }
 
     void _HandleMouseWheel(BMessage *msg)
@@ -292,7 +292,7 @@ class SDL_BApp : public BApplication
             return;
         }
         win = GetSDLWindow(winID);
-        SDL_SendMouseWheel(win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
+        SDL_SendMouseWheel(0, win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
     }
 
     void _HandleKey(BMessage *msg)
@@ -309,7 +309,7 @@ class SDL_BApp : public BApplication
             return;
         }
         HAIKU_SetKeyState(scancode, state);
-        SDL_SendKeyboardKey(state, HAIKU_GetScancodeFromBeKey(scancode));
+        SDL_SendKeyboardKey(0, state, HAIKU_GetScancodeFromBeKey(scancode));
 
         if (state == SDL_PRESSED && SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
             const int8 *keyUtf8;

+ 1 - 1
src/video/kmsdrm/SDL_kmsdrmmouse.c

@@ -372,7 +372,7 @@ static int KMSDRM_WarpMouseGlobal(int x, int y)
         SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata;
 
         /* Update internal mouse position. */
-        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
+        SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 0, x, y);
 
         /* And now update the cursor graphic position on screen. */
         if (dispdata->cursor_bo) {

+ 1 - 0
src/video/n3ds/SDL_n3dsevents.c

@@ -36,6 +36,7 @@ void N3DS_PumpEvents(_THIS)
     if (!aptMainLoop()) {
         SDL_Event ev;
         ev.type = SDL_QUIT;
+        ev.common.timestamp = 0;
         SDL_PushEvent(&ev);
         return;
     }

+ 2 - 2
src/video/n3ds/SDL_n3dstouch.c

@@ -59,7 +59,7 @@ void N3DS_PollTouch(void)
 
     if (pressed != was_pressed) {
         was_pressed = pressed;
-        SDL_SendTouch(N3DS_TOUCH_ID,
+        SDL_SendTouch(0, N3DS_TOUCH_ID,
                       0,
                       NULL,
                       pressed,
@@ -67,7 +67,7 @@ void N3DS_PollTouch(void)
                       touch.py * TOUCHSCREEN_SCALE_Y,
                       pressed ? 1.0f : 0.0f);
     } else if (pressed) {
-        SDL_SendTouchMotion(N3DS_TOUCH_ID,
+        SDL_SendTouchMotion(0, N3DS_TOUCH_ID,
                             0,
                             NULL,
                             touch.px * TOUCHSCREEN_SCALE_X,

+ 2 - 2
src/video/ngage/SDL_ngageevents.cpp

@@ -154,10 +154,10 @@ int HandleWsEvent(_THIS, const TWsEvent &aWsEvent)
 
     switch (aWsEvent.Type()) {
     case EEventKeyDown: /* Key events */
-        SDL_SendKeyboardKey(SDL_PRESSED, ConvertScancode(_this, aWsEvent.Key()->iScanCode));
+        SDL_SendKeyboardKey(0, SDL_PRESSED, ConvertScancode(_this, aWsEvent.Key()->iScanCode));
         break;
     case EEventKeyUp: /* Key events */
-        SDL_SendKeyboardKey(SDL_RELEASED, ConvertScancode(_this, aWsEvent.Key()->iScanCode));
+        SDL_SendKeyboardKey(0, SDL_RELEASED, ConvertScancode(_this, aWsEvent.Key()->iScanCode));
         break;
     case EEventFocusGained: /* SDL window got focus */
         phdata->NGAGE_IsWindowFocused = ETrue;

+ 2 - 2
src/video/psp/SDL_pspevents.c

@@ -90,7 +90,7 @@ void PSP_PumpEvents(_THIS)
     if (changed) {
         for (i = 0; i < sizeof(keymap_psp) / sizeof(keymap_psp[0]); i++) {
             if (changed & keymap_psp[i].id) {
-                SDL_SendKeyboardKey((keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap_psp[i].sym));
+                SDL_SendKeyboardKey(0, (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap_psp[i].sym));
             }
         }
     }
@@ -113,7 +113,7 @@ void PSP_PumpEvents(_THIS)
                     sym.sym = keymap[raw];
                     /* not tested */
                     /* SDL_PrivateKeyboard(pressed?SDL_PRESSED:SDL_RELEASED, &sym); */
-                    SDL_SendKeyboardKey((keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap[raw]));
+                    SDL_SendKeyboardKey(0, (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap[raw]));
                 }
             }
         }

+ 1 - 1
src/video/raspberry/SDL_rpimouse.c

@@ -244,7 +244,7 @@ static int RPI_WarpMouseGlobal(int x, int y)
     }
 
     /* Update internal mouse position. */
-    SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
+    SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 0, x, y);
 
     curdata = (RPI_CursorData *)mouse->cur_cursor->driverdata;
     if (curdata->element == DISPMANX_NO_HANDLE) {

+ 4 - 4
src/video/riscos/SDL_riscosevents.c

@@ -58,7 +58,7 @@ void RISCOS_PollKeyboard(_THIS)
     for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {
         if (driverdata->key_pressed[i] != 255) {
             if ((_kernel_osbyte(129, driverdata->key_pressed[i] ^ 0xff, 0xff) & 0xff) != 255) {
-                SDL_SendKeyboardKey(SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i]));
+                SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i]));
                 driverdata->key_pressed[i] = 255;
             }
         }
@@ -81,7 +81,7 @@ void RISCOS_PollKeyboard(_THIS)
             break;
 
         default:
-            SDL_SendKeyboardKey(SDL_PRESSED, SDL_RISCOS_translate_keycode(key));
+            SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_RISCOS_translate_keycode(key));
 
             /* Record the press so we can detect release later. */
             for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {
@@ -126,12 +126,12 @@ void RISCOS_PollMouse(_THIS)
     buttons = regs.r[2];
 
     if (mouse->x != x || mouse->y != y) {
-        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
+        SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 0, x, y);
     }
 
     if (driverdata->last_mouse_buttons != buttons) {
         for (i = 0; i < SDL_arraysize(mouse_button_map); i++) {
-            SDL_SendMouseButton(mouse->focus, mouse->mouseID, (buttons & (1 << i)) ? SDL_PRESSED : SDL_RELEASED, mouse_button_map[i]);
+            SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, (buttons & (1 << i)) ? SDL_PRESSED : SDL_RELEASED, mouse_button_map[i]);
         }
         driverdata->last_mouse_buttons = buttons;
     }

+ 3 - 0
src/video/uikit/SDL_uikitevents.h

@@ -21,8 +21,11 @@
 #ifndef SDL_uikitevents_h_
 #define SDL_uikitevents_h_
 
+#import <UIKit/UIKit.h>
+
 #include "../SDL_sysvideo.h"
 
+extern Uint64 UIKit_GetEventTimestamp(NSTimeInterval nsTimestamp);
 extern void UIKit_PumpEvents(_THIS);
 
 extern void SDL_InitGCKeyboard(void);

+ 22 - 4
src/video/uikit/SDL_uikitevents.m

@@ -108,6 +108,24 @@ static BOOL UIKit_EventPumpEnabled = YES;
 
 @end
 
+Uint64 UIKit_GetEventTimestamp(NSTimeInterval nsTimestamp)
+{
+    static Uint64 timestamp_offset;
+    Uint64 timestamp = (Uint64)(nsTimestamp * SDL_NS_PER_SECOND);
+    Uint64 now = SDL_GetTicksNS();
+
+    if (!timestamp_offset) {
+        timestamp_offset = (now - timestamp);
+    }
+    timestamp += timestamp_offset;
+
+    if (timestamp > now) {
+        timestamp_offset -= (timestamp - now);
+        timestamp = now;
+    }
+    return timestamp;
+}
+
 void SDL_iPhoneSetEventPump(SDL_bool enabled)
 {
     UIKit_EventPumpEnabled = enabled;
@@ -161,7 +179,7 @@ static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0
 {
     keyboard_connected = SDL_TRUE;
     keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) {
-      SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode);
+      SDL_SendKeyboardKey(0, pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode);
     };
 
     dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL);
@@ -275,7 +293,7 @@ static int SetGCMouseRelativeMode(SDL_bool enabled)
 
 static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL pressed)
 {
-    SDL_SendMouseButton(SDL_GetMouseFocus(), mouseID, pressed ? SDL_PRESSED : SDL_RELEASED, button);
+    SDL_SendMouseButton(0, SDL_GetMouseFocus(), mouseID, pressed ? SDL_PRESSED : SDL_RELEASED, button);
 }
 
 static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
@@ -302,12 +320,12 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
 
     mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouseInput, float deltaX, float deltaY) {
       if (SDL_GCMouseRelativeMode()) {
-          SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, 1, (int)deltaX, -(int)deltaY);
+          SDL_SendMouseMotion(0, SDL_GetMouseFocus(), mouseID, 1, (int)deltaX, -(int)deltaY);
       }
     };
 
     mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) {
-      SDL_SendMouseWheel(SDL_GetMouseFocus(), 0, xValue, yValue, SDL_MOUSEWHEEL_NORMAL);
+      SDL_SendMouseWheel(0, SDL_GetMouseFocus(), 0, xValue, yValue, SDL_MOUSEWHEEL_NORMAL);
     };
 
     dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL);

+ 16 - 13
src/video/uikit/SDL_uikitview.m

@@ -158,7 +158,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
         point.x -= origin.x;
         point.y -= origin.y;
 
-        SDL_SendMouseMotion(sdlwindow, 0, 0, (int)point.x, (int)point.y);
+        SDL_SendMouseMotion(0, sdlwindow, 0, 0, (int)point.x, (int)point.y);
     }
     return [UIPointerRegion regionWithRect:self.bounds identifier:nil];
 }
@@ -250,7 +250,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
                                 button = (Uint8)i;
                                 break;
                             }
-                            SDL_SendMouseButton(sdlwindow, 0, SDL_PRESSED, button);
+                            SDL_SendMouseButton(UIKit_GetEventTimestamp([event timestamp]), sdlwindow, 0, SDL_PRESSED, button);
                         }
                     }
                 }
@@ -270,7 +270,8 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
             /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */
 
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
-            SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
+            SDL_SendTouch(UIKit_GetEventTimestamp([event timestamp]),
+                          touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
                           SDL_TRUE, locationInView.x, locationInView.y, pressure);
         }
     }
@@ -305,7 +306,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
                                 button = (Uint8)i;
                                 break;
                             }
-                            SDL_SendMouseButton(sdlwindow, 0, SDL_RELEASED, button);
+                            SDL_SendMouseButton(UIKit_GetEventTimestamp([event timestamp]), sdlwindow, 0, SDL_RELEASED, button);
                         }
                     }
                 }
@@ -325,7 +326,8 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
             /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */
 
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
-            SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
+            SDL_SendTouch(UIKit_GetEventTimestamp([event timestamp]),
+                          touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
                           SDL_FALSE, locationInView.x, locationInView.y, pressure);
         }
     }
@@ -359,7 +361,8 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
             }
 
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
-            SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
+            SDL_SendTouchMotion(UIKit_GetEventTimestamp([event timestamp]),
+                                touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
                                 locationInView.x, locationInView.y, pressure);
         }
     }
@@ -411,7 +414,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
     if (!SDL_HasGCKeyboard()) {
         for (UIPress *press in presses) {
             SDL_Scancode scancode = [self scancodeFromPress:press];
-            SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+            SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_PRESSED, scancode);
         }
     }
     [super pressesBegan:presses withEvent:event];
@@ -422,7 +425,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
     if (!SDL_HasGCKeyboard()) {
         for (UIPress *press in presses) {
             SDL_Scancode scancode = [self scancodeFromPress:press];
-            SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+            SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_RELEASED, scancode);
         }
     }
     [super pressesEnded:presses withEvent:event];
@@ -433,7 +436,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
     if (!SDL_HasGCKeyboard()) {
         for (UIPress *press in presses) {
             SDL_Scancode scancode = [self scancodeFromPress:press];
-            SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+            SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_RELEASED, scancode);
         }
     }
     [super pressesCancelled:presses withEvent:event];
@@ -458,16 +461,16 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
              * which better maps to swipe gestures. */
             switch (gesture.direction) {
             case UISwipeGestureRecognizerDirectionUp:
-                SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_UP);
+                SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_UP);
                 break;
             case UISwipeGestureRecognizerDirectionDown:
-                SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_DOWN);
+                SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_DOWN);
                 break;
             case UISwipeGestureRecognizerDirectionLeft:
-                SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_LEFT);
+                SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_LEFT);
                 break;
             case UISwipeGestureRecognizerDirectionRight:
-                SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RIGHT);
+                SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RIGHT);
                 break;
             }
         }

+ 5 - 5
src/video/uikit/SDL_uikitviewcontroller.m

@@ -313,7 +313,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
     }
 
     if (scancode != SDL_SCANCODE_UNKNOWN) {
-        SDL_SendKeyboardKeyAutoRelease(scancode);
+        SDL_SendKeyboardKeyAutoRelease(0, scancode);
     }
 }
 
@@ -409,8 +409,8 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
             size_t deleteLength = SDL_utf8strlen([[committedText substringFromIndex:matchLength] UTF8String]);
             while (deleteLength > 0) {
                 /* Send distinct down and up events for each backspace action */
-                SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
-                SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
+                SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
+                SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
                 --deleteLength;
             }
         }
@@ -422,7 +422,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
                  * convert them to key presses */
                 NSUInteger i;
                 for (i = 0; i < pendingText.length; i++) {
-                    SDL_SendKeyboardUnicodeKey([pendingText characterAtIndex:i]);
+                    SDL_SendKeyboardUnicodeKey(0, [pendingText characterAtIndex:i]);
                 }
             }
             SDL_SendKeyboardText([pendingText UTF8String]);
@@ -480,7 +480,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
 /* Terminates the editing session */
 - (BOOL)textFieldShouldReturn:(UITextField *)_textField
 {
-    SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN);
+    SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN);
     if (keyboardVisible &&
         SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE)) {
         SDL_StopTextInput();

+ 28 - 28
src/video/vita/SDL_vitakeyboard.c

@@ -62,40 +62,40 @@ void VITA_PollKeyboard(void)
             // The k_report only reports the state of the LED
             if (k_reports[numReports - 1].modifiers[1] & 0x1) {
                 if (!(locks & 0x1)) {
-                    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
+                    SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
                     locks |= 0x1;
                 }
             } else {
                 if (locks & 0x1) {
-                    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
-                    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
-                    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
+                    SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
+                    SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
+                    SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
                     locks &= ~0x1;
                 }
             }
 
             if (k_reports[numReports - 1].modifiers[1] & 0x2) {
                 if (!(locks & 0x2)) {
-                    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
+                    SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
                     locks |= 0x2;
                 }
             } else {
                 if (locks & 0x2) {
-                    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
-                    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
-                    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
+                    SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
+                    SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
+                    SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
                     locks &= ~0x2;
                 }
             }
 
             if (k_reports[numReports - 1].modifiers[1] & 0x4) {
                 if (!(locks & 0x4)) {
-                    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK);
+                    SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK);
                     locks |= 0x4;
                 }
             } else {
                 if (locks & 0x4) {
-                    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK);
+                    SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK);
                     locks &= ~0x4;
                 }
             }
@@ -105,58 +105,58 @@ void VITA_PollKeyboard(void)
 
                 if (changed_modifiers & 0x01) {
                     if (prev_modifiers & 0x01) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LCTRL);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LCTRL);
                     } else {
-                        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LCTRL);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LCTRL);
                     }
                 }
                 if (changed_modifiers & 0x02) {
                     if (prev_modifiers & 0x02) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
                     } else {
-                        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LSHIFT);
                     }
                 }
                 if (changed_modifiers & 0x04) {
                     if (prev_modifiers & 0x04) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LALT);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LALT);
                     } else {
-                        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LALT);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LALT);
                     }
                 }
                 if (changed_modifiers & 0x08) {
                     if (prev_modifiers & 0x08) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LGUI);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LGUI);
                     } else {
-                        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LGUI);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LGUI);
                     }
                 }
                 if (changed_modifiers & 0x10) {
                     if (prev_modifiers & 0x10) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RCTRL);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RCTRL);
                     } else {
-                        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RCTRL);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RCTRL);
                     }
                 }
                 if (changed_modifiers & 0x20) {
                     if (prev_modifiers & 0x20) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RSHIFT);
                     } else {
-                        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RSHIFT);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RSHIFT);
                     }
                 }
                 if (changed_modifiers & 0x40) {
                     if (prev_modifiers & 0x40) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RALT);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RALT);
                     } else {
-                        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RALT);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RALT);
                     }
                 }
                 if (changed_modifiers & 0x80) {
                     if (prev_modifiers & 0x80) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RGUI);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RGUI);
                     } else {
-                        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RGUI);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RGUI);
                     }
                 }
             }
@@ -170,10 +170,10 @@ void VITA_PollKeyboard(void)
                 if (keyCode != prev_keys[i]) {
 
                     if (prev_keys[i]) {
-                        SDL_SendKeyboardKey(SDL_RELEASED, prev_keys[i]);
+                        SDL_SendKeyboardKey(0, SDL_RELEASED, prev_keys[i]);
                     }
                     if (keyCode) {
-                        SDL_SendKeyboardKey(SDL_PRESSED, keyCode);
+                        SDL_SendKeyboardKey(0, SDL_PRESSED, keyCode);
                     }
                     prev_keys[i] = keyCode;
                 }

+ 7 - 7
src/video/vita/SDL_vitamouse.c

@@ -54,27 +54,27 @@ void VITA_PollMouse(void)
 
                 if (changed_buttons & 0x1) {
                     if (prev_buttons & 0x1)
-                        SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_LEFT);
+                        SDL_SendMouseButton(0, Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_LEFT);
                     else
-                        SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_LEFT);
+                        SDL_SendMouseButton(0, Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_LEFT);
                 }
                 if (changed_buttons & 0x2) {
                     if (prev_buttons & 0x2)
-                        SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_RIGHT);
+                        SDL_SendMouseButton(0, Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_RIGHT);
                     else
-                        SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_RIGHT);
+                        SDL_SendMouseButton(0, Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_RIGHT);
                 }
                 if (changed_buttons & 0x4) {
                     if (prev_buttons & 0x4)
-                        SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_MIDDLE);
+                        SDL_SendMouseButton(0, Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_MIDDLE);
                     else
-                        SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_MIDDLE);
+                        SDL_SendMouseButton(0, Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_MIDDLE);
                 }
 
                 prev_buttons = m_reports[i].buttons;
 
                 if (m_reports[i].rel_x || m_reports[i].rel_y) {
-                    SDL_SendMouseMotion(Vita_Window, 0, 1, m_reports[i].rel_x, m_reports[i].rel_y);
+                    SDL_SendMouseMotion(0, Vita_Window, 0, 1, m_reports[i].rel_x, m_reports[i].rel_y);
                 }
             }
         }

+ 3 - 3
src/video/vita/SDL_vitatouch.c

@@ -121,7 +121,7 @@ void VITA_PollTouch(void)
                 // Skip if finger was already previously down
                 if (!finger_down) {
                     // Send an initial touch
-                    SDL_SendTouch((SDL_TouchID)port,
+                    SDL_SendTouch(0, (SDL_TouchID)port,
                                   finger_id,
                                   Vita_Window,
                                   SDL_TRUE,
@@ -131,7 +131,7 @@ void VITA_PollTouch(void)
                 }
 
                 // Always send the motion
-                SDL_SendTouchMotion((SDL_TouchID)port,
+                SDL_SendTouchMotion(0, (SDL_TouchID)port,
                                     finger_id,
                                     Vita_Window,
                                     x,
@@ -158,7 +158,7 @@ void VITA_PollTouch(void)
                     VITA_ConvertTouchXYToSDLXY(&x, &y, touch_old[port].report[i].x, touch_old[port].report[i].y, port);
                     finger_id = (SDL_FingerID)touch_old[port].report[i].id;
                     // Finger released from screen
-                    SDL_SendTouch((SDL_TouchID)port,
+                    SDL_SendTouch(0, (SDL_TouchID)port,
                                   finger_id,
                                   Vita_Window,
                                   SDL_FALSE,

+ 4 - 4
src/video/vita/SDL_vitavideo.c

@@ -418,12 +418,12 @@ void VITA_ImeEventHandler(void *arg, const SceImeEventData *e)
     switch (e->id) {
     case SCE_IME_EVENT_UPDATE_TEXT:
         if (e->param.text.caretIndex == 0) {
-            SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_BACKSPACE);
+            SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_BACKSPACE);
             sceImeSetText((SceWChar16 *)libime_initval, 4);
         } else {
             scancode = SDL_GetScancodeFromKey(*(SceWChar16 *)&libime_out[1]);
             if (scancode == SDL_SCANCODE_SPACE) {
-                SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_SPACE);
+                SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_SPACE);
             } else {
                 utf16_to_utf8((SceWChar16 *)&libime_out[1], utf8_buffer);
                 SDL_SendKeyboardText((const char *)utf8_buffer);
@@ -436,7 +436,7 @@ void VITA_ImeEventHandler(void *arg, const SceImeEventData *e)
         }
         break;
     case SCE_IME_EVENT_PRESS_ENTER:
-        SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN);
+        SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN);
     case SCE_IME_EVENT_PRESS_CLOSE:
         sceImeClose();
         videodata->ime_active = SDL_FALSE;
@@ -572,7 +572,7 @@ void VITA_PumpEvents(_THIS)
 
             // Send enter key only on enter
             if (result.button == SCE_IME_DIALOG_BUTTON_ENTER) {
-                SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN);
+                SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN);
             }
 
             sceImeDialogTerm();

+ 14 - 14
src/video/wayland/SDL_waylandevents.c

@@ -179,7 +179,7 @@ static SDL_bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, u
     SDL_bool ret = SDL_FALSE;
     while ((elapsed - repeat_info->next_repeat_ms) < 0x80000000U) {
         if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) {
-            SDL_SendKeyboardKey(SDL_PRESSED, repeat_info->scancode);
+            SDL_SendKeyboardKey(0, SDL_PRESSED, repeat_info->scancode);
         }
         if (repeat_info->text[0]) {
             SDL_SendKeyboardText(repeat_info->text);
@@ -409,7 +409,7 @@ static void pointer_handle_motion(void *data, struct wl_pointer *pointer,
         const float sy_f = (float)wl_fixed_to_double(sy_w);
         const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x);
         const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y);
-        SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
+        SDL_SendMouseMotion(0, window->sdlwindow, 0, 0, sx, sy);
     }
 }
 
@@ -599,7 +599,7 @@ static void pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_
         Wayland_data_device_set_serial(input->data_device, serial);
         Wayland_primary_selection_device_set_serial(input->primary_selection_device, serial);
 
-        SDL_SendMouseButton(window->sdlwindow, 0,
+        SDL_SendMouseButton(0, window->sdlwindow, 0,
                             state ? SDL_PRESSED : SDL_RELEASED, sdl_button);
     }
 }
@@ -636,7 +636,7 @@ static void pointer_handle_axis_common_v1(struct SDL_WaylandInput *input,
         x /= WAYLAND_WHEEL_AXIS_UNIT;
         y /= WAYLAND_WHEEL_AXIS_UNIT;
 
-        SDL_SendMouseWheel(window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
+        SDL_SendMouseWheel(0, window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
     }
 }
 
@@ -765,7 +765,7 @@ static void pointer_handle_frame(void *data, struct wl_pointer *pointer)
     SDL_memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info);
 
     if (x != 0.0f || y != 0.0f) {
-        SDL_SendMouseWheel(window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
+        SDL_SendMouseWheel(0, window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
     }
 }
 
@@ -822,7 +822,7 @@ static void touch_handler_down(void *data, struct wl_touch *touch, unsigned int
 
     touch_add(id, x, y, surface);
 
-    SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window_data->sdlwindow, SDL_TRUE, x, y, 1.0f);
+    SDL_SendTouch(0, (SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window_data->sdlwindow, SDL_TRUE, x, y, 1.0f);
 }
 
 static void touch_handler_up(void *data, struct wl_touch *touch, unsigned int serial,
@@ -839,7 +839,7 @@ static void touch_handler_up(void *data, struct wl_touch *touch, unsigned int se
         window = window_data->sdlwindow;
     }
 
-    SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window, SDL_FALSE, x, y, 0.0f);
+    SDL_SendTouch(0, (SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window, SDL_FALSE, x, y, 0.0f);
 }
 
 static void touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp,
@@ -852,7 +852,7 @@ static void touch_handler_motion(void *data, struct wl_touch *touch, unsigned in
     const float y = dbly / window_data->sdlwindow->h;
 
     touch_update(id, x, y);
-    SDL_SendTouchMotion((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window_data->sdlwindow, x, y, 1.0f);
+    SDL_SendTouchMotion(0, (SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window_data->sdlwindow, x, y, 1.0f);
 }
 
 static void touch_handler_frame(void *data, struct wl_touch *touch)
@@ -1100,7 +1100,7 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
         if (scancode != SDL_SCANCODE_UNKNOWN) {
             for (uint32_t i = 0; i < sizeof mod_scancodes / sizeof *mod_scancodes; ++i) {
                 if (mod_scancodes[i] == scancode) {
-                    SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+                    SDL_SendKeyboardKey(0, SDL_PRESSED, scancode);
                     break;
                 }
             }
@@ -1215,7 +1215,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
 
     if (!handled_by_ime) {
         scancode = Wayland_get_scancode_from_key(input, key + 8);
-        SDL_SendKeyboardKey(state == WL_KEYBOARD_KEY_STATE_PRESSED ? SDL_PRESSED : SDL_RELEASED, scancode);
+        SDL_SendKeyboardKey(0, state == WL_KEYBOARD_KEY_STATE_PRESSED ? SDL_PRESSED : SDL_RELEASED, scancode);
     }
 
     if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
@@ -2083,7 +2083,7 @@ static void tablet_tool_handle_down(void *data, struct zwp_tablet_tool_v2 *tool,
         return;
     }
 
-    SDL_SendMouseButton(window->sdlwindow, 0, SDL_PRESSED, tablet_tool_btn_to_sdl_button(input));
+    SDL_SendMouseButton(0, window->sdlwindow, 0, SDL_PRESSED, tablet_tool_btn_to_sdl_button(input));
 }
 
 static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 *tool)
@@ -2101,7 +2101,7 @@ static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 *tool)
         return;
     }
 
-    SDL_SendMouseButton(window->sdlwindow, 0, SDL_RELEASED, tablet_tool_btn_to_sdl_button(input));
+    SDL_SendMouseButton(0, window->sdlwindow, 0, SDL_RELEASED, tablet_tool_btn_to_sdl_button(input));
 }
 
 static void tablet_tool_handle_motion(void *data, struct zwp_tablet_tool_v2 *tool, wl_fixed_t sx_w, wl_fixed_t sy_w)
@@ -2116,7 +2116,7 @@ static void tablet_tool_handle_motion(void *data, struct zwp_tablet_tool_v2 *too
         const float sy_f = (float)wl_fixed_to_double(sy_w);
         const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x);
         const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y);
-        SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
+        SDL_SendMouseMotion(0, window->sdlwindow, 0, 0, sx, sy);
     }
 }
 
@@ -2473,7 +2473,7 @@ static void relative_pointer_handle_relative_motion(void *data,
     input->dy_frac = modf(dy_unaccel, &dy);
 
     if (input->pointer_focus && d->relative_mouse_mode) {
-        SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy);
+        SDL_SendMouseMotion(0, window->sdlwindow, 0, 1, (int)dx, (int)dy);
     }
 }
 

+ 2 - 2
src/video/wayland/SDL_waylandtouch.c

@@ -104,12 +104,12 @@ static void touch_handle_touch(void *data,
     switch (touchState) {
     case QtWaylandTouchPointPressed:
     case QtWaylandTouchPointReleased:
-        SDL_SendTouch(deviceId, (SDL_FingerID)id, window,
+        SDL_SendTouch(0, deviceId, (SDL_FingerID)id, window,
                       (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE,
                       xf, yf, pressuref);
         break;
     case QtWaylandTouchPointMoved:
-        SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, window, xf, yf, pressuref);
+        SDL_SendTouchMotion(0, deviceId, (SDL_FingerID)id, window, xf, yf, pressuref);
         break;
     default:
         /* Should not happen */

+ 79 - 33
src/video/windows/SDL_windowsevents.c

@@ -109,6 +109,48 @@
 #define IS_SURROGATE_PAIR(h, l) (IS_HIGH_SURROGATE(h) && IS_LOW_SURROGATE(l))
 #endif
 
+/* Used to compare Windows message timestamps */
+#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0)
+
+static SDL_bool SDL_processing_messages;
+static DWORD message_tick;
+static Uint64 timestamp_offset;
+
+static void WIN_SetMessageTick(DWORD tick)
+{
+    if (message_tick) {
+        if (tick < message_tick && timestamp_offset) {
+            /* The tick counter rolled over, bump our offset */
+            timestamp_offset += SDL_MS_TO_NS(0x100000000LLU);
+        }
+    }
+    message_tick = tick;
+}
+
+static Uint64 WIN_GetEventTimestamp()
+{
+    Uint64 timestamp, now;
+
+    if (!SDL_processing_messages) {
+        /* message_tick isn't valid, just use the current time */
+        return 0;
+    }
+
+    now = SDL_GetTicksNS();
+    timestamp = SDL_MS_TO_NS(message_tick);
+
+    if (!timestamp_offset) {
+        timestamp_offset = (now - timestamp);
+    }
+    timestamp += timestamp_offset;
+
+    if (timestamp > now) {
+        timestamp_offset -= (timestamp - now);
+        timestamp = now;
+    }
+    return timestamp;
+}
+
 static SDL_Scancode VKeytoScancodeFallback(WPARAM vkey)
 {
     switch (vkey) {
@@ -337,9 +379,9 @@ static void WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, Uint32 mous
     }
 
     if (bwParamMousePressed && !(mouseFlags & SDL_BUTTON(button))) {
-        SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button);
+        SDL_SendMouseButton(WIN_GetEventTimestamp(), data->window, mouseID, SDL_PRESSED, button);
     } else if (!bwParamMousePressed && (mouseFlags & SDL_BUTTON(button))) {
-        SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button);
+        SDL_SendMouseButton(WIN_GetEventTimestamp(), data->window, mouseID, SDL_RELEASED, button);
     }
 }
 
@@ -481,7 +523,7 @@ static void WIN_UpdateFocus(SDL_Window *window, SDL_bool expect_focus)
             point.x = cursorPos.x;
             point.y = cursorPos.y;
             WIN_ClientPointToSDL(data->window, &point.x, &point.y);
-            SDL_SendMouseMotion(window, 0, 0, point.x, point.y);
+            SDL_SendMouseMotion(WIN_GetEventTimestamp(), window, 0, 0, point.x, point.y);
         }
 
         WIN_CheckAsyncMouseRelease(data);
@@ -651,9 +693,9 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
     }
 
     if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
-        SDL_SendKeyboardKey(SDL_PRESSED, scanCode);
+        SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_PRESSED, scanCode);
     } else {
-        SDL_SendKeyboardKey(SDL_RELEASED, scanCode);
+        SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_RELEASED, scanCode);
 
         /* If the key was down prior to our hook being installed, allow the
            key up message to pass normally the first time. This ensures other
@@ -793,7 +835,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
                 WIN_ClientPointToSDL(data->window, &x, &y);
 
-                SDL_SendMouseMotion(data->window, 0, 0, x, y);
+                SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, 0, 0, x, y);
             }
         }
     } break;
@@ -855,7 +897,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
             rawmouse = &inp.data.mouse;
 
             if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
-                SDL_SendMouseMotion(data->window, mouseID, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
+                SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, mouseID, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
             } else if (rawmouse->lLastX || rawmouse->lLastY) {
                 /* This is absolute motion, either using a tablet or mouse over RDP
 
@@ -911,7 +953,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                             const int MAX_RELATIVE_MOTION = (h / 6);
                             if (SDL_abs(relX) < MAX_RELATIVE_MOTION &&
                                 SDL_abs(relY) < MAX_RELATIVE_MOTION) {
-                                SDL_SendMouseMotion(data->window, mouseID, 1, relX, relY);
+                                SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, mouseID, 1, relX, relY);
                             }
                         }
                     }
@@ -921,7 +963,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                         SDL_abs(relY) > MAXIMUM_TABLET_RELATIVE_MOTION) {
                         /* Ignore this motion, probably a pen lift and drop */
                     } else {
-                        SDL_SendMouseMotion(data->window, mouseID, 1, relX, relY);
+                        SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, mouseID, 1, relX, relY);
                     }
                 }
 
@@ -938,9 +980,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         short amount = GET_WHEEL_DELTA_WPARAM(wParam);
         float fAmount = (float)amount / WHEEL_DELTA;
         if (msg == WM_MOUSEWHEEL) {
-            SDL_SendMouseWheel(data->window, 0, 0.0f, fAmount, SDL_MOUSEWHEEL_NORMAL);
+            SDL_SendMouseWheel(WIN_GetEventTimestamp(), data->window, 0, 0.0f, fAmount, SDL_MOUSEWHEEL_NORMAL);
         } else {
-            SDL_SendMouseWheel(data->window, 0, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
+            SDL_SendMouseWheel(WIN_GetEventTimestamp(), data->window, 0, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
         }
     } break;
 
@@ -957,13 +999,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                 WIN_ClientPointToSDL(data->window, &point.x, &point.y);
                 mouse = SDL_GetMouse();
                 if (!mouse->was_touch_mouse_events) { /* we're not a touch handler causing a mouse leave? */
-                    SDL_SendMouseMotion(data->window, 0, 0, point.x, point.y);
+                    SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, 0, 0, point.x, point.y);
                 } else {                                       /* touch handling? */
                     mouse->was_touch_mouse_events = SDL_FALSE; /* not anymore */
                     if (mouse->touch_mouse_events) {           /* convert touch to mouse events */
-                        SDL_SendMouseMotion(data->window, SDL_TOUCH_MOUSEID, 0, point.x, point.y);
+                        SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, SDL_TOUCH_MOUSEID, 0, point.x, point.y);
                     } else { /* normal handling */
-                        SDL_SendMouseMotion(data->window, 0, 0, point.x, point.y);
+                        SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, 0, 0, point.x, point.y);
                     }
                 }
             }
@@ -996,7 +1038,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         }
 
         if (code != SDL_SCANCODE_UNKNOWN) {
-            SDL_SendKeyboardKey(SDL_PRESSED, code);
+            SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_PRESSED, code);
         }
     }
 
@@ -1012,9 +1054,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         if (code != SDL_SCANCODE_UNKNOWN) {
             if (code == SDL_SCANCODE_PRINTSCREEN &&
                 keyboardState[code] == SDL_RELEASED) {
-                SDL_SendKeyboardKey(SDL_PRESSED, code);
+                SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_PRESSED, code);
             }
-            SDL_SendKeyboardKey(SDL_RELEASED, code);
+            SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_RELEASED, code);
         }
     }
         returnCode = 0;
@@ -1376,14 +1418,15 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                     x = (float)(input->x - rect.left) / (rect.right - rect.left);
                     y = (float)(input->y - rect.top) / (rect.bottom - rect.top);
 
+                    /* FIXME: Should we use the input->dwTime field for the tick source of the timestamp? */
                     if (input->dwFlags & TOUCHEVENTF_DOWN) {
-                        SDL_SendTouch(touchId, input->dwID, data->window, SDL_TRUE, x, y, 1.0f);
+                        SDL_SendTouch(WIN_GetEventTimestamp(), touchId, input->dwID, data->window, SDL_TRUE, x, y, 1.0f);
                     }
                     if (input->dwFlags & TOUCHEVENTF_MOVE) {
-                        SDL_SendTouchMotion(touchId, input->dwID, data->window, x, y, 1.0f);
+                        SDL_SendTouchMotion(WIN_GetEventTimestamp(), touchId, input->dwID, data->window, x, y, 1.0f);
                     }
                     if (input->dwFlags & TOUCHEVENTF_UP) {
-                        SDL_SendTouch(touchId, input->dwID, data->window, SDL_FALSE, x, y, 1.0f);
+                        SDL_SendTouch(WIN_GetEventTimestamp(), touchId, input->dwID, data->window, SDL_FALSE, x, y, 1.0f);
                     }
                 }
             }
@@ -1743,12 +1786,12 @@ static void WIN_UpdateMouseCapture()
                 point.y = cursorPos.y;
                 WIN_ClientPointToSDL(data->window, &point.x, &point.y);
 
-                SDL_SendMouseMotion(data->window, mouseID, 0, point.x, point.y);
-                SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT);
-                SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT);
-                SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
-                SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
-                SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
+                SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, mouseID, 0, point.x, point.y);
+                SDL_SendMouseButton(WIN_GetEventTimestamp(), data->window, mouseID, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT);
+                SDL_SendMouseButton(WIN_GetEventTimestamp(), data->window, mouseID, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT);
+                SDL_SendMouseButton(WIN_GetEventTimestamp(), data->window, mouseID, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
+                SDL_SendMouseButton(WIN_GetEventTimestamp(), data->window, mouseID, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
+                SDL_SendMouseButton(WIN_GetEventTimestamp(), data->window, mouseID, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
             }
         }
     }
@@ -1806,9 +1849,6 @@ void WIN_SendWakeupEvent(_THIS, SDL_Window *window)
     PostMessage(data->hwnd, data->videodata->_SDL_WAKEUP, 0, 0);
 }
 
-/* Used to compare Windows message timestamps */
-#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0)
-
 void WIN_PumpEvents(_THIS)
 {
     MSG msg;
@@ -1820,6 +1860,8 @@ void WIN_PumpEvents(_THIS)
 #endif
 
     if (g_WindowsEnableMessageLoop) {
+        SDL_processing_messages = SDL_TRUE;
+
         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
             if (g_WindowsMessageHook) {
                 g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam);
@@ -1837,6 +1879,8 @@ void WIN_PumpEvents(_THIS)
             }
 #endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
 
+            WIN_SetMessageTick(msg.time);
+
             /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */
             TranslateMessage(&msg);
             DispatchMessage(&msg);
@@ -1854,6 +1898,8 @@ void WIN_PumpEvents(_THIS)
                 }
             }
         }
+
+        SDL_processing_messages = SDL_FALSE;
     }
 
 #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
@@ -1863,10 +1909,10 @@ void WIN_PumpEvents(_THIS)
        and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */
     keystate = SDL_GetKeyboardState(NULL);
     if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
-        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
+        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
     }
     if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
-        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT);
+        SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RSHIFT);
     }
 
     /* The Windows key state gets lost when using Windows+Space or Windows+G shortcuts and
@@ -1875,10 +1921,10 @@ void WIN_PumpEvents(_THIS)
     focusWindow = SDL_GetKeyboardFocus();
     if (focusWindow == NULL || !(focusWindow->flags & SDL_WINDOW_KEYBOARD_GRABBED)) {
         if ((keystate[SDL_SCANCODE_LGUI] == SDL_PRESSED) && !(GetKeyState(VK_LWIN) & 0x8000)) {
-            SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LGUI);
+            SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LGUI);
         }
         if ((keystate[SDL_SCANCODE_RGUI] == SDL_PRESSED) && !(GetKeyState(VK_RWIN) & 0x8000)) {
-            SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RGUI);
+            SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RGUI);
         }
     }
 

+ 1 - 1
src/video/windows/SDL_windowsmouse.c

@@ -294,7 +294,7 @@ static void WIN_WarpMouse(SDL_Window *window, int x, int y)
     WIN_SetCursorPos(pt.x, pt.y);
 
     /* Send the exact mouse motion associated with this warp */
-    SDL_SendMouseMotion(window, SDL_GetMouse()->mouseID, 0, x, y);
+    SDL_SendMouseMotion(0, window, SDL_GetMouse()->mouseID, 0, x, y);
 }
 
 static int WIN_WarpMouseGlobal(int x, int y)

+ 2 - 2
src/video/winrt/SDL_winrtkeyboard.cpp

@@ -351,7 +351,7 @@ void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^ args)
         SDL_GetKeyName(keycode));
     //args->Handled = true;
 #endif
-    SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode);
+    SDL_SendKeyboardKey(0, SDL_PRESSED, sdlScancode);
 }
 
 void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^ args)
@@ -376,7 +376,7 @@ void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^ args)
         SDL_GetKeyName(keycode));
     //args->Handled = true;
 #endif
-    SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode);
+    SDL_SendKeyboardKey(0, SDL_RELEASED, sdlScancode);
 }
 
 void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^ args)

+ 9 - 9
src/video/winrt/SDL_winrtpointerinput.cpp

@@ -221,12 +221,12 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po
         Uint8 button, pressed;
         WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed);
         SDL_assert(pressed == 1);
-        SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
+        SDL_SendMouseButton(0, window, 0, SDL_PRESSED, button);
     } else {
         Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
         Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
 
-        SDL_SendTouch(
+        SDL_SendTouch(0,
             WINRT_TouchID,
             (SDL_FingerID)pointerPoint->PointerId,
             window,
@@ -250,12 +250,12 @@ void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::Poin
         /* For some odd reason Moved events are used for multiple mouse buttons */
         Uint8 button, pressed;
         if (WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed)) {
-            SDL_SendMouseButton(window, 0, pressed, button);
+            SDL_SendMouseButton(0, window, 0, pressed, button);
         }
 
-        SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
+        SDL_SendMouseMotion(0, window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
     } else {
-        SDL_SendTouchMotion(
+        SDL_SendTouchMotion(0,
             WINRT_TouchID,
             (SDL_FingerID)pointerPoint->PointerId,
             window,
@@ -275,11 +275,11 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P
         Uint8 button, pressed;
         WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed);
         SDL_assert(pressed == 0);
-        SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
+        SDL_SendMouseButton(0, window, 0, SDL_RELEASED, button);
     } else {
         Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
 
-        SDL_SendTouch(
+        SDL_SendTouch(0,
             WINRT_TouchID,
             (SDL_FingerID)pointerPoint->PointerId,
             window,
@@ -319,7 +319,7 @@ void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Inpu
     }
 
     float motion = (float)pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
-    SDL_SendMouseWheel(window, 0, 0, (float)motion, SDL_MOUSEWHEEL_NORMAL);
+    SDL_SendMouseWheel(0, window, 0, 0, (float)motion, SDL_MOUSEWHEEL_NORMAL);
 }
 
 void WINRT_ProcessMouseMovedEvent(SDL_Window *window, Windows::Devices::Input::MouseEventArgs ^ args)
@@ -386,7 +386,7 @@ void WINRT_ProcessMouseMovedEvent(SDL_Window *window, Windows::Devices::Input::M
     //
     const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y);
     const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize);
-    SDL_SendMouseMotion(
+    SDL_SendMouseMotion(0,
         window,
         0,
         1,

+ 12 - 12
src/video/x11/SDL_x11events.c

@@ -436,13 +436,13 @@ void X11_ReconcileKeyboardState(_THIS)
             case SDLK_LGUI:
             case SDLK_RGUI:
             case SDLK_MODE:
-                SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+                SDL_SendKeyboardKey(0, SDL_PRESSED, scancode);
                 break;
             default:
                 break;
             }
         } else if (!x11KeyPressed && sdlKeyPressed) {
-            SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+            SDL_SendKeyboardKey(0, SDL_RELEASED, scancode);
         }
     }
 }
@@ -793,9 +793,9 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
             videodata->filter_time = xevent->xkey.time;
 
             if (orig_event_type == KeyPress) {
-                SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+                SDL_SendKeyboardKey(0, SDL_PRESSED, scancode);
             } else {
-                SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+                SDL_SendKeyboardKey(0, SDL_RELEASED, scancode);
             }
 #endif
         }
@@ -932,7 +932,7 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
 #endif
 
         if (!mouse->relative_mode) {
-            SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y);
+            SDL_SendMouseMotion(0, data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y);
         }
 
         /* We ungrab in LeaveNotify, so we may need to grab again here */
@@ -954,7 +954,7 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
         }
 #endif
         if (!SDL_GetMouse()->relative_mode) {
-            SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y);
+            SDL_SendMouseMotion(0, data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y);
         }
 
         if (xevent->xcrossing.mode != NotifyGrab &&
@@ -1086,7 +1086,7 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
             if (xevent->type == KeyPress) {
                 /* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
                 if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
-                    SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
+                    SDL_SendKeyboardKey(0, SDL_PRESSED, videodata->key_layout[keycode]);
                 }
                 if (*text) {
                     SDL_SendKeyboardText(text);
@@ -1096,7 +1096,7 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
                     /* We're about to get a repeated key down, ignore the key up */
                     break;
                 }
-                SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
+                SDL_SendKeyboardKey(0, SDL_RELEASED, videodata->key_layout[keycode]);
             }
         }
 
@@ -1311,7 +1311,7 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
             printf("window %p: X11 motion: %d,%d\n", data, xevent->xmotion.x, xevent->xmotion.y);
 #endif
 
-            SDL_SendMouseMotion(data->window, 0, 0, xevent->xmotion.x, xevent->xmotion.y);
+            SDL_SendMouseMotion(0, data->window, 0, 0, xevent->xmotion.x, xevent->xmotion.y);
         }
     } break;
 
@@ -1322,7 +1322,7 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
         printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent->xbutton.button);
 #endif
         if (X11_IsWheelEvent(display, xevent, &xticks, &yticks)) {
-            SDL_SendMouseWheel(data->window, 0, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL);
+            SDL_SendMouseWheel(0, data->window, 0, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL);
         } else {
             SDL_bool ignore_click = SDL_FALSE;
             int button = xevent->xbutton.button;
@@ -1344,7 +1344,7 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
                 data->last_focus_event_time = 0;
             }
             if (!ignore_click) {
-                SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button);
+                SDL_SendMouseButton(0, data->window, 0, SDL_PRESSED, button);
             }
         }
         X11_UpdateUserTime(data, xevent->xbutton.time);
@@ -1363,7 +1363,7 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
                 /* see explanation at case ButtonPress */
                 button -= (8 - SDL_BUTTON_X1);
             }
-            SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button);
+            SDL_SendMouseButton(0, data->window, 0, SDL_RELEASED, button);
         }
     } break;
 

+ 5 - 5
src/video/x11/SDL_x11xinput2.c

@@ -306,7 +306,7 @@ int X11_HandleXinput2Event(SDL_VideoData *videodata, XGenericEventCookie *cookie
             }
         }
 
-        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)processed_coords[0], (int)processed_coords[1]);
+        SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, (int)processed_coords[0], (int)processed_coords[1]);
         devinfo->prev_coords[0] = coords[0];
         devinfo->prev_coords[1] = coords[1];
         devinfo->prev_time = rawev->time;
@@ -347,7 +347,7 @@ int X11_HandleXinput2Event(SDL_VideoData *videodata, XGenericEventCookie *cookie
             if (!mouse->relative_mode || mouse->relative_mode_warp) {
                 SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
                 if (window) {
-                    SDL_SendMouseMotion(window, 0, 0, xev->event_x, xev->event_y);
+                    SDL_SendMouseMotion(0, window, 0, 0, xev->event_x, xev->event_y);
                 }
             }
         }
@@ -360,7 +360,7 @@ int X11_HandleXinput2Event(SDL_VideoData *videodata, XGenericEventCookie *cookie
         float x, y;
         SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
         xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y);
-        SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_TRUE, x, y, 1.0);
+        SDL_SendTouch(0, xev->sourceid, xev->detail, window, SDL_TRUE, x, y, 1.0);
         return 1;
     } break;
     case XI_TouchEnd:
@@ -369,7 +369,7 @@ int X11_HandleXinput2Event(SDL_VideoData *videodata, XGenericEventCookie *cookie
         float x, y;
         SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
         xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y);
-        SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_FALSE, x, y, 1.0);
+        SDL_SendTouch(0, xev->sourceid, xev->detail, window, SDL_FALSE, x, y, 1.0);
         return 1;
     } break;
     case XI_TouchUpdate:
@@ -378,7 +378,7 @@ int X11_HandleXinput2Event(SDL_VideoData *videodata, XGenericEventCookie *cookie
         float x, y;
         SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
         xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y);
-        SDL_SendTouchMotion(xev->sourceid, xev->detail, window, x, y, 1.0);
+        SDL_SendTouchMotion(0, xev->sourceid, xev->detail, window, x, y, 1.0);
         return 1;
     } break;