@@ -179,7 +179,7 @@ static void Wayland_GetScaledMouseRect(SDL_Window *window, SDL_Rect *scaled_rect
179
179
scaled_rect -> h = (int )SDL_ceil (window -> mouse_rect .h / window_data -> pointer_scale .y );
180
180
}
181
181
182
- static Uint64 Wayland_GetEventTimestamp (Uint64 nsTimestamp )
182
+ static Uint64 Wayland_AdjustEventTimestampBase (Uint64 nsTimestamp )
183
183
{
184
184
static Uint64 timestamp_offset = 0 ;
185
185
const Uint64 now = SDL_GetTicksNS ();
@@ -197,16 +197,9 @@ static Uint64 Wayland_GetEventTimestamp(Uint64 nsTimestamp)
197
197
return nsTimestamp ;
198
198
}
199
199
200
- static void input_timestamp_listener (void * data , struct zwp_input_timestamps_v1 * zwp_input_timestamps_v1 ,
201
- uint32_t tv_sec_hi , uint32_t tv_sec_lo , uint32_t tv_nsec )
202
- {
203
- * ((Uint64 * )data ) = ((((Uint64 )tv_sec_hi << 32 ) | (Uint64 )tv_sec_lo ) * SDL_NS_PER_SECOND ) + tv_nsec ;
204
- }
205
-
206
- static const struct zwp_input_timestamps_v1_listener timestamp_listener = {
207
- input_timestamp_listener
208
- };
209
-
200
+ /* This should only be called with 32-bit millisecond timestamps received in Wayland events!
201
+ * No synthetic or high-res timestamps, as they can corrupt the rollover offset!
202
+ */
210
203
static Uint64 Wayland_EventTimestampMSToNS (Uint32 wl_timestamp_ms )
211
204
{
212
205
static Uint64 timestamp_offset = 0 ;
@@ -222,38 +215,38 @@ static Uint64 Wayland_EventTimestampMSToNS(Uint32 wl_timestamp_ms)
222
215
return SDL_MS_TO_NS (wl_timestamp_ms ) + timestamp_offset ;
223
216
}
224
217
225
- static Uint64 Wayland_GetKeyboardTimestamp (SDL_WaylandSeat * seat , Uint32 wl_timestamp_ms )
226
- {
227
- if (wl_timestamp_ms ) {
228
- return Wayland_GetEventTimestamp (seat -> keyboard .highres_timestamp_ns ? seat -> keyboard .highres_timestamp_ns : Wayland_EventTimestampMSToNS (wl_timestamp_ms ));
229
- }
230
-
231
- return 0 ;
232
- }
218
+ /* Even if high-res timestamps are available, the millisecond timestamps are still processed
219
+ * to accumulate the rollover offset if needed later.
220
+ */
233
221
234
222
static Uint64 Wayland_GetKeyboardTimestampRaw (SDL_WaylandSeat * seat , Uint32 wl_timestamp_ms )
235
223
{
236
- return seat -> keyboard .highres_timestamp_ns ? seat -> keyboard .highres_timestamp_ns : Wayland_EventTimestampMSToNS (wl_timestamp_ms );
224
+ const Uint64 adjustedTimestampMS = Wayland_EventTimestampMSToNS (wl_timestamp_ms );
225
+ return seat -> keyboard .timestamps ? seat -> keyboard .highres_timestamp_ns : adjustedTimestampMS ;
237
226
}
238
227
239
228
static Uint64 Wayland_GetPointerTimestamp (SDL_WaylandSeat * seat , Uint32 wl_timestamp_ms )
240
229
{
241
- if (wl_timestamp_ms ) {
242
- return Wayland_GetEventTimestamp (seat -> pointer .highres_timestamp_ns ? seat -> pointer .highres_timestamp_ns : Wayland_EventTimestampMSToNS (wl_timestamp_ms ));
243
- }
244
-
245
- return 0 ;
230
+ const Uint64 adjustedTimestampMS = Wayland_EventTimestampMSToNS (wl_timestamp_ms );
231
+ return Wayland_AdjustEventTimestampBase (seat -> pointer .timestamps ? seat -> pointer .highres_timestamp_ns : adjustedTimestampMS );
246
232
}
247
233
248
234
Uint64 Wayland_GetTouchTimestamp (SDL_WaylandSeat * seat , Uint32 wl_timestamp_ms )
249
235
{
250
- if (wl_timestamp_ms ) {
251
- return Wayland_GetEventTimestamp (seat -> touch .highres_timestamp_ns ? seat -> touch .highres_timestamp_ns : Wayland_EventTimestampMSToNS ( wl_timestamp_ms ) );
252
- }
236
+ const Uint64 adjustedTimestampMS = Wayland_EventTimestampMSToNS (wl_timestamp_ms );
237
+ return Wayland_AdjustEventTimestampBase (seat -> touch .timestamps ? seat -> touch .highres_timestamp_ns : adjustedTimestampMS );
238
+ }
253
239
254
- return 0 ;
240
+ static void input_timestamp_listener (void * data , struct zwp_input_timestamps_v1 * zwp_input_timestamps_v1 ,
241
+ uint32_t tv_sec_hi , uint32_t tv_sec_lo , uint32_t tv_nsec )
242
+ {
243
+ * ((Uint64 * )data ) = ((((Uint64 )tv_sec_hi << 32 ) | (Uint64 )tv_sec_lo ) * SDL_NS_PER_SECOND ) + tv_nsec ;
255
244
}
256
245
246
+ static const struct zwp_input_timestamps_v1_listener timestamp_listener = {
247
+ input_timestamp_listener
248
+ };
249
+
257
250
static void Wayland_SeatRegisterInputTimestampListeners (SDL_WaylandSeat * seat )
258
251
{
259
252
if (seat -> display -> input_timestamps_manager ) {
@@ -308,7 +301,7 @@ static bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, Uint6
308
301
while (elapsed >= repeat_info -> next_repeat_ns ) {
309
302
if (repeat_info -> scancode != SDL_SCANCODE_UNKNOWN ) {
310
303
const Uint64 timestamp = repeat_info -> wl_press_time_ns + repeat_info -> next_repeat_ns ;
311
- SDL_SendKeyboardKeyIgnoreModifiers (Wayland_GetEventTimestamp (timestamp ), repeat_info -> keyboard_id , repeat_info -> key , repeat_info -> scancode , true);
304
+ SDL_SendKeyboardKeyIgnoreModifiers (Wayland_AdjustEventTimestampBase (timestamp ), repeat_info -> keyboard_id , repeat_info -> key , repeat_info -> scancode , true);
312
305
}
313
306
if (repeat_info -> text [0 ]) {
314
307
SDL_SendKeyboardText (repeat_info -> text );
@@ -574,17 +567,15 @@ void Wayland_PumpEvents(SDL_VideoDevice *_this)
574
567
}
575
568
}
576
569
577
- static void pointer_handle_motion (void * data , struct wl_pointer * pointer ,
578
- uint32_t time , wl_fixed_t sx_w , wl_fixed_t sy_w )
570
+ static void pointer_handle_motion_common (SDL_WaylandSeat * seat , Uint64 nsTimestamp , wl_fixed_t sx_w , wl_fixed_t sy_w )
579
571
{
580
- SDL_WaylandSeat * seat = data ;
581
572
SDL_WindowData * window_data = seat -> pointer .focus ;
582
573
SDL_Window * window = window_data ? window_data -> sdlwindow : NULL ;
583
574
584
575
if (window_data ) {
585
576
const float sx = (float )(wl_fixed_to_double (sx_w ) * window_data -> pointer_scale .x );
586
577
const float sy = (float )(wl_fixed_to_double (sy_w ) * window_data -> pointer_scale .y );
587
- SDL_SendMouseMotion (Wayland_GetPointerTimestamp ( seat , time ) , window_data -> sdlwindow , seat -> pointer .sdl_id , false, sx , sy );
578
+ SDL_SendMouseMotion (nsTimestamp , window_data -> sdlwindow , seat -> pointer .sdl_id , false, sx , sy );
588
579
589
580
seat -> pointer .last_motion .x = (int )SDL_floorf (sx );
590
581
seat -> pointer .last_motion .y = (int )SDL_floorf (sy );
@@ -678,6 +669,13 @@ static void pointer_handle_motion(void *data, struct wl_pointer *pointer,
678
669
}
679
670
}
680
671
672
+ static void pointer_handle_motion (void * data , struct wl_pointer * pointer ,
673
+ uint32_t time , wl_fixed_t sx_w , wl_fixed_t sy_w )
674
+ {
675
+ SDL_WaylandSeat * seat = (SDL_WaylandSeat * )data ;
676
+ pointer_handle_motion_common (seat , Wayland_GetPointerTimestamp (seat , time ), sx_w , sy_w );
677
+ }
678
+
681
679
static void pointer_handle_enter (void * data , struct wl_pointer * pointer ,
682
680
uint32_t serial , struct wl_surface * surface ,
683
681
wl_fixed_t sx_w , wl_fixed_t sy_w )
@@ -706,7 +704,7 @@ static void pointer_handle_enter(void *data, struct wl_pointer *pointer,
706
704
* FIXME: This causes a movement event with an anomalous timestamp when
707
705
* the cursor enters the window.
708
706
*/
709
- pointer_handle_motion ( data , pointer , 0 , sx_w , sy_w );
707
+ pointer_handle_motion_common ( seat , 0 , sx_w , sy_w );
710
708
711
709
// Update the pointer grab state.
712
710
Wayland_SeatUpdatePointerGrab (seat );
@@ -845,11 +843,10 @@ static bool Wayland_ProcessHitTest(SDL_WaylandSeat *seat, Uint32 serial)
845
843
}
846
844
847
845
static void pointer_handle_button_common (SDL_WaylandSeat * seat , uint32_t serial ,
848
- uint32_t time , uint32_t button , uint32_t state_w )
846
+ Uint64 nsTimestamp , uint32_t button , uint32_t state_w )
849
847
{
850
848
SDL_WindowData * window = seat -> pointer .focus ;
851
849
enum wl_pointer_button_state state = state_w ;
852
- Uint64 timestamp = Wayland_GetPointerTimestamp (seat , time );
853
850
Uint8 sdl_button ;
854
851
const bool down = (state != 0 );
855
852
@@ -913,7 +910,7 @@ static void pointer_handle_button_common(SDL_WaylandSeat *seat, uint32_t serial,
913
910
}
914
911
915
912
if (!ignore_click ) {
916
- SDL_SendMouseButton (timestamp , window -> sdlwindow , seat -> pointer .sdl_id , sdl_button , down );
913
+ SDL_SendMouseButton (nsTimestamp , window -> sdlwindow , seat -> pointer .sdl_id , sdl_button , down );
917
914
}
918
915
}
919
916
}
@@ -922,15 +919,13 @@ static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32
922
919
uint32_t time , uint32_t button , uint32_t state_w )
923
920
{
924
921
SDL_WaylandSeat * seat = data ;
925
-
926
- pointer_handle_button_common (seat , serial , time , button , state_w );
922
+ pointer_handle_button_common (seat , serial , Wayland_GetPointerTimestamp (seat , time ), button , state_w );
927
923
}
928
924
929
925
static void pointer_handle_axis_common_v1 (SDL_WaylandSeat * seat ,
930
- uint32_t time , uint32_t axis , wl_fixed_t value )
926
+ Uint64 nsTimestamp , uint32_t axis , wl_fixed_t value )
931
927
{
932
928
SDL_WindowData * window = seat -> pointer .focus ;
933
- const Uint64 timestamp = Wayland_GetPointerTimestamp (seat , time );
934
929
const enum wl_pointer_axis a = axis ;
935
930
936
931
if (seat -> pointer .focus ) {
@@ -952,7 +947,7 @@ static void pointer_handle_axis_common_v1(SDL_WaylandSeat *seat,
952
947
x /= WAYLAND_WHEEL_AXIS_UNIT ;
953
948
y /= WAYLAND_WHEEL_AXIS_UNIT ;
954
949
955
- SDL_SendMouseWheel (timestamp , window -> sdlwindow , seat -> pointer .sdl_id , x , y , SDL_MOUSEWHEEL_NORMAL );
950
+ SDL_SendMouseWheel (nsTimestamp , window -> sdlwindow , seat -> pointer .sdl_id , x , y , SDL_MOUSEWHEEL_NORMAL );
956
951
}
957
952
}
958
953
@@ -1033,12 +1028,13 @@ static void pointer_handle_axis(void *data, struct wl_pointer *pointer,
1033
1028
uint32_t time , uint32_t axis , wl_fixed_t value )
1034
1029
{
1035
1030
SDL_WaylandSeat * seat = data ;
1031
+ const Uint64 nsTimestamp = Wayland_GetPointerTimestamp (seat , time );
1036
1032
1037
1033
if (wl_seat_get_version (seat -> wl_seat ) >= WL_POINTER_FRAME_SINCE_VERSION ) {
1038
- seat -> pointer .current_axis_info .timestamp_ns = Wayland_GetPointerTimestamp ( seat , time ) ;
1034
+ seat -> pointer .current_axis_info .timestamp_ns = nsTimestamp ;
1039
1035
pointer_handle_axis_common (seat , AXIS_EVENT_CONTINUOUS , axis , value );
1040
1036
} else {
1041
- pointer_handle_axis_common_v1 (seat , time , axis , value );
1037
+ pointer_handle_axis_common_v1 (seat , nsTimestamp , axis , value );
1042
1038
}
1043
1039
}
1044
1040
@@ -1166,7 +1162,7 @@ static void relative_pointer_handle_relative_motion(void *data,
1166
1162
SDL_Mouse * mouse = SDL_GetMouse ();
1167
1163
1168
1164
// Relative pointer event times are in microsecond granularity.
1169
- const Uint64 timestamp = Wayland_GetEventTimestamp (SDL_US_TO_NS (((Uint64 )time_hi << 32 ) | (Uint64 )time_lo ));
1165
+ const Uint64 timestamp = Wayland_AdjustEventTimestampBase (SDL_US_TO_NS (((Uint64 )time_hi << 32 ) | (Uint64 )time_lo ));
1170
1166
1171
1167
double dx ;
1172
1168
double dy ;
@@ -2022,7 +2018,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
2022
2018
2023
2019
const SDL_Scancode scancode = Wayland_GetScancodeForKey (seat , key );
2024
2020
Wayland_HandleModifierKeys (seat , scancode , state == WL_KEYBOARD_KEY_STATE_PRESSED );
2025
- Uint64 timestamp = Wayland_GetKeyboardTimestamp ( seat , time );
2021
+ Uint64 timestamp = Wayland_AdjustEventTimestampBase ( timestamp_raw_ns );
2026
2022
2027
2023
SDL_SendKeyboardKeyIgnoreModifiers (timestamp , seat -> keyboard .sdl_id , key , scancode , state == WL_KEYBOARD_KEY_STATE_PRESSED );
2028
2024
@@ -3243,7 +3239,7 @@ static void tablet_tool_handle_frame(void *data, struct zwp_tablet_tool_v2 *tool
3243
3239
return ; // Not a pen we report on.
3244
3240
}
3245
3241
3246
- const Uint64 timestamp = Wayland_GetEventTimestamp (Wayland_EventTimestampMSToNS (time ));
3242
+ const Uint64 timestamp = Wayland_AdjustEventTimestampBase (Wayland_EventTimestampMSToNS (time ));
3247
3243
const SDL_PenID instance_id = sdltool -> instance_id ;
3248
3244
SDL_Window * window = sdltool -> tool_focus ;
3249
3245
0 commit comments