We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3237

Summary: Android: When physical keyboards get opened with SDL_JoystickOpen, it breaks arrow key events
Product: SDL Reporter: Anthony @ POW Games <ant>
Component: joystickAssignee: ny00
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: sylvain.becker
Version: 2.0.4   
Hardware: All   
OS: Android (All)   

Description Anthony @ POW Games 2016-01-12 15:06:13 UTC
This is a major problem for me because arrow keys are used on Android TV remotes to navigate menus.

Here's what happens: Android lists many non-joystick devices under SDL_NumJoysticks(), including physical keyboards. It's not possible to distinguish between real game controllers and soft keyboards and physical keyboards, so they all get opened with SDL_JoystickOpen(). Once a physical keyboard gets opened, the arrow key events (SDLK_UP, SDLK_DOWN, etc) stop coming from that keyboard. Instead, I get SDL_JOYBUTTONDOWN and SDL_JOYBUTTONUP events with button index numbers ranging from 11 to 14. So effectively, keyboard arrows get converted into joystick fire buttons. I could hack this behaviour and treat joystick button 11 as UP and 12 as DOWN, but I have USB game controllers with buttons of the same index. 

This happens with ANY physical keyboard USB, or bluetooth. I have a collection of 6 USB game controllers including an XBOX one. Only the XBOX one is (SDL_IsGameController()), and that doesn't work on any of my Android devices, so I can't even use SDL_IsGameController() to filter out the fake keyboard game controllers.

If I mess around with SDLActivity.java's "public boolean onKey(View  v, int keyCode, KeyEvent event)", I can half fix it, but I don't really know what I'm doing there...
Comment 1 Anthony @ POW Games 2016-01-12 15:29:21 UTC
In SDLActivity.java I propose adding:

&& (joystickDevice.getSources() & InputDevice.SOURCE_KEYBOARD) == 0

to the condition in pollInputDevices() that decides to add the joystick.

This filters out keyboards. I see no reason why a keyboard needs to be added as a joystick on the Android platform. It causes a lot of problems when trying to use real USB joysticks and it breaks the events from keyboards.
Comment 2 Sam Lantinga 2016-09-29 23:54:35 UTC
Can you check whether the latest version in Mercurial fixes your issue?
http://www.libsdl.org/tmp/SDL-2.0.zip

Thanks!
Comment 3 Sylvain 2016-10-07 07:49:35 UTC
This bug talks somehow about this issue: https://bugzilla.libsdl.org/show_bug.cgi?id=3444
Comment 4 Sylvain 2016-10-17 20:35:22 UTC
> I could hack this behaviour and treat joystick button 11 as UP and 12 as DOWN, 
> but I have USB game controllers with buttons of the same index. 

11, 12, 13, 14 are meant to be:

SDL_CONTROLLER_BUTTON_DPAD_UP,
SDL_CONTROLLER_BUTTON_DPAD_DOWN,
SDL_CONTROLLER_BUTTON_DPAD_LEFT,
SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
Comment 5 Sam Lantinga 2016-10-18 05:10:36 UTC
Fixed, thanks!
https://hg.libsdl.org/SDL/rev/a5bc0d82dca4