Hi!
I couldn’t get key repeat to work, i.e. even though I called SDL_EnableKeyRepeat, I didn’t receive any repeat events.
The reason turned out to be that my event handler was hooked in with SDL_SetEventFilter, and there’s a bug in the
KeyRepeat function, so that it “forgets” to filter the repeat events before pushing them.
To fix that, the following changes must be made in SDL_keyboard.c:
In function SDL_CheckKeyRepeat:
if ( interval > (Uint32)SDL_KeyRepeat.interval ) {
SDL_KeyRepeat.timestamp = now;
SDL_PushEvent(&SDL_KeyRepeat.evt);
}
must be:
if ( interval > (Uint32)SDL_KeyRepeat.interval ) {
SDL_KeyRepeat.timestamp = now;
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&SDL_KeyRepeat.evt) ) {
SDL_PushEvent(&SDL_KeyRepeat.evt);
}
}
In function SDL_PrivateKeyboard, the activation of the key repeats is currently done only if the event filter
lets the initial SDL_KEYDOWN event pass through. So no key repeat events will be generated if the event filter
blocks the first SDL_KEYDOWN event. I think this behavior doesn’t match the description in the doc:
SDL_SetEventFilter – Sets up a filter to process all events before they are posted to the event queue.
“All events” means that the filter can in principle receive all events, not that the received events depend
on some previous filter behavior. To fix that, the code block
if ( (SDL_EventOK == NULL) || SDL_EventOK(&event) ) {
posted = 1;
/*
- jk 991215 - Added
*/
if (repeatable && (SDL_KeyRepeat.delay != 0)) {
SDL_KeyRepeat.evt = event;
SDL_KeyRepeat.firsttime = 1;
SDL_KeyRepeat.timestamp=SDL_GetTicks();
}
SDL_PushEvent(&event);
}
must be changed to:
/*
- jk 991215 - Added
*/
if (repeatable && (SDL_KeyRepeat.delay != 0)) {
SDL_KeyRepeat.evt = event;
SDL_KeyRepeat.firsttime = 1;
SDL_KeyRepeat.timestamp=SDL_GetTicks();
}
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
posted = 1;
SDL_PushEvent(&event);
}
Ciao,
Elmar