event: Cap maximum wait time if sensor or joystick subsystems are active Joystick and sensor subsystems require periodic polling to detect new devices.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index 074da1a..2e79852 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -44,6 +44,9 @@
/* An arbitrary limit so we don't have unbounded growth */
#define SDL_MAX_QUEUED_EVENTS 65535
+/* Determines how often we wake to call SDL_PumpEvents() in SDL_WaitEventTimeout_Device() */
+#define PERIODIC_POLL_INTERVAL_MS 3000
+
typedef struct SDL_EventWatcher {
SDL_EventFilter callback;
void *userdata;
@@ -795,10 +798,29 @@ SDL_PollEvent(SDL_Event * event)
return SDL_WaitEventTimeout(event, 0);
}
+static SDL_bool
+SDL_events_need_periodic_poll() {
+ SDL_bool need_periodic_poll = SDL_FALSE;
+
+#if !SDL_JOYSTICK_DISABLED
+ need_periodic_poll =
+ SDL_WasInit(SDL_INIT_JOYSTICK) &&
+ (!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY));
+#endif
+
+#if !SDL_SENSOR_DISABLED
+ need_periodic_poll = need_periodic_poll ||
+ (SDL_WasInit(SDL_INIT_SENSOR) && !SDL_disabled_events[SDL_SENSORUPDATE >> 8]);
+#endif
+
+ return need_periodic_poll;
+}
+
static int
SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event, Uint32 start, int timeout)
{
int loop_timeout = timeout;
+ SDL_bool need_periodic_poll = SDL_events_need_periodic_poll();
for (;;) {
/* Pump events on entry and each time we wake to ensure:
@@ -838,6 +860,13 @@ SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event,
}
loop_timeout = (int)((Uint32)timeout - elapsed);
}
+ if (need_periodic_poll) {
+ if (loop_timeout >= 0) {
+ loop_timeout = SDL_min(loop_timeout, PERIODIC_POLL_INTERVAL_MS);
+ } else {
+ loop_timeout = PERIODIC_POLL_INTERVAL_MS;
+ }
+ }
status = _this->WaitEventTimeout(_this, loop_timeout);
/* Set wakeup_window to NULL without holding the lock. */
_this->wakeup_window = NULL;