Hi
I’m writing an application that needs to react to button inputs from a controller (which presents as a joystick via SDL2), while it is also being used by another (third-party) application. This works in principle, however as soon as I open a window, my application only receives events while that window is in focus. I suspect they are being filtered by SDL2 internally somehow. Is there any way to change this behaviour and always receive all joystick events? I only need this to work on Linux.
For reference, I’ll paste my test code below. The program opens all connected joysticks, prints a line whenever a button is pressed or depressed, and quits when the last joystick is disconnected. When compiled and run with argument “window”, it opens a window, and only receives joystick button events while the window is in focus. Otherwise, it doesn’t open a window and always receives events.
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
int main(int argc, char *argv[]) {
atexit(SDL_Quit);
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) {
return EXIT_FAILURE;
}
SDL_DisableScreenSaver();
int open_window = (argc == 2) && (strcmp(argv[1], "window") == 0);
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
if (open_window) {
window = SDL_CreateWindow("window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 360, 0);
if (!window) {
return EXIT_FAILURE;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
if (!renderer) {
return EXIT_FAILURE;
}
}
int done = 0;
while (!done) {
if (open_window) {
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
else {
SDL_Delay(16); // ms
}
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_JOYDEVICEADDED:
SDL_Joystick *controller = SDL_JoystickOpen(event.jdevice.which);
if (!controller) {
fprintf(stderr, "Couldn't open controller: %s\n", SDL_GetError());
return EXIT_FAILURE;
}
printf("Controller %d added\n", SDL_JoystickInstanceID(controller));
break;
case SDL_JOYDEVICEREMOVED:
printf("Controller %d removed\n", event.jdevice.which);
if (SDL_NumJoysticks() == 0) {
done = 1;
}
break;
case SDL_JOYBUTTONDOWN:
printf("controller %d button %d down\n", event.jbutton.which, event.jbutton.button);
break;
case SDL_JOYBUTTONUP:
printf("controller %d button %d up\n", event.jbutton.which, event.jbutton.button);
break;
case SDL_KEYDOWN:
printf("key down event\n");
if (event.key.keysym.sym == SDLK_ESCAPE) {
done = 1;
}
break;
default:
break;
}
}
}
}