mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Android: Improve screen safe-area reporting
The goal of this change is to ensure that the safeAreaInsets and keyboardInsets members of Display correctly take the current system UI and screen cutouts into account. This change also enables rendering behind the status bar and navigation bar for JUCE applications. This is in line with the new defaults in Android 15, where building against the Android SDK 35 will automatically enable "edge-to-edge" drawing. Enabling this behaviour on older platforms too provides a more consistent experience.
This commit is contained in:
parent
cfc006aaf9
commit
f904fd356a
5 changed files with 1359 additions and 1181 deletions
|
|
@ -230,7 +230,7 @@ static jobject makeAndroidRect (Rectangle<int> r)
|
|||
r.getBottom());
|
||||
}
|
||||
|
||||
static jobject makeAndroidPoint (Point<int> p)
|
||||
static inline jobject makeAndroidPoint (Point<int> p)
|
||||
{
|
||||
return getEnv()->NewObject (AndroidPoint,
|
||||
AndroidPoint.create,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@
|
|||
|
||||
package com.rmsl.juce;
|
||||
|
||||
import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT;
|
||||
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE;
|
||||
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
|
@ -44,31 +48,33 @@ import android.graphics.Paint;
|
|||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.text.Selection;
|
||||
import android.text.SpanWatcher;
|
||||
import android.text.Spannable;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Pair;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.Selection;
|
||||
import android.text.SpanWatcher;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Pair;
|
||||
import android.view.Choreographer;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.accessibility.AccessibilityNodeProvider;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowInsetsController;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.accessibility.AccessibilityNodeProvider;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -80,7 +86,7 @@ public final class ComponentPeerView extends ViewGroup
|
|||
{
|
||||
super (context);
|
||||
|
||||
if (Application.class.isInstance (context))
|
||||
if (context instanceof Application)
|
||||
{
|
||||
((Application) context).registerActivityLifecycleCallbacks (this);
|
||||
}
|
||||
|
|
@ -796,35 +802,53 @@ public final class ComponentPeerView extends ViewGroup
|
|||
{
|
||||
}
|
||||
|
||||
public void setSystemUiVisibilityCompat (int visibility)
|
||||
public void setSystemUiVisibilityCompat (Window window, boolean visible)
|
||||
{
|
||||
Method systemUIVisibilityMethod = null;
|
||||
try
|
||||
if (30 <= Build.VERSION.SDK_INT)
|
||||
{
|
||||
systemUIVisibilityMethod = this.getClass().getMethod ("setSystemUiVisibility", int.class);
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (systemUIVisibilityMethod == null) return;
|
||||
WindowInsetsController controller = getWindowInsetsController();
|
||||
|
||||
try
|
||||
{
|
||||
systemUIVisibilityMethod.invoke (this, visibility);
|
||||
if (controller != null)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
controller.show (WindowInsets.Type.systemBars());
|
||||
controller.setSystemBarsBehavior (31 <= Build.VERSION.SDK_INT ? BEHAVIOR_DEFAULT
|
||||
: BEHAVIOR_SHOW_BARS_BY_SWIPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller.hide (WindowInsets.Type.systemBars());
|
||||
controller.setSystemBarsBehavior (BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (java.lang.IllegalArgumentException e)
|
||||
{
|
||||
}
|
||||
catch (java.lang.IllegalAccessException e)
|
||||
{
|
||||
}
|
||||
catch (java.lang.reflect.InvocationTargetException e)
|
||||
|
||||
if (window == null)
|
||||
return;
|
||||
|
||||
// Displays::findDisplays queries the DecorView to determine the
|
||||
// most recently-requested visibility state of the system UI.
|
||||
// As we're creating new top-level views via WindowManager,
|
||||
// updating only the DecorView isn't sufficient to hide the global
|
||||
// system UI; we also need to update the view that was added to
|
||||
// the WindowManager.
|
||||
ArrayList<View> views = new ArrayList<>();
|
||||
views.add (window.getDecorView());
|
||||
views.add (this);
|
||||
|
||||
for (View view : views)
|
||||
{
|
||||
final int prevFlags = view.getSystemUiVisibility();
|
||||
final int fullScreenFlags = SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
final int newFlags = visible ? (prevFlags & ~fullScreenFlags)
|
||||
: (prevFlags | fullScreenFlags);
|
||||
|
||||
view.setSystemUiVisibility (newFlags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,21 +34,54 @@
|
|||
|
||||
package com.rmsl.juce;
|
||||
|
||||
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
||||
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
|
||||
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
|
||||
//==============================================================================
|
||||
public class JuceActivity extends Activity
|
||||
{
|
||||
//==============================================================================
|
||||
private native void appNewIntent (Intent intent);
|
||||
private native void appOnResume();
|
||||
|
||||
private void initEdgeToEdge()
|
||||
{
|
||||
if (Build.VERSION.SDK_INT < 35)
|
||||
{
|
||||
View decorView = getWindow().getDecorView();
|
||||
|
||||
final int flags = Build.VERSION.SDK_INT < 30
|
||||
? ( SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
|
||||
: SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||
|
||||
decorView.setSystemUiVisibility (decorView.getSystemUiVisibility() | flags);
|
||||
}
|
||||
|
||||
if (30 <= Build.VERSION.SDK_INT)
|
||||
getWindow().setDecorFitsSystemWindows (false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate (Bundle savedInstanceState)
|
||||
{
|
||||
initEdgeToEdge();
|
||||
|
||||
super.onCreate (savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent (Intent intent)
|
||||
{
|
||||
super.onNewIntent(intent);
|
||||
setIntent(intent);
|
||||
super.onNewIntent (intent);
|
||||
setIntent (intent);
|
||||
|
||||
appNewIntent (intent);
|
||||
}
|
||||
|
|
@ -57,7 +90,6 @@ public class JuceActivity extends Activity
|
|||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
appOnResume();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue