bevyengine / bevyengine/bevy

Ability to hide navigation buttons on Android (immersive mode)

Open
#11,402 1 comment 1 reaction 0 assignees View on GitHub
A-Windowing C-Feature O-Android
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## What problem does this solve or what need does it fill?

I think most games would prefer to have the game be full screen instead of showing the title bar and navigation buttons. It is already possible to hide the title bar through Android build configuration in `cargo-apk` or `xbuild`, but hiding the navigation buttons requires calling Java functions.

## What solution would you like?

A boolean paremeter on `WindowPlugin` would be nice to enable or disable this feature. I think it should be on by default for games.

## What alternative(s) have you considered?

You can always implement it yourself, but it's not trivial.

## Additional context

I have crated this monstrosity to achieve this while being very inexperienced in Android APIs. I'm not sure if this works for all Android versions but seems to work for me. There is also `WindowInsetsControllerCompat`, which could have better compatibility, but I couldn't get it to work without crashing. There is an [official guide](https://developer.android.com/develop/ui/views/layout/immersive) on how to do this differently, but this simple way seems to be enough.

```rust
use jni::objects::{JObject, JValue};

/// Needs to be called from the main thread
pub fn enable_immersive_mode() -> anyhow::Result<()> {
let android_app = bevy::winit::ANDROID_APP.get().unwrap();
let vm = unsafe { jni::JavaVM::from_raw(android_app.vm_as_ptr() as *mut *const _)? };
let activity = unsafe { JObject::from_raw(android_app.activity_as_ptr() as *mut _) };
let mut env = vm.attach_current_thread()?;

// getWindow()
let window = env
.call_method(activity, "getWindow", "()Landroid/view/Window;", &[])?
.l()?;

// getWindow().getInsetsController()
let insets_controller = env
.call_method(
&window,
"getInsetsController",
"()Landroid/view/WindowInsetsController;",
&[],
)?
.l()?;

// getWindow().getInsetsController().hide(2)
env.call_method(&insets_controller, "hide", "(I)V", &[JValue::from(2)])?;

Ok(())
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.