-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Multiple bugs with Android immersive mode, especially after pause/resume #1117
Comments
Possibly related: kivy/kivy#2856 |
This is also probably related to a problem with rotation - as I remember, if you start in portrait mode, enable rotation, rotate to landscape, pause and reopen the app, the app remains landscape but the kivy 'window' is portrait, and half off the screen. There are probably other similar variant problems as well. |
Has anyone found a solution to this problem? I'm getting the same issue at the moment. My app isn't going to fullscreen on_resume and there's a big black bar at the top. |
Here's my hack solution: Manually set the android window size to the kivy window size: You may need to increase the height a bit. |
@LarsDu |
I noticed that the hack I listed would mostly not work unless you changed the command to something like activity.getWindow().setLayout(Window.width,Window.height-32) or something so that the new window height isn't exactly the same as the kivy window height (or maybe not the same as a standard android cell phone window???) This leaves small black bar gaps on the top and bottom of the screen, and it also doesn't work 100% of the time when coming back from waking up on suspend mode. If anyone else has run into this problem, I would be so grateful for a more permanent/substantial solution. |
I have a hunch (and nothing to back this up), that size/pos changes in the root window aren't making it to kivy. Something probably guesses - wrongly - that the root window size/pos doesn't change on a mobile device. But clearly, it does when you rotate, or enable/disable immersive mode. This is on my long list of issues to track down. I wonder if it can be reproduced with just SDL code? |
I believe doing something like setLayout(1920,960) explicitly doesn't fix the black bar problem, so it's definitely not something to do with Kivy Window not getting the right height, but I'll try this in my app if that does not work. |
So perhaps kivy isn't expecting the position of the root window (with respect to the openGL coordinates) to change? |
@hackalog its seems you may have some interest in this, here is a simple example and some opinion. After on_start() the black bar is at the bottom; after on_resume() the black bar is at the top. The existence of the black bar is the issue, it's location is an artifact that will disappear when it gets the size is right. Moving self.set_background_color() to the end of on_start() does not change the issue. So Window.size is unchanged after changing the app window size. I suggest this is the issue. Looked at this way, Window.size is not static. And Kivy may not know Window.size till the end of on_start()/on_resume(). And I'd guess Kivy gets app Window.size from Android as in general Kivy could not know the size of the Navigation bar on some device. Perhaps the issue can be addressed by re-making that Android call returning Window.size (explicitly or implicitly) at the end of on_start()/on_resume(). The BIG assumption here is that Kivy evaluation order does not assume Window.size is static - and I have no clue on that! Note: on the latest p4a this requires the workaround to Issue #1504 else p4a crashes. Edit: I also tried putting set_android_immersive_sticky() in build() and removing on_start() and on_resume(). The behavior was the same as with on_start() and on_resume(). To me this suggests p4a gets the device size before build().
.p4a
|
This sounds like it could possibly be resolved by a simple update to latest SDL2 and SDLActivity. If I had to guess, that's where I would assume the bug is (in SDLActivity/the java wrapper, specifically). I'm still busy with a few other pull requests but plan to tackle this soon (in case nobody else has picked it up yet once I get to it), since this will also solve a lot of other issues like missing key events for certain physical keys, CTRL not working on physical keyboards and other problems that appear to be resolved in later SDL2 versions for Android |
Heh, if I remember the last time we tried to update to latest SDL2, the word "simple" might be a misnomer. But yes, an update to newer SDL would be fantastic for a number of reasons (including this one: kivy/kivy-ios#274). @inclement The rotation-related bugs are a definite issue, too (both in p4a and in kivy-ios). I'd like to see if updating SDL helps there. If not, I'll another issue. We have an easy reproducer, at least on the IOS side) |
I drilled down into this and there are two separate issues: one at first 'UI mode' call, and one at on_resume()
This is due to a missing resize handler in the Kivy code. From Kivy's point of view a 'UI mode' change is a screen resize. We get a black bar because the app is not written to respond to UI change. If the app works on a desktop 'window resize' or on a portable 'sensor rotate', these are cases where there is already a resize handler and this problem should (!) not appear. The app need something of the form:
If an immersive 'UI mode' is called in build() or on_start(), then SDL2 generates a 'windowresize' event after on_start() and another after on_resume(). These events then set the Kivy Window.size. The on_start() 'windowresize' contains the immersive window size values. But the on_resume() 'windowresize' contains the NON-immersive window size values. After on_resume Kivy then paints a smaller window, and Android keeps the Navigation Bar hidden. Giving rise to the black bar. To me this looks like an SDL2 issue. The on_resume event is redundant as Android does not have a state change. Kivy does not have a state change till it receives this misleading event. The resulting Kivy state change is bogus. No idea how to workaround at this time. |
I'm currently looking into an SDL2 version bump: #1528 pull request will not work/build yet as-is, but I'll let you know when it does (should in 1-2 days, got it working locally but I'm still waiting on other merge requests). You could then try it out and see if it helps with anything. I'm not familiar enough with immersive mode myself to be able to tell for sure, I can't see anything obviously wrong in my test app but I might have misunderstood what the issue is |
When you are ready I'd be happy to try the latest... Here is my current thinking..... It seems SDL2 always (?) calls setSystemUiVisibility() [see SDLActivity.java] at start time and at on_resume() A second setSystemUiVisibility() call from Kivy gives additional resize events, these are filtered for a recursion case (I think) so these event dont get back to Kivy hence the black bars. Tried lots of workarounds - no cigar. Not clear this is an error, but an explicit setSystemUiVisibility() call seems to require explicit disabling of the implicit setSystemUiVisibility() call. Which would be an enhancement request, and might be an SDL2 thing, I can't tell yet. Trying a different approach. What I want is Android Immersive_stickey mode. In SDLAactavity.java the call setSystemUiVisibility('IMMERSIVE_STICKEY') exists, and is enabled by the 'fullscreen' option. So try 'fullscreen' as shown in the example below. The 'fullscreen' option works on Windows but not on Android. From Kivy's point of view Android 'immersive' is fullscreen, so its seems like is 'should' work; and it looks like the code is in SDL2. In kivy/core/window/window_sdl2.py I can trace fullscreen into _window_sdl2.so but can't find the source code which presumably is in kivy.deps.sdl2 wherever that is located. Any suggestions on how to proceed?
|
I wonder if this is still happening since the SDL2.0.9 upgrade? That definitely had implications for some fullscreen behaviour. |
I should be able to try it... I'll try building this eve
|
I planned to try sdl2==2.0.9 but found this is now the default with python-for-android Two issues (pretty basic so I wonder about my sanity):
This message was in the log file:
|
@Ham-Merhead can you try without the version pin? It should be possible to pin it like that but maybe something's broken about it and the recipe isn't recognized. Can you see in the output whether it's built as a recipe module or pure python one? @ two issues: things like that are expected if you run kivy master on pre-2.0.9 p4a (with old SDL2), or you run kivy stable on 2.0.9 master p4a. pretty sure they only work correctly if you upgrade both (or none) |
Also, shouldn't |
@Jonast ..."can you try without the version pin?"... Case 1) If I specify Case 2) if I change to The behavior is the same in both the first two cases: B) --orientation is disabled. C) In the docs https://python-for-android.readthedocs.io/en/latest/buildoptions/ Case 3)
the snippet of main.py is (size is NoneType) !
|
That is the approach I'd recommend, yes. (if you're using p4a master) If that crashes, can you file a bug here?
Independently of the crash, I honestly think this is intended. Fullscreen is with status bar and navigation hidden (VARIANT 2 BELOW), windowed is with both visible (VARIANT 1 BELOW). The "mixed" variant I'm pretty sure was simply a bug, and I don't think we ever had a proper option for this...? Maybe it could be added as a feature, but given the settings right now there is no good way to specify it |
yes
yes .
perhaps it is a legacy from when the navigation bar was physical buttons?
yes I see What about Btw Google is quite good on the current documentation of display modes: |
@Ham-Merhead I can assure you p4a master returns window size just fine, so this is 99% not an SDL2 issue (I use an alternative to kivy where it works fine) @ google: yes I'm aware of the various modes, p4a just simply only supports windowed (ALL bars visible) and sticky immersive (everything gone as much as possible) historically. I know there are more, but p4a has so far never offered any options to access the others 🤷♂️ if this is a common request we could possibly add it, it's not impossible or challenging per se it's just that nobody has added options for that so far |
IMHO Those other modes would be really cool. The same as Java, that would keep the marketing folks happy. Oh, wait, we don't .....
I thought LandscapeLeft and LandscapeRight were an iOS thing. But maybe not only iOS. |
Happy, happy, joy, joy Immersive rotates just fine.
Not challenging for whom? ;) I can call Android/Java .setSystemUiVisibility() and change the UI options. This works. But the UI is immediately reset to the default after a single touch event. I could write a listener in Java, but presumably that would keep firing. A not a good idea. Any suggestions? |
Oh right, I forgot SDL2 doesn't support these modes. Nevertheless it should be doable, you need to add things to our SDLActivity.java.patch to change this particular function/line: (That is where SDL2 triggers this UI fiddling that you are seeing, in an attempt to ensure Android doesn't slide back in the bars in sticky immersive which it likes to do) |
Was looking for something a little more user friendly. Continuing that quest: A more basic question, how to switch between the two modes we now have programmatically? my assumption had been that Clearly ? |
The default is 'auto' is because you are supposed to use
Yes, which is why I recommend you to use that 🙂 and leave 'auto' (As a side note, per design programmatically cannot really be done right now at least without a very visible delayed switch, because the loading screen comes up before your program runs and doesn't know what your program will decide upon, so it is impossible to launch it programmatically from the start in the right mode)
The
|
Another side-note: programmatically changing the mode from my tests appears to work, through |
Getting wiser slowly:
P4A_IS_WINDOWED is used in Kivy here Where it says:
Which means:
Back to square one. But not giving up..... |
I'm not sure that code comment is correct for Regarding "convincing SDL2", for that you need to modify the line of SDLActivity.java that I quoted (similarly to p4a and kivy, SDL2 only knows fullscreen and windowed and not the in-between you want as far as I'm aware, but it adapts to surface size changes properly. So if you prevent it from enforcing the fullscreen by hacking around in the java code it will probably work fine if you set whatever different style) |
FYI I tried this in _window_sdl2.pyx (yes, propagated to .c and .so)
I tried I always get a windowed screen. Which in retrospect I can rationalize. |
p4a 0.5.3, kivy 1.10.0)
Reproducer code: https://gist.github.com/hackalog/c02703f78f09cf606cf5c1f32c074f23
How to reproduce:
ask_update()
will fix this.*Press "fullscreen". Soft menu will disappear, but note app window is not full-sized (black space at top, resolution wrong) BUG 3
This was reproduced on a Google Pixel C tablet with android 6.0.1 (Build MXC89L)
The text was updated successfully, but these errors were encountered: