[Solved] Search for workaround/fix for broken windowed mode on Android [FIXED in hg]


#1

With a bump to API level 27 and SDL 2.0.9, I ran into an issue with windowed mode on Android: when my SDL app launches and SDL_CreateWindow() doesn’t specify any fullscreen flags, it will use that weird kind-of-fullscreen-but-not mode, with the topbar & button bar half-transparent sliding away after a second or so, and the topbar staying half-there kinda overlayed. This is not only distracting, but actually obstructs the apps own topbar and makes it borderline unusable…

Ticket is here: https://bugzilla.libsdl.org/show_bug.cgi?id=4424

I’m relatively sure this is an SDL bug because when I use SDL_SetWindowFullscreen() to switch to fullscreen, I get proper fullscreen with all bars permanently gone, and if I use it again to go back to windowed, I get proper windowed with the bars fully there & solid, no weird sliding.

However, that fullscreen-and-back workaround hack only works with a delay, so I’d need delayed timer ugliness or something. Therefore, I’ve wondered if anyone has an idea for a better workaround that doesn’t involve unreliable timing magic?

Edit: okay, here an illustration of the problem:

When I start an android app with no fullscreen flags, I expect to get Variant 1 (left). This is also what I used to get with an old SDL2 at API level 19.

However, with SDL 2.0.9 + API 27 I get Variant 3 (right) for my windowed application with bars overlaying content, obstructing vital UI buttons and being generally annoying by shifting in/out of view.

As soon as I enable fullscreen on SDL 2.0.9 I revert to Variant 2, and when I go to windowed again I get Variant 1, but only after those two switches, and only if I do them with some delay (can’t just do it instantly after window creation with no pause) - and that kinda sucks. So, any suggestions what to do about that?


#2

Doesn’t anybody else observe the same issue? Did I do something specifically unusual?


#3

I forgot to mention this, but this is what the SDL2 example project uses to launch in its manifest:

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

And this is what I use to launch, since obviously, I want to run it windowed:

android:theme="@android:style/Theme.NoTitleBar"

So this is most likely related in some way. But how else am I supposed to have it launched windowed if not like this? SDL_CreateWindow uses no fullscreen flag either (=windowed), so as far as that is concerned, my use of manifest+SDL app code should be consistent.


#4

To discard this behaviour, you can comment out in SDLActivity.java the line:
mSingleton.sendCommand(COMMAND_CHANGE_WINDOW_STYLE, fullscreen ? 1 : 0);


#5

But that would break SDL_SetWindowFullscreen, right? I am doing this for a framework (python-for-android) so some hack that just works for me is not acceptable, I need both initial windowed mode startup & windowed/fullscreen toggle to be working properly.

Edit: the guess I made here about the potential culprit is wrong, see next post


#6

Okay, I have confirmed the following (with hacking additional debug log entries into SDLActivity.java):

  1. The app starts fine in windowed mode, action bar & status bar are solid and the surfaceChanged() output indicate window size: 2016x1008, device size: 2160x1080 (–> obviously a reduced size, which is in line with a proper windowed mode) - so everything starts out intended and non-broken, including the viewport/render surface

  2. So far, there has been no call to setWindowStyle(boolean fullscreen) on SDLActivity.java - again verified by hacked in debug output

  3. At some point later, the native main function starts. This is whereSDL_Init() and SDL_CreateWindow() is called with no SDL_WINDOW_FULLSCREEN flag or anything.

  4. Then, suddenly, I see another surfaceChanged() while already seeing app gfx (like half a second later): Window size: 2160x1080, Device size: 2160x1080. There has been no call to setWindowStyle()! This means there hasn’t been any attempt to set the proper sticky mode, hide the status/topbar properly, anything. And indeed, now I’m suddenly in this very annoying broken semi-fullscreen mode where the bars float half-transparent over the app and make it borderline unusable.

  5. Everything is now broken until I do a delayed SDL_SetWindowFullscreen() to actually toggle to proper fullscreen and back to proper windowed - which makes sense, since this actually seems to call through into setWindowStyle() instead of just resizing the surface out of the blue without adapting the UI/window style accordingly

My theory:
Since I can’t see any other function in SDLActivity.java to change the surface size, I’m wondering if something is messing with the underlying surface size straight out of the native code. It seems to me like the native code simply assumes the app always starts in fullscreen mode without checking this, or giving any attention to SDL_WINDOW_FULLSCREEN flag not being present, and cranks the surface size to fullscreen no matter what, and surprise, things break.

Is anyone familiar with the native code for Android and can share some insight on this theory?


#7

I did some more investigations and tests here: https://bugzilla.libsdl.org/show_bug.cgi?id=4424#c6

This breaks windowed mode start up really bad, so if Android is maintained at all, it’d be really cool if someone who knows how this works could eventually make the time to look at it (I understand right now it’s Christmas and all, but afterwards maybe?)


#8

I have dug deeper, and it really seems like something in SDL2 is enforcing the broken mode and fighting me over it if I want to repair it in SDLActivity.java. See bug report for more details. Would be really great if this could be fixed, since you know, this is quite broken…


#9

Found the bug. Necessary change is in SDLActivity.java:

 -        if (SDLActivity.mFullscreenModeActive && (visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 || (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
 +        if (SDLActivity.mFullscreenModeActive && ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 || (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)) {

This is a really annoying bug IMHO (breaks windowed mode!) so it’d be neat if there could be a patch release for this.


#10

Thanks for the merge :smile: :+1: