Commit 461724d287a512b8bd0fe8daa3c63e954025b77c

Joan Bruguera 2022-01-08T19:09:35

wayland: Refactor time fields in SDL_WaylandKeyboardRepeat Refactorization with no functional changes. Instead of `next_repeat_ms` containing a timestamp based on SDL ticks, we make it zero-based relative to the key press time, and we store the key press time in SDL ticks in a new field. This refactorization is groundwork for future commits which need to use the key press and release timestamps provided by the Wayland API, which are also expressed in milliseconds, but whose base does not match the one for SDL ticks. Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>

diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 956d5af..1ee8da9 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -204,13 +204,10 @@ touch_surface(SDL_TouchID id)
 
 /* Returns SDL_TRUE if a key repeat event was due */
 static SDL_bool
-keyboard_repeat_handle(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t now)
+keyboard_repeat_handle(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t elapsed)
 {
     SDL_bool ret = SDL_FALSE;
-    if (!repeat_info->is_key_down || !repeat_info->is_initialized) {
-        return ret;
-    }
-    while ((now - repeat_info->next_repeat_ms) < 0x80000000U) {
+    while ((elapsed - repeat_info->next_repeat_ms) < 0x80000000U) {
         if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) {
             SDL_SendKeyboardKey(SDL_PRESSED, repeat_info->scancode);
         }
@@ -238,7 +235,8 @@ keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info,
         return;
     }
     repeat_info->is_key_down = SDL_TRUE;
-    repeat_info->next_repeat_ms = SDL_GetTicks() + repeat_info->repeat_delay;
+    repeat_info->sdl_press_time = SDL_GetTicks();
+    repeat_info->next_repeat_ms = repeat_info->repeat_delay;
     repeat_info->scancode = scancode;
     if (has_text) {
         SDL_memcpy(repeat_info->text, text, 8);
@@ -247,6 +245,10 @@ keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info,
     }
 }
 
+static SDL_bool keyboard_repeat_is_set(SDL_WaylandKeyboardRepeat* repeat_info) {
+    return repeat_info->is_initialized && repeat_info->is_key_down;
+}
+
 void
 Wayland_SendWakeupEvent(_THIS, SDL_Window *window)
 {
@@ -273,13 +275,13 @@ Wayland_WaitEventTimeout(_THIS, int timeout)
 #endif
 
     /* If key repeat is active, we'll need to cap our maximum wait time to handle repeats */
-    if (input && input->keyboard_repeat.is_initialized && input->keyboard_repeat.is_key_down) {
-        uint32_t now = SDL_GetTicks();
-        if (keyboard_repeat_handle(&input->keyboard_repeat, now)) {
+    if (input && keyboard_repeat_is_set(&input->keyboard_repeat)) {
+        uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time;
+        if (keyboard_repeat_handle(&input->keyboard_repeat, elapsed)) {
             /* A repeat key event was already due */
             return 1;
         } else {
-            uint32_t next_repeat_wait_time = (input->keyboard_repeat.next_repeat_ms - now) + 1;
+            uint32_t next_repeat_wait_time = (input->keyboard_repeat.next_repeat_ms - elapsed) + 1;
             if (timeout >= 0) {
                 timeout = SDL_min(timeout, next_repeat_wait_time);
             } else {
@@ -305,8 +307,8 @@ Wayland_WaitEventTimeout(_THIS, int timeout)
 
             /* If key repeat is active, we might have woken up to generate a key event */
             if (key_repeat_active) {
-                uint32_t now = SDL_GetTicks();
-                if (keyboard_repeat_handle(&input->keyboard_repeat, now)) {
+                uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time;
+                if (keyboard_repeat_handle(&input->keyboard_repeat, elapsed)) {
                     return 1;
                 }
             }
@@ -346,9 +348,9 @@ Wayland_PumpEvents(_THIS)
     }
 #endif
 
-    if (input) {
-        uint32_t now = SDL_GetTicks();
-        keyboard_repeat_handle(&input->keyboard_repeat, now);
+    if (input && keyboard_repeat_is_set(&input->keyboard_repeat)) {
+        uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time;
+        keyboard_repeat_handle(&input->keyboard_repeat, elapsed);
     }
 
     /* wl_display_prepare_read() will return -1 if the default queue is not empty.
diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h
index 1ed4924..a106823 100644
--- a/src/video/wayland/SDL_waylandevents_c.h
+++ b/src/video/wayland/SDL_waylandevents_c.h
@@ -36,6 +36,7 @@ typedef struct {
     SDL_bool is_initialized;
 
     SDL_bool is_key_down;
+    uint32_t sdl_press_time; // Key press time expressed in SDL ticks
     uint32_t next_repeat_ms;
     uint32_t scancode;
     char text[8];