acinclude/ac_check_define.m4
author Sam Lantinga <slouken@libsdl.org>
Thu, 25 Apr 2019 14:17:07 -0700
changeset 12723 24883e864f7e
parent 6491 03b7e6b0a8bf
permissions -rw-r--r--
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.
     1 AC_DEFUN([AC_CHECK_DEFINE],[dnl
     2   AC_CACHE_CHECK(for $1 in $2, ac_cv_define_$1,
     3     AC_EGREP_CPP([YES_IS_DEFINED], [
     4 #include <$2>
     5 #ifdef $1
     6 YES_IS_DEFINED
     7 #endif
     8     ], ac_cv_define_$1=yes, ac_cv_define_$1=no)
     9   )
    10   if test "$ac_cv_define_$1" = "yes" ; then
    11     AC_DEFINE([HAVE_$1],[],[Added by AC_CHECK_DEFINE])
    12   fi
    13 ])dnl
    14 AC_DEFINE([HAVE_$1],[],[Added by AC_CHECK_DEFINE])