Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Android patch to disable system bars #2265

Open
SDLBugzilla opened this issue Feb 11, 2021 · 0 comments
Open

Improved Android patch to disable system bars #2265

SDLBugzilla opened this issue Feb 11, 2021 · 0 comments
Assignees
Milestone

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

Reported in version: HG 2.1
Reported for operating system, platform: Windows 10, x86_64

Comments on the original bug report:

On 2016-10-04 18:55:41 +0000, Daniel Sobe wrote:

Hi,

some time ago somebody posted a patch to dim the system bars on Android. Nevertheless, I was using the patch successfully for a while.

Now that Android supports a "sticky immersive mode", I have improved the patch to use this mode if available.

Please ignore the additional WinRT code in SDL_hints.h. Also, the import of the AbsoluteLayout is not necessary anymore (got fixed meanwhile).

Regards,

Daniel


--- SDL_snapshot/android-project/AndroidManifest.xml 2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/android-project/AndroidManifest.xml 2016-10-02 13:29:01.203126644 +0200
@@ -9,12 +9,13 @@
android:installLocation="auto">

 <!-- Android 2.3.3 -->

--- SDL_snapshot/android-project/src/org/libsdl/app/SDLActivity.java 2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/android-project/src/org/libsdl/app/SDLActivity.java 2016-10-02 14:51:36.873309659 +0200
@@ -17,6 +17,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.widget.AbsoluteLayout;
import android.widget.RelativeLayout;
import android.widget.Button;
import android.widget.LinearLayout;
@@ -36,6 +37,8 @@
public class SDLActivity extends Activity {
private static final String TAG = "SDL";

  • private static final String SDL_HINT_ANDROID_HIDE_SYSTEM_BARS = "SDL_ANDROID_HIDE_SYSTEM_BARS";

  • // Keep track of the paused state
    public static boolean mIsPaused, mIsSurfaceReady, mHasFocus;
    public static boolean mExitCalledFromJava;
    @@ -166,6 +169,13 @@
    // Set up the surface
    mSurface = new SDLSurface(getApplication());

  •    nativeAddHintCallback(SDL_HINT_ANDROID_HIDE_SYSTEM_BARS, new SDLHintCallback() {
    
  •        @Override
    
  •        public void callback(String name, String oldValue, String newValue) {
    
  •            updateSystemBarsStatus(newValue);
    
  •        }
    
  •    });
    
  •    if(Build.VERSION.SDK_INT >= 12) {
           mJoystickHandler = new SDLJoystickHandler_API12();
       }
    

@@ -213,6 +223,8 @@
}

     SDLActivity.handleResume();
  •    updateSystemBarsStatus(nativeGetHint(SDL_HINT_ANDROID_HIDE_SYSTEM_BARS));
    
    }

@@ -325,6 +337,30 @@
mSingleton.finish();
}

  • void updateSystemBarsStatus(String value) {

  •    if ("1".equals(value)) {
    
  •        runOnUiThread(new Runnable() {
    
  •            @Override
    
  •            public void run() {
    
  •                // first try immersive mode (sticky immersive)
    
  •                if (Build.VERSION.SDK_INT >= 19) {
    
  •                    getWindow().getDecorView().setSystemUiVisibility(
    
  •                            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    
  •                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    
  •                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    
  •                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    
  •                            | View.SYSTEM_UI_FLAG_FULLSCREEN
    
  •                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    
  •                } else {
    
  •                    // if not available, use at least low profile mode
    
  •                    if (Build.VERSION.SDK_INT >= 14) {
    
  •                        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
    
  •                    }
    
  •                }
    
  •            }
    
  •        });
    
  •    }
    
  • }

    // Messages from the SDLMain thread
    static final int COMMAND_CHANGE_TITLE = 1;
    @@ -437,6 +473,10 @@
    int is_accelerometer, int nbuttons,
    int naxes, int nhats, int nballs);
    public static native int nativeRemoveJoystick(int device_id);

  • interface SDLHintCallback {

  •    void callback(String name, String oldValue, String newValue);
    
  • }

  • public static native void nativeAddHintCallback(String name, SDLHintCallback callback);
    public static native String nativeGetHint(String name);

    /**

--- SDL_snapshot/include/SDL_hints.h 2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/include/SDL_hints.h 2016-10-02 11:38:21.092649566 +0200
@@ -689,6 +689,30 @@
#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT"

/**

    • \brief A hint to control whether the system shall remember the preferred fullscreen mode.
    • This hint will work for WinRT only.
    • The variable can be set to the following values:
    • "0" - No action. System does not remember whether the app wants to run in fullscreen.
    • "1" - Remember preferred app setting (fullscreen or windowed).
    • The default is "0".
  • */
    +#define SDL_HINT_WINRT_REMEMBER_WINDOW_FULLSCREEN_PREFERENCE "SDL_WINRT_REMEMBER_WINDOW_FULLSCREEN_PREFERENCE"

