| Summary: | Android back button does not send SDL_KEYDOWN event | ||
|---|---|---|---|
| Product: | SDL | Reporter: | someuniquename |
| Component: | *don't know* | Assignee: | Sylvain <sylvain.becker> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | critical | ||
| Priority: | P2 | Keywords: | target-2.0.10 |
| Version: | 2.0.10 | ||
| Hardware: | ARM | ||
| OS: | Android (All) | ||
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) 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). 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 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 (That is trace from SDLActivity.java) 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. 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 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 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." > I also see the onDispatchEvent() + keyCode = 4
what is onDispatchEvent? i don't see it in SDLACtivity.java
Sorry, I mean't dispatchKeyEvent also the SDLK_AC_BACK should arrive through onKey(), then SDLActivity.onNativeKeyDown() I think 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 And u think it explains why the issue is cured after user invokes Android keyboard - the event changes source from zero to keyboard 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);
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() 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 ? Tested it on kivy app, and it works! |
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)