diff --git a/include/SDL_hints.h b/include/SDL_hints.h index c96d88745..e38a577bd 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -215,6 +215,20 @@ extern "C" { #define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG" +/** + * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background. + * + * The default value is "0". + * + * The variable can be set to the following values: + * "0" - Disable joystick & gamecontroller input events when the + * application is in the background. + * "1" - Enable joystick & gamecontroller input events when the + * application is in the backgroumd. + */ +#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" + + /** * \brief If set to 0 then never set the top most bit on a SDL Window, even if the video mode expects it. * This is a debugging aid for developers and not expected to be used by end users. The default is "1" diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 0e9c3f74c..0342e6ba9 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -25,6 +25,7 @@ #include "SDL_events.h" #include "SDL_sysjoystick.h" #include "SDL_assert.h" +#include "SDL_hints.h" #if !SDL_EVENTS_DISABLED #include "../events/SDL_events_c.h" @@ -451,6 +452,22 @@ SDL_JoystickQuit(void) } +static SDL_bool +SDL_PrivateJoystickShouldIgnoreEvent() +{ + const char *hint; + if (SDL_GetKeyboardFocus() != NULL) { + return SDL_FALSE; + } + + hint = SDL_GetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS); + if (hint && *hint == '1') { + return SDL_FALSE; + } + + return SDL_TRUE; +} + /* These are global for SDL_sysjoystick.c and SDL_events.c */ int @@ -469,6 +486,15 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) } joystick->axes[axis] = value; + /* We ignore events if we don't have keyboard focus, except for centering + * events. + */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + if (!(joystick->closed && joystick->uncentered)) { + return 0; + } + } + /* Post the event, if desired */ posted = 0; #if !SDL_EVENTS_DISABLED @@ -497,6 +523,16 @@ SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value) /* Update internal joystick state */ joystick->hats[hat] = value; + /* We ignore events if we don't have keyboard focus, except for centering + * events. + */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + if (!(joystick->closed && joystick->uncentered)) { + return 0; + } + } + + /* Post the event, if desired */ posted = 0; #if !SDL_EVENTS_DISABLED @@ -523,6 +559,11 @@ SDL_PrivateJoystickBall(SDL_Joystick * joystick, Uint8 ball, return 0; } + /* We ignore events if we don't have keyboard focus. */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + return 0; + } + /* Update internal mouse state */ joystick->balls[ball].dx += xrel; joystick->balls[ball].dy += yrel; @@ -568,6 +609,12 @@ SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state) return 0; } + /* We ignore events if we don't have keyboard focus, except for button + * release. */ + if (SDL_PrivateJoystickShouldIgnoreEvent() && event.type == SDL_JOYBUTTONDOWN) { + return 0; + } + /* Update internal joystick state */ joystick->buttons[button] = state; @@ -605,7 +652,6 @@ SDL_JoystickUpdate(void) if ( joystick->closed && joystick->uncentered ) { int i; - joystick->uncentered = 0; /* Tell the app that everything is centered/unpressed... */ for (i = 0; i < joystick->naxes; i++) @@ -617,6 +663,7 @@ SDL_JoystickUpdate(void) for (i = 0; i < joystick->nhats; i++) SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); + joystick->uncentered = 0; } SDL_updating_joystick = NULL;