Fixed bug 4608 - Android: not getting SDL_WINDOWEVENT_FOCUS_GAINED on start of our app
authorSam Lantinga <slouken@libsdl.org>
Thu, 25 Apr 2019 14:17:07 -0700
changeset 1272324883e864f7e
parent 12720 f926c8070a2a
child 12724 19c373658809
Fixed bug 4608 - Android: not getting SDL_WINDOWEVENT_FOCUS_GAINED on start of our app

Dan Ginsburg

I've seen this on several devices including Moto Z running Android 7 and a Snapdragon 845 running Android 9.

What happens is as follows:

SDLActivity.onWindowFocusChanged(true) happens pretty early on, but it's before we've done SDL_CreateWindow and so Android_Window is 0x0 thus this message does not get sent:

JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)(
JNIEnv *env, jclass cls, jboolean hasFocus)
{
SDL_LockMutex(Android_ActivityMutex);

if (Android_Window) {
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeFocusChanged()");
SDL_SendWindowEvent(Android_Window, (hasFocus ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST), 0, 0);
}

SDL_UnlockMutex(Android_ActivityMutex);
}

When the window does get created, in Android_CreateWindow it does this:

window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizeable */
window->flags &= ~SDL_WINDOW_HIDDEN;
window->flags |= SDL_WINDOW_SHOWN; /* only one window on Android */
window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */

/* One window, it always has focus */
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);

The SDL_SetKeyboardFocus does send an SDL_WINDOWEVENT_FOCUS_GAINED message, but it gets eaten in SDL_SendWindowEvent because we've forced SDL_WINDOW_INPUT_FOCUS beforehand:

case SDL_WINDOWEVENT_FOCUS_GAINED:
if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
return 0;
}
window->flags |= SDL_WINDOW_INPUT_FOCUS;
SDL_OnWindowFocusGained(window);
break;

I can fix the problem if I comment out this line from Android_CreateWindow:

window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */

I would propose that as a fix unless there is a reason not to.
src/video/android/SDL_androidwindow.c
     1.1 --- a/src/video/android/SDL_androidwindow.c	Wed Apr 24 12:53:15 2019 -0700
     1.2 +++ b/src/video/android/SDL_androidwindow.c	Thu Apr 25 14:17:07 2019 -0700
     1.3 @@ -61,7 +61,6 @@
     1.4      window->flags &= ~SDL_WINDOW_RESIZABLE;     /* window is NEVER resizeable */
     1.5      window->flags &= ~SDL_WINDOW_HIDDEN;
     1.6      window->flags |= SDL_WINDOW_SHOWN;          /* only one window on Android */
     1.7 -    window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */
     1.8  
     1.9      /* One window, it always has focus */
    1.10      SDL_SetMouseFocus(window);