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 4702 - Android back button does not send SDL_KEYDOWN event
Summary: Android back button does not send SDL_KEYDOWN event
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: *don't know* (show other bugs)
Version: 2.0.10
Hardware: ARM Android (All)
: P2 critical
Assignee: Sylvain
QA Contact: Sam Lantinga
URL:
Keywords: target-2.0.10
Depends on:
Blocks:
 
Reported: 2019-07-01 13:05 UTC by someuniquename
Modified: 2019-07-03 16:22 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description someuniquename 2019-07-01 13:05:34 UTC
sdl version: 2.0.8 - current hg tip

i have enabled the SDL_ANDROID_TRAP_BACK_BUTTON hint:

    SDL_SetHintWithPriority("SDL_ANDROID_TRAP_BACK_BUTTON", "1", SDL_HINT_OVERRIDE);

But the app does not receive any SDL_KEYDOWN event when button is pressed.

Sample c code: https://gist.github.com/Fak3/f5d14e946f8fdb9c22fcf794ae466e41
Failing apk: https://drive.google.com/file/d/1I5mKskgPEUHdx_VjM9ygYhHhqgXLRZ1D/view?usp=sharing

Same issue arise in a kivy app, but it is cured when user invokes keyboard, and then closes it (keyboard). From that point back button properly sends SDL_KEYDOWN to the event loop (but it brokes again when app is minimized then maximized)
Comment 1 Sylvain 2019-07-02 09:00:45 UTC
if you don't set the hint at all, what happens ? 

don't you get 
evt.type == SDL_KEYDOWN 
and 
evt.key.keysym.sym == SDLK_AC_BACK ?


I receive those events without using the hint. 
but according to the doc, it should be set to 1.
https://hg.libsdl.org/SDL/file/d3a97780aa05/include/SDL_hints.h#l859


(there was this recent issue also: bug 4657)
Comment 2 someuniquename 2019-07-02 09:51:42 UTC
If I don;t set hint or set it to "0" I don't receive any SDL_KEYDOWN event either. But the app now closes on back button press, log:
07-02 12:51:07.802 V/SDL     (12980): onWindowFocusChanged(): false
07-02 12:51:07.802 V/SDL     (12980): nativeFocusChanged()
07-02 12:51:07.802 V/SDL     (12980): nativePause()
07-02 12:51:08.312 V/SDL     (12980): onPause()
07-02 12:51:08.592 V/SDL     (12980): COMMAND_CHANGE_WINDOW_STYLE
07-02 12:51:08.592 V/SDL     (12980): SDLActivity.mFullscreenModeActive = false;
07-02 12:51:08.622 V/SDL     (12980): surfaceDestroyed()
07-02 12:51:09.262 V/SDL     (12980): onStop()
07-02 12:51:09.262 V/SDL     (12980): onDestroy()

I actually want to prevent the app from closing, and handle the button press in the app (go back in history).
Comment 3 someuniquename 2019-07-02 10:10:32 UTC
I have tested this bug in kivy app almost 2 years ago with 2 devices: I could reproduce it on ZTE nubia z11 mini, but not my other phone - some samsung, also with Android 5.x
Comment 4 someuniquename 2019-07-02 10:20:17 UTC
I have added more trace, and in both cases, with or without hint, i receive these in the log:


07-02 13:21:03.452 V/SDL     (17399): dispatchKeyEvent 4
07-02 13:21:03.462 V/SDL     (17399): dispatchKeyEvent 4
07-02 13:21:03.462 V/SDL     (17399): onBackPressed
Comment 5 someuniquename 2019-07-02 10:21:57 UTC
(That is trace from SDLActivity.java)
Comment 6 someuniquename 2019-07-02 10:24:41 UTC
Back then, 2 years ago I had to patch onBackPressed() function to actually send SDL_KEYDOWN event to fix the issue, but I don't exactly remember how I did that.
And I'm not sure if my approach was correct.
Comment 7 someuniquename 2019-07-02 10:35:56 UTC
Some more trace prints, from onKey() handler:

07-02 13:37:01.192 V/SDL     (20565): dispatchKeyEvent 4
07-02 13:37:01.202 V/SDL     (20565): onKey source 0, keycode 4
07-02 13:37:01.202 V/SDL     (20565): onKey exit
07-02 13:37:01.232 V/SDL     (20565): dispatchKeyEvent 4
07-02 13:37:01.232 V/SDL     (20565): onKey source 0, keycode 4
07-02 13:37:01.232 V/SDL     (20565): onKey exit
07-02 13:37:01.232 V/SDL     (20565): onBackPressed
Comment 8 Sylvain 2019-07-02 11:18:32 UTC
I also see the onDispatchEvent() + keyCode = 4


But, this is strange, onBackPressed() is never called for me.
Whatever the return value is in onDispatchEvent() (which tell if the event is handled or not).

(tried on android 5.0.2 and recent)


Which version are you using for:
NDK ?
compileSdkVersion ?
targetSdkVersion
Comment 9 someuniquename 2019-07-02 12:06:44 UTC
ndk-r17c
compile and target sdk is 26

the bug also exists with compile 28, and some older (tried 2 years ago), target 19 and 21

That's odd if you don't receive onBackPressed, from the docs it seems that you have to receive it on each press: https://developer.android.com/reference/android/app/Activity#onBackPressed()
"Called when the activity has detected the user's press of the back key. The default implementation simply finishes the current activity, but you can override this to do whatever you want."
Comment 10 someuniquename 2019-07-02 12:18:31 UTC
> I also see the onDispatchEvent() + keyCode = 4

what is onDispatchEvent? i don't see it in SDLACtivity.java
Comment 11 Sylvain 2019-07-02 17:10:42 UTC
Sorry, I mean't dispatchKeyEvent


also the SDLK_AC_BACK should arrive through onKey(), then SDLActivity.onNativeKeyDown() I think
Comment 12 someuniquename 2019-07-02 17:41:46 UTC
It does not reach onNativeKeyDown because the event has source of 0 and it's ignored in onKey handler (as my trace shows)
So I think the issue is onKey handler - it should pass down the event with keycode 4 (back button), even if it's source is 0
Comment 13 someuniquename 2019-07-02 17:48:50 UTC
And u think it explains why the issue is cured after user invokes Android keyboard - the event changes source from zero to keyboard
Comment 14 Sylvain 2019-07-02 20:00:11 UTC
ok, this is clearer now.
So event.getSource() == 0 is in fact INPUT_UNKNOWN as you found out.

If I also return false from onKey(), I see the onBackPressed() now.

maybe a patch could be, in onKey:
before:
if ((event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
after:
if (
  (event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0
 ||
  event.getSource() == InputDevice.SOURCE_UNKNOWN
) {


but..
1/ can you check other buttons (home, menu, volume) from the phone, to see which source they have ?

2/
can you see which is the type of device when you press BACK, like in:
https://hg.libsdl.org/SDL/file/73091a9e72f7/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java#l91

doing something like:
 
int deviceId = event.getDeviceId()
InputDevice device = InputDevice.getDevice(deviceId);
int sources = device.getSources();
Log.v(TAG, "Input device " + device.getName() + "sources=" + sources);
Comment 15 someuniquename 2019-07-03 10:34:34 UTC
back button:
07-03 13:16:52.973 V/SDL     ( 4199): dispatchKeyEvent 4 Input device Virtual sources=769
07-03 13:16:52.973 V/SDL     ( 4199): onKey source 0, keycode 4
07-03 13:16:52.973 V/SDL     ( 4199): onKey exit
07-03 13:16:52.993 V/SDL     ( 4199): dispatchKeyEvent 4 Input device Virtual sources=769
07-03 13:16:52.993 V/SDL     ( 4199): onKey source 0, keycode 4
07-03 13:16:52.993 V/SDL     ( 4199): onKey exit
07-03 13:16:52.993 V/SDL     ( 4199): onBackPressed


Menu button:
07-03 13:17:42.363 V/SDL     ( 4199): dispatchKeyEvent 82 Input device Virtual sources=769
07-03 13:17:42.363 V/SDL     ( 4199): onKey source 0, keycode 82
07-03 13:17:42.363 V/SDL     ( 4199): onKey exit
07-03 13:17:42.373 V/SDL     ( 4199): dispatchKeyEvent 82 Input device Virtual sources=769
07-03 13:17:42.373 V/SDL     ( 4199): onKey source 0, keycode 82
07-03 13:17:42.373 V/SDL     ( 4199): onKey exit

Home button minimizes the app without any key event:
07-03 13:18:04.633 V/SDL     ( 4199): onWindowFocusChanged(): false
07-03 13:18:04.633 V/SDL     ( 4199): nativeFocusChanged()
07-03 13:18:04.633 V/SDL     ( 4199): nativePause()
07-03 13:18:05.143 V/SDL     ( 4199): COMMAND_CHANGE_WINDOW_STYLE
07-03 13:18:05.143 V/SDL     ( 4199): SDLActivity.mFullscreenModeActive = false;
07-03 13:18:05.143 V/SDL     ( 4199): onPause()
07-03 13:18:05.193 V/SDL     ( 4199): surfaceChanged()
07-03 13:18:05.193 V/SDL     ( 4199): pixel format RGBA_8888
07-03 13:18:05.193 V/SDL     ( 4199): Window size: 1080x1845
07-03 13:18:05.193 V/SDL     ( 4199): Device size: 1080x1920
07-03 13:18:05.293 V/SDL     ( 4199): onSystemUiVisibilityChange start
07-03 13:18:05.403 V/SDL     ( 4199): surfaceDestroyed()
07-03 13:18:05.713 V/SDL     ( 4199): onStop()
Comment 16 Sylvain 2019-07-03 11:40:49 UTC
Seems good, because sources=769 is a combination of several keyboard, button, dpad..

https://developer.android.com/reference/android/view/InputDevice.html

Here's a patch:
https://hg.libsdl.org/SDL/rev/b5cd5e1e4440
Can you double-check it ?
Comment 17 someuniquename 2019-07-03 16:22:26 UTC
Tested it on kivy app, and it works!