Fixed bug 4580 - Android 8: immersive fullscreen notification causes flickering between fullscreen and non-fullscreen and app is unresponsive

Sylvain 2019-04-18 21:22:59 UTC

Changes:
- SDL_WINDOWEVENT_FOCUS_GAINED and SDL_WINDOWEVENT_FOCUS_LOST are sent when the java method onWindowFocusChanged() is called.

- If we have support for MultiWindow (eg API >= 24), SDL event loop is blocked/un-blocked (or simply egl-backed-up or not), when java onStart()/onStop() are called.

- If not, this behaves like now, SDL event loop is blocked/un-blocked when onPause()/onResume() are called.

So if we have two app on screen and switch from one to the other, only FOCUS events are sent (and onPause()/onResume() are called but empty. onStart()/onStop() are not called).
The SDL app, un-focused, would still continue to run and display frames (currently the App would be displayed, but paused).
Like a video player app or a chronometer that would still be refreshed, even if the window hasn't the focus.
It should work also on ChromeBooks (not tested), with two apps opened at the same time.


I am not sure this fix Dan's issue. Because focus lost event triggers Minimize function (which BTW is not provided on android).
https://hg.libsdl.org/SDL/file/bb41b3635c34/src/video/SDL_video.c#l2653
https://hg.libsdl.org/SDL/file/bb41b3635c34/src/video/SDL_video.c#l2634

So, in addition, it would need to add by default SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS to 0.
So that the lost focus event doesn't try to minimize the window. And this should fix also the issue.
This commit is contained in:
Sam Lantinga 2019-04-22 16:19:52 -07:00
parent 2f6c988e7c
commit 9950271bb6
2 changed files with 69 additions and 17 deletions

View File

@ -38,6 +38,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL"; private static final String TAG = "SDL";
public static boolean mIsResumedCalled, mHasFocus; public static boolean mIsResumedCalled, mHasFocus;
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24);
// Cursor types // Cursor types
private static final int SDL_SYSTEM_CURSOR_NONE = -1; private static final int SDL_SYSTEM_CURSOR_NONE = -1;
@ -274,16 +275,12 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
} }
} }
// Events protected void pauseNativeThread() {
@Override
protected void onPause() {
Log.v(TAG, "onPause()");
super.onPause();
mNextNativeState = NativeState.PAUSED; mNextNativeState = NativeState.PAUSED;
mIsResumedCalled = false; mIsResumedCalled = false;
if (SDLActivity.mBrokenLibraries) { if (SDLActivity.mBrokenLibraries) {
return; return;
} }
if (mHIDDeviceManager != null) { if (mHIDDeviceManager != null) {
@ -293,10 +290,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
SDLActivity.handleNativeState(); SDLActivity.handleNativeState();
} }
@Override protected void resumeNativeThread() {
protected void onResume() {
Log.v(TAG, "onResume()");
super.onResume();
mNextNativeState = NativeState.RESUMED; mNextNativeState = NativeState.RESUMED;
mIsResumedCalled = true; mIsResumedCalled = true;
@ -311,6 +305,43 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
SDLActivity.handleNativeState(); SDLActivity.handleNativeState();
} }
// Events
@Override
protected void onPause() {
Log.v(TAG, "onPause()");
super.onPause();
if (!mHasMultiWindow) {
pauseNativeThread();
}
}
@Override
protected void onResume() {
Log.v(TAG, "onResume()");
super.onResume();
if (!mHasMultiWindow) {
resumeNativeThread();
}
}
@Override
protected void onStop() {
Log.v(TAG, "onStop()");
super.onStop();
if (mHasMultiWindow) {
pauseNativeThread();
}
}
@Override
protected void onStart() {
Log.v(TAG, "onStart()");
super.onStart();
if (mHasMultiWindow) {
resumeNativeThread();
}
}
public static int getCurrentOrientation() { public static int getCurrentOrientation() {
final Context context = SDLActivity.getContext(); final Context context = SDLActivity.getContext();
final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
@ -347,15 +378,21 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
return; return;
} }
SDLActivity.mHasFocus = hasFocus; mHasFocus = hasFocus;
if (hasFocus) { if (hasFocus) {
mNextNativeState = NativeState.RESUMED; mNextNativeState = NativeState.RESUMED;
SDLActivity.getMotionListener().reclaimRelativeMouseModeIfNeeded(); SDLActivity.getMotionListener().reclaimRelativeMouseModeIfNeeded();
} else {
mNextNativeState = NativeState.PAUSED;
}
SDLActivity.handleNativeState(); SDLActivity.handleNativeState();
nativeFocusChanged(true);
} else {
nativeFocusChanged(false);
if (!mHasMultiWindow) {
mNextNativeState = NativeState.PAUSED;
SDLActivity.handleNativeState();
}
}
} }
@Override @Override
@ -719,6 +756,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
public static native void nativeQuit(); public static native void nativeQuit();
public static native void nativePause(); public static native void nativePause();
public static native void nativeResume(); public static native void nativeResume();
public static native void nativeFocusChanged(boolean hasFocus);
public static native void onNativeDropFile(String filename); public static native void onNativeDropFile(String filename);
public static native void nativeSetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, int format, float rate); public static native void nativeSetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, int format, float rate);
public static native void onNativeResize(); public static native void onNativeResize();

View File

@ -131,6 +131,9 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)(
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
JNIEnv *env, jclass cls); JNIEnv *env, jclass cls);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)(
JNIEnv *env, jclass cls, jboolean hasFocus);
JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)( JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
JNIEnv *env, jclass cls, JNIEnv *env, jclass cls,
jstring name); jstring name);
@ -1034,7 +1037,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)(
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativePause()"); __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativePause()");
if (Android_Window) { if (Android_Window) {
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND); SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND); SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
@ -1060,7 +1062,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
if (Android_Window) { if (Android_Window) {
SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND); SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND); SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0); SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0);
} }
@ -1073,6 +1074,19 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
SDL_UnlockMutex(Android_ActivityMutex); SDL_UnlockMutex(Android_ActivityMutex);
} }
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);
}
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
JNIEnv *env, jclass cls, JNIEnv *env, jclass cls,
jstring text, jint newCursorPosition) jstring text, jint newCursorPosition)