+/**

    • \brief A hint to control whether an Android app shall try to dim resp. remove the system bars.
    • This hint, when set to 1, will try to set "low profile mode" or "sticky immersive mode",
    • depending on which Android API was found. If the API version is too low for either,
    • nothing will happen.
  • */
    +#define SDL_HINT_ANDROID_HIDE_SYSTEM_BARS "SDL_ANDROID_HIDE_SYSTEM_BARS"

+/**

  • \brief An enumeration of hint priorities
    */
    typedef enum

--- SDL_snapshot/src/core/android/SDL_android.c 2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/src/core/android/SDL_android.c 2016-10-02 11:49:15.985195517 +0200
@@ -421,6 +421,32 @@
return result;
}

+void Android_JNI_HintCallback(void *userdata, const char *name, const char *oldValue, const char *newValue) {

  • JNIEnv *env = Android_JNI_GetEnv();
  • jobject callback = (jobject)userdata;
  • jclass cls = (*env)->GetObjectClass(env, callback);
  • jmethodID method = (*env)->GetMethodID(env, cls, "callback", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
  • jstring javaName = (*env)->NewStringUTF(env, name);
  • jstring javaOldValue = (*env)->NewStringUTF(env, oldValue);
  • jstring javaNewValue = (*env)->NewStringUTF(env, newValue);
  • (*env)->CallVoidMethod(env, callback, method, javaName, javaOldValue, javaNewValue);
  • (*env)->DeleteLocalRef(env, javaName);
  • (*env)->DeleteLocalRef(env, javaOldValue);
  • (*env)->DeleteLocalRef(env, javaNewValue);
    +}

+void Java_org_libsdl_app_SDLActivity_nativeAddHintCallback(JNIEnv* env, jclass cls, jstring name, jobject callback) {

  • const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
  • SDL_AddHintCallback(utfname, Android_JNI_HintCallback, (*env)->NewGlobalRef(env, callback));
  • (*env)->ReleaseStringUTFChars(env, name, utfname);
    +}

/*******************************************************************************
Functions called by SDL into Java
*******************************************************************************/

On 2016-10-04 23:39:28 +0000, Alex Szpakowski wrote:

Should immersive mode automatically activate when the SDL window is fullscreen and/or borderless? That's effectively what happens on iOS.

On 2016-10-05 07:16:40 +0000, Daniel Sobe wrote:

I'm not sure everybody would like the navigation bar at the bottom to disappear by default, because unlike iOS there's a "back" button which the app might want to make use of.

However, the back button is typically used to cycle between activities, thus the main usage should be to leave the SDL app. So maybe most of the developers would want it to be hidden by default in their app.

Maybe the hint should be "the other way 'round", making immersive mode default, unless the developer explicitly requests the bar to be permanently visible?

I cannot say anything about the impact of Android 7's new features where windows are not always fullscreen. Maybe somebody else already has experience with this?

On 2017-11-03 08:47:18 +0000, Sylvain wrote:

there was this commit https://hg.libsdl.org/SDL/rev/cf6fe791a6ee
(and bug 3937)

On 2017-11-05 05:18:35 +0000, Sam Lantinga wrote:

This is a great idea (and the hint listener is fantastic!)

I'm going to make this dynamic based on the application state of the window and play with this a bit.

Thanks!

On 2017-11-05 08:56:38 +0000, Daniel Sobe wrote:

I'm wondering whether the commit mentioned in comment # 3 already does the same like this patch. If this is the case, the patch here can be disregarded.

The difference I see is that the patch here checks for the API versions (14 and 19) before taking appropriate actions. The committed version does this without any checks, but in case the additional flags are simply being ignored on older devices with older APIs, this would work as well.

Last thing is the hint, which is used in this patch. The committed version doesn't use any, e.g. makes the behaviour default. This can be seen as reasonable choice for a gaming library.

I guess both patches require a target API >= 19, so this is not a difference. Minimum API of 10 probably still works, although the number of devices will be relatively small nowadays.

On 2017-11-09 00:59:42 +0000, Diego wrote:

With this new fullscreen mode the app goes into fullscreen when started but after leaving the app, such as with the home or overview button, and then returning to the app causes the navigation bar to be show and not return to fullscreen.

On 2017-11-13 09:47:25 +0000, Daniel Sobe wrote:

Yes, the patch here restores the "sticky immersive mode" (resp low profile mode on lower API versions) on every restore of the app, not just on initial launch.

No matter whether this patch is used or the currently merged approach - both require target API 19 to compile. This patch needs it on the Java side, the merged patch on the native side.

@slouken slouken removed the bug label May 11, 2022
@slouken slouken added this to the 3.x milestone Nov 4, 2023
@slouken slouken self-assigned this Nov 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